Перейти к основному содержимому

Отчёт по доработке кода BELF

Дата фиксации: 2026-09-17

Статус: готово к deploy. Публикация, commit, push и merge не выполнялись.

Что было целью работы

Сайт не переписывался с нуля. Работа велась в существующем проекте: сохранить дизайн, тексты, цены, маршруты и сценарии пользователя, одновременно сделать код понятнее, безопаснее и проверяемым автоматически.

Главный технический результат — сайт теперь устроен по понятной схеме:

app → pages → widgets → features → shared

То есть страницы собирают блоки, крупные виджеты не знают о страницах, а общие данные и утилиты не зависят от интерфейса. Нарушения этой схемы останавливают проверку до публикации.

Что изменено в коде

1. Навигация и доступность

Основные файлы: src/widgets/site-header/NavigationDialog.tsx, src/widgets/site-header/SiteHeader.tsx, src/widgets/site-header/useNavigationDialog.ts.

  • Меню вынесено в самостоятельный диалог навигации, а шапка сайта отвечает только за кнопку открытия и возврат фокуса.
  • При открытии меню курсор клавиатуры сразу попадает внутрь него.
  • Tab и Shift+Tab не позволяют уйти за пределы меню.
  • Закрытие работает через кнопку, клик по фону, Escape и переход по ссылке.
  • Пока меню открыто, внешний сайт недоступен для фокуса и прокрутки; после закрытия прежнее состояние восстанавливается.
  • Учтены размонтирование компонента и режим разработки React StrictMode, чтобы не оставались заблокированными прокрутка или фокус.

2. Структура страниц и компонентов

Основные папки: src/pages, src/widgets, src/features, src/shared.

  • Шапка и подвал вынесены в widgets.
  • Механика темы шапки вынесена в features/navigation-theme.
  • На главной выделены самостоятельные SignalStrip и CalculatorSection.
  • На партнёрской странице реестр клиентов получил отдельную модель проверки данных, а форма заявки стала самостоятельным компонентом.
  • На странице карьеры форма резюме и секции страницы имеют собственных владельцев.
  • Для локальных модулей созданы публичные index.ts, чтобы другие части сайта не импортировали внутренние файлы напрямую.

Компоненты выделялись только там, где у блока есть отдельная ответственность: состояние, поведение, доступность, собственные стили или повторное применение.

3. Калькулятор

Основные файлы: src/features/calculator/*, src/shared/data/modules.ts, src/shared/data/pricing.ts.

  • Введены закрытые типы для модулей, хостинга, установки, периода оплаты и скидок/корректировок.
  • Проверяется полное соответствие модулей и цен: отсутствующая цена больше не может незаметно превратиться в ноль.
  • Разделены три независимые части: чтение введённых значений, расчёт и вывод результата.
  • Форма разбита на предметные блоки: модули, масштаб, хостинг и установка.
  • Сохранены исходные корректные суммы расчёта, включая self-hosted, cloud, годовой период и выездную установку.

4. Стили и визуальная устойчивость

Основные файлы: src/styles/tokens.css, CSS Modules рядом с компонентами.

  • Добавлены смысловые токены цветов, поверхностей, текста, границ, фокуса и overlay, чтобы стили не зависели от случайных повторов шестнадцатеричных значений.
  • Каждый CSS Module имеет одного владельца; стили одного блока не передаются в другой компонент через props.
  • Убраны архитектурно опасные зависимости между стилями и компонентами.
  • Визуальные снимки проверяют три маршрута на шести размерах экрана: мобильных, планшетных и десктопных. Снимки главной страницы добавлены только после ручной проверки, без автоматического обновления baseline.

5. SEO и серверная выдача страниц

Основные файлы: src/shared/config/site.ts, scripts/build.mjs, scripts/check-seo.mjs, scripts/check-links.mjs.

  • Создан единый источник данных о BELF, Digital Revolution Makers, контактах, домене и страницах сайта.
  • Для /, /partners/ и /careers/ автоматически создаются уникальные title, description, H1, canonical, Open Graph и Twitter metadata.
  • Сайт собирает страницы заранее для поисковых роботов, а не отдаёт пустой экран с последующей загрузкой JavaScript.
  • Автоматически создаются robots.txt и sitemap.xml из того же реестра страниц, поэтому новая страница не может случайно остаться вне карты сайта.
  • Добавлена структурированная разметка Organization, WebSite, SoftwareApplication и BreadcrumbList.
  • В Organization попадают только подтверждённые владельцем Instagram и Telegram BELF.
  • Внутренние ссылки, canonical, заголовки, alt-тексты, sitemap и schema проверяются отдельным автоматическим аудитом.

6. Защита архитектуры и качества

Основные файлы: eslint.config.js, scripts/check-architecture.mjs, scripts/test-eslint-boundaries.mjs, scripts/check-cycles.mjs, scripts/check-orphan-files.mjs, scripts/check-orphan-exports.mjs.

  • ESLint проверяет направление импортов, запрет ../..., deep imports, cross-page imports и обратные зависимости слоёв.
  • Добавлены 14 специальных «плохих» примеров: проверка должна их отвергать, иначе считается сломанной.
  • Добавлена проверка циклических зависимостей и недостижимых файлов.
  • Добавлена проверка неиспользуемых публичных exports.
  • Подключен полный рекомендованный набор правил React Hooks без отключений комментариями.
  • Добавлены ограничения размера файлов и сложности, а также проверка владения CSS.

7. Автоматические проверки и CI

Основные файлы: package.json, .github/workflows/pages.yml, scripts/*.

Добавлены или включены команды:

format:check, lint, lint:css, typecheck, test, test:coverage,
test:a11y, test:e2e, test:seo, test:architecture, check:cycles,
check:bundle, check:links, check:lighthouse, build, quality

npm run quality объединяет все локальные обязательные проверки. CI запускает эту же команду до возможной публикации сайта.

Какие дефекты исправлены

  • Навигационное меню могло оставлять фокус снаружи диалога; теперь фокус всегда удерживается внутри и корректно возвращается обратно.
  • Внешнее содержимое сайта не становилось полноценно недоступным при открытом меню; добавлено корректное inert-поведение с восстановлением.
  • В старой реализации React мог синхронно менять состояние из эффекта; это исправлено без подавления предупреждений.
  • Архитектурные правила ранее не ловили часть запрещённых импортов; теперь это доказано негативными тестами.
  • Некорректные данные реестра клиентов могли пройти дальше в интерфейс; теперь они отклоняются на границе загрузки.
  • Отсутствующая цена модуля могла давать результат 0; теперь это ошибка данных, а не тихий неверный расчёт.
  • Метаданные и SEO-схема могли расходиться между страницами; теперь они генерируются из одного реестра и проверяются после сборки.

Проверки, которые прошли

Последний полный зафиксированный локальный quality gate прошёл успешно:

  • 56 unit/component тестов в 15 файлах — PASS.
  • Coverage: statements 96.18%, branches 81.01%, functions 97.09%, lines 96.76% — PASS.
  • Проверка изменённых строк покрытия — PASS.
  • Архитектурные fixtures: 14 — PASS.
  • Циклические зависимости: 0 среди 94 исходных файлов — PASS.
  • Accessibility: 24 браузерных axe-проверки на шести размерах экрана — PASS.
  • End-to-end и visual regression: 162 сценария — PASS.
  • SEO, ссылки и production build — PASS.
  • Bundle gzip: главная 84.96 KiB, партнёры 80.30 KiB, карьера 77.42 KiB, общий JavaScript 74.51 KiB — PASS.
  • Lighthouse: mobile Performance 98–99, Accessibility/Best Practices/SEO 100; desktop все категории 100. Mobile LCP 1.96–2.10 с, desktop LCP 447–526 мс.

После подтверждения соцсетей дополнительно прошли npm run test:seo, npm run format:check и git diff --check.

Что зафиксировано в Google Search Console

  • Подтверждён ресурс belf.uz.
  • https://belf.uz/sitemap.xml принят Google успешно.
  • В карте обнаружены 3 ожидаемые страницы.
  • Отчёт об индексации ещё обрабатывается, поэтому нельзя честно утверждать, что страницы уже появились в выдаче Google.

Что намеренно не делалось

  • Не менялись цены, тексты, маршруты, anchors и пользовательские сценарии без подтверждённой причины.
  • Не использовались eslint-disable, @ts-ignore, @ts-nocheck, необоснованный any, !important, ослабление проверок или автоматическое обновление снимков.
  • Не придумывались отзывы, кейсы, сертификаты, позиции в Google или показатели.
  • Не выполнялись commit, push, merge и deploy.

Что перенесено на следующий план

Это внешние действия, которые требуют времени Google, решения владельца или публикации новой версии сайта:

  • подтвердить фактическую индексацию и Google-selected canonical;
  • получить baseline запросов, стран, устройств и брендовой выдачи;
  • подтвердить источники для всех продуктовых/коммерческих claims;
  • решить, нужны ли отдельные полноценные узбекская и английская версии сайта;
  • при разрешённом deploy пройти post-release SEO, field Core Web Vitals и проверку конверсий.

Подробная техническая история по этапам находится в quality-gates-report.md; незакрытые внешние пункты — в seo-external-handoff.md.