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

NAV-IA-2026-09-28 — иерархия навигационной панели

ID и цель​

ID: NAV-IA-2026-09-28

Перестроить информационную архитектуру раскрывающейся панели навигации BELF, чтобы ссылки были сгруппированы по пользовательской задаче, а не по истории добавления страниц:

  • в «Продукте» оставить только навигацию по секциям главной страницы;
  • создать отдельный блок «Модули» для самостоятельных страниц возможностей;
  • вынести служебные продуктовые страницы в блок «Внедрение»;
  • перенести «Правовую информацию» под блок «Компания» как вложенный подраздел;
  • применить одну и ту же иерархию на всех страницах, языках и viewport;
  • не потерять существующие маршруты, локализацию, доступность и сценарии меню.

Источник: запрос пользователя от 2026-09-28 и согласованная в диалоге целевая структура. Документ используется как план и журнал реализации.

Исходное состояние​

  • Git root: BelfProctor/dist.
  • Ветка: main.
  • HEAD при создании плана: dad7a77be0261e2511452568983f2860367b138d.
  • Исходный git status --short: ?? AGENTS.md.
  • AGENTS.md — существующий пользовательский untracked-файл; не изменять, не удалять, не добавлять в commit без отдельного разрешения.
  • Незакоммиченных изменений в затрагиваемых исходниках при создании плана нет.

Текущая проблема:

  • группа product одновременно содержит якоря главной, SEO-страницы возможностей, страницы внедрения, страницу о продукте и загрузку;
  • legal отображается как самостоятельная группа, хотя по смыслу относится к корпоративной и служебной информации;
  • общей ссылки на существующую страницу /{locale}/modules/ в меню нет;
  • footer выбирает группы по индексам groups[0], groups[1], groups[2], поэтому простое добавление новой группы способно незаметно перепутать ссылки;
  • desktop-сетка рассчитана на фактические две колонки, mobile — на линейный список, поэтому изменение данных без layout-проверки создаст дисбаланс и переполнение.

Сохраняемые контракты​

  • Все существующие routes, anchors и локализованные пути остаются рабочими.
  • Русский, узбекский и английский получают одинаковую структуру и порядок.
  • /docs/ остаётся нелокализованным внешним для marketing-locales маршрутом.
  • Узбекский contact anchor остаётся #aloqa; остальные якоря локализуются по существующим правилам.
  • Не меняются содержимое страниц, metadata, sitemap, бизнес-правила, цены, контактные данные и поведение cookie consent.
  • Сохраняются open/close, Escape, backdrop, link close, focus trap, initial focus, возврат focus, scroll lock, inert cleanup и reduced motion.
  • Footer визуально и содержательно не перестраивается в рамках этой задачи; он только отвязывается от позиций групп, чтобы новая структура меню его не сломала.
  • Contact panel остаётся отдельным CTA-блоком, а не становится пятой колонкой ссылок.

Целевая информационная архитектура​

1. Продукт / Mahsulot / Product​

Назначение: быстрый обзор главной страницы. Здесь допускаются только ссылки на секции локализованной главной.

IDRU labelБазовый href
platformПлатформа/#platform
modules-overviewМодули/#modules
proctoringBELF Прокторинг/#proctoring
deploymentРазмещение/#deployment
calculatorКалькулятор/#calculator

Инвариант: каждый href группы product после удаления locale-префикса содержит /#...; отдельных страниц в этой группе нет.

2. Модули / Modullar / Modules​

Назначение: перейти к каталогу модулей или к отдельной странице продуктовой возможности.

IDRU labelБазовый href
all-modulesВсе модули/modules/
time-trackingУчёт рабочего времени/time-tracking/
employee-monitoringМониторинг сотрудников/employee-monitoring/
productivityАналитика продуктивности/productivity/
screenshotsСнимки экрана/screenshots/

Название all-modules должно явно отличаться от якоря «Модули» в «Продукте»: первое ведёт на самостоятельную страницу, второе — к обзору на главной.

3. Внедрение / Joriy etish / Implementation​

Назначение: собрать самостоятельные страницы о выборе конфигурации, размещении, доступе и начале работы. Этот блок нужен, чтобы не маскировать такие страницы под модули и при этом выполнить контракт «Продукт — только главная».

IDRU labelБазовый href
securityБезопасность/security/
self-hostedSelf-hosted/self-hosted/
pricingСтоимость/pricing/
downloadСкачать BELF/download/
docsТехническая документация/docs/ (localizeHref: false)

4. Компания / Kompaniya / Company​

Назначение: информация о BELF и Digital Revolution Makers, сотрудничестве и контакте с командой.

IDRU labelБазовый href
aboutО BELF/about/
partnersПартнёрская программа/partners/
careersРабота в BELF/careers/
contactСвязаться с командой/#contact

5. Правовая информация как подраздел «Компании»​

legal не является равноправной основной колонкой. Это вложенный subsection в визуальном и семантическом контейнере company, расположенный после основных ссылок компании.

Сохраняемый набор ссылок:

IDRU labelБазовый href
privacyОбработка данных/legal/privacy/
termsУсловия использования/legal/terms/
monitoringМониторинг сотрудников/legal/monitoring/
acceptable-useДопустимое использование/legal/acceptable-use/

Добавление DPA или Cookies в меню не входит в эту задачу: их routes существуют, но пользователь просил перегруппировку текущей навигации, а не расширение юридического раздела.

Порядок восприятия и layout-контракт​

Порядок в DOM и на mobile:

  1. Продукт.
  2. Модули.
  3. Внедрение.
  4. Компания.
  5. Правовая информация внутри «Компании».
  6. Контактная CTA-панель.

На desktop/tablet визуальная сетка может менять число колонок, но не должна менять логический DOM-порядок. Юридический subsection всегда расположен в той же визуальной колонке/карточке, что и «Компания», и имеет меньший уровень иерархии. Не использовать CSS order, который расходится с порядком tab и screen reader.

Рекомендуемая композиция:

  • >= 1024: навигационные секции в компактной сетке 2×2, contact panel справа;
  • 768–1023: навигационная сетка 2×2, contact panel отдельной строкой;
  • mobile/touch: одна колонка в зафиксированном DOM-порядке;
  • существующие фактические breakpoints можно сохранить, если проверки доказывают отсутствие переполнения и визуальный порядок выше.

Не уменьшать шрифт для сокрытия переполнения. Сначала корректировать ширины grid, gap, перенос и плотность описаний.

План реализации​

Этап 1. Зафиксировать regression-контракт​

  • Повторно проверить исходный Git status и diff всех затрагиваемых файлов.
  • Добавить unit-тесты текущего data API, которые сначала падают на новой ожидаемой структуре.
  • Зафиксировать тестами membership и порядок всех групп и ссылок.
  • Зафиксировать инвариант: product содержит только якоря главной.
  • Зафиксировать legal как subsection company, а не top-level sibling.
  • Зафиксировать уникальность ID и href внутри результата для каждого locale.
  • Зафиксировать all-modules с локализованными href /ru/modules/, /uz/modules/, /en/modules/.
  • Зафиксировать /docs/ без locale-префикса и /#contact → /uz/#aloqa.

Этап 2. Сделать data contract устойчивым​

  • В src/shared/data/navigation.ts добавить стабильные ID групп, секций и ссылок в возвращаемые типы; не использовать title/href как identity.
  • Описать один уровень вложенных subsections, достаточный для legal внутри company; не создавать универсальный рекурсивный CMS без необходимости.
  • Обеспечить compile-time закрытые union-типы для известных group IDs.
  • Сохранить единый translation/localizedHref pipeline для всех уровней.
  • Предоставить API выбора группы по ID или keyed result для потребителей, которым не нужен весь menu tree.

Этап 3. Перегруппировать контент​

  • Перестроить src/shared/i18n/navigation.json по целевой таблице выше.
  • Добавить переводы названий modules, implementation, all-modules и необходимых descriptions для RU/UZ/EN в существующем тоне.
  • Перенести существующие link objects без изменения их фактов и маршрутов.
  • Проверить, что каждый существующий menu href встречается ровно один раз, кроме намеренного различия /#modules и /modules/.
  • Не менять page copy и SEO metadata как побочный эффект.
  • До добавления новых top-level групп заменить groups[0..2] в src/widgets/site-footer/SiteFooter.tsx на выбор по стабильным ID или на отдельный footer selector.
  • Сохранить текущие четыре footer-колонки и их видимые ссылки, если только новый data contract не требует явного перечисления того же набора.
  • Добавить regression, доказывающий, что юридические ссылки футера остаются юридическими после перестройки menu tree.
  • Не переносить визуальную иерархию header menu в footer без отдельного пользовательского решения.

Этап 5. Обновить семантический рендер панели​

  • В NavigationDialog.tsx рендерить основные группы по ID, вложенный legal — внутри секции company после основных company links.
  • Использовать корректную структуру headings без пропуска уровней.
  • Key строить по стабильному ID, а не по переведённому title или href.
  • Сохранить один nav dialog, существующее accessible name и все обработчики перехода/закрытия.
  • Не дублировать contact link так, чтобы он конкурировал с основным CTA; если дублирование остаётся, link и CTA должны иметь разные ясные роли.

Этап 6. Перестроить адаптивную сетку​

  • Обновить только CSS-владельцев NavigationDialog.module.css и NavigationDialogResponsive.module.css.
  • Создать устойчивую grid-композицию для четырёх смысловых секций и contact panel без fixed heights и arbitrary offsets.
  • Визуально обозначить legal вторичным subsection, не делая его равноправной основной группой.
  • Проверить баланс колонок с длинными RU/UZ/EN labels/descriptions.
  • Сохранить touch targets не менее 44×44 px, видимый focus и reduced motion.
  • Не менять header tone, overlay animation и mobile sticky close toolbar.

Этап 7. Проверить все варианты​

  • RU, UZ и EN.
  • Главная и внутренние страницы: минимум /, /partners/, /careers/, плюс локализованная страница модуля и legal page.
  • Viewport: 390, 430, 768, 1024, 1440 и 1920 px.
  • Mouse, touch/coarse media, keyboard Tab/Shift+Tab, Enter, Escape.
  • Open menu scroll, reopen scroll reset, focus restore и body scroll lock.
  • Нет horizontal overflow; все группы и CTA достижимы вертикальной прокруткой на mobile.
  • Все ссылки ведут на ожидаемые локализованные routes/anchors.
  • Нет pageerror, console.error, hydration warning.

Этап 8. Visual review и завершение​

  • Запустить существующие navigation screenshots без update flag.
  • Вручную просмотреть actual/diff каждого затронутого open-menu baseline на всех шести viewport и трёх базовых маршрутах.
  • После подтверждения ожидаемой дельты вручную обновить только open-menu baselines; closed/full-page baselines не менять без отдельной причины.
  • После отдельного разрешения вручную просмотреть и обновить устаревшие closed/full-page baselines на Darwin и Linux; контроль без update-флага — 36/36 PASS на каждой платформе.
  • Сохранить maxDiffPixelRatio <= 0.003.
  • Запустить целевые тесты, затем полный npm run quality.
  • Записать результаты, визуальную дельту, полный итоговый Git status и статус commit/push/deploy в этот файл.

Предполагаемые владельцы и файлы​

ФайлОтветственность изменения
src/shared/i18n/navigation.jsonГруппы, порядок, RU/UZ/EN тексты и href
src/shared/data/navigation.tsТипизированная модель, IDs, nested legal, locale mapping
src/widgets/site-header/NavigationDialog.tsxСемантический рендер и порядок чтения
src/widgets/site-header/NavigationDialog.module.cssDesktop layout и визуальная иерархия
src/widgets/site-header/NavigationDialogResponsive.module.cssTablet/mobile layout
src/widgets/site-header/SiteHeader.localization.test.tsxЛокализованная структура и href
src/widgets/site-header/SiteHeader.test.tsx или отдельный data testComponent/data regression
src/widgets/site-footer/SiteFooter.tsxОтвязка от array indices
tests/e2e/navigation.spec.tsПоведение, маршруты и visual regression

Создавать новый компонент только если nested subsection получает собственную смысловую/семантическую ответственность и это реально уменьшает сложность NavigationDialog.tsx. Не создавать обёртки ради каждого блока.

Команды проверки​

Порядок уточнить по scripts в актуальном package.json, запускать из Git root:

npm run format:check
npm run lint
npm run lint:css
npm run typecheck
npm run test
npm run test:a11y
npm run test:e2e
npm run check:links
npm run test:seo
npm run build
npm run quality
git diff --check

Во время разработки допустимы более узкие Vitest/Playwright-фильтры, но они не заменяют финальный npm run quality.

Критерии приёмки​

  • Пользователь за первый просмотр различает обзор продукта, страницы модулей, внедрение и корпоративную информацию.
  • «Продукт» содержит только якоря главной страницы.
  • Отдельная группа «Модули» содержит страницу всех модулей и четыре самостоятельные страницы возможностей.
  • Security, Self-hosted, Pricing, Download и Docs не выданы за модули, а находятся в «Внедрении».
  • «О BELF» находится в «Компании».
  • «Правовая информация» визуально и семантически находится под «Компанией».
  • Ни одна существующая ссылка меню не потеряна и не продублирована случайно.
  • Структура одинакова для RU/UZ/EN, href локализуются корректно.
  • Панель работает на всех заявленных viewport и страницах без overflow.
  • Accessibility-контракт меню не ухудшен.
  • Footer не зависит от индексов групп и не получил случайную контентную дельту.
  • Visual diff навигации и отдельно разрешённых устаревших page-level эталонов вручную проверен на Darwin и Linux.
  • npm run quality — PASS.

Стоп-условия​

  • Не продолжать при обнаружении неизвестных пользовательских правок в затрагиваемых файлах; показать пересечение и запросить направление.
  • Не обновлять snapshots автоматически или до ручного просмотра actual/diff.
  • Не прятать переполнение уменьшением текста, !important, fixed height или отключением описаний на произвольном breakpoint.
  • Не ослаблять focus, accessibility, link, visual или SEO assertions.
  • Не менять routes, page metadata, pricing и содержимое страниц ради меню.
  • Не выполнять commit, push, merge или deploy без отдельного разрешения.

Журнал выполнения​

Выполнено 2026-09-28​

  • Regression evidence до исправления: добавленные data/component assertions дали ожидаемые 5/5 FAIL — отсутствовали стабильные ID четырёх групп, вложенный legal, отдельный all-modules, инвариант якорей product и безопасные footer selectors.
  • navigation.json: создана единая структура product → modules → implementation → company; legal вложен в company, добавлены RU/UZ/EN переводы и ссылка на каталог модулей.
  • navigation.ts: добавлены закрытые типы ID, runtime-проверка схемы, единый перевод вложенных ссылок и отдельные selectors футера с сохранением прежнего набора и порядка ссылок.
  • NavigationDialog: группы и ссылки получают стабильные keys, legal выводится семантически вложенной секцией с h4; существующая логика dialog, focus и закрытия не менялась.
  • CSS: четыре основные группы раскладываются в сетку 2×2 на широких экранах и последовательно на mobile; subsection юридической информации визуально подчинён «Компании».
  • Unit/component regression: 20/20 PASS в целевом запуске; полный Vitest в npm run check — 124/124 PASS.
  • Новый Playwright-контракт расширен до home, modules и legal pages для RU/UZ/EN на шести viewport: 54/54 PASS. Проверены порядок групп, только anchors в «Продукте», вложенный legal, локализованная ссылка «Все модули», отсутствие horizontal overflow и достижимость последней ссылки/CTA прокруткой.
  • Обнаружено и закрыто реальное расхождение вариантов: локализованные legal pages использовали отдельный header без navigation dialog. Теперь все три языка legal pages используют общие SiteHeader и SiteFooter, сохраняя локализованные CTA, language routes и юридическую навигацию документа.
  • Accessibility + IA matrix на home/modules/legal: 114 PASS, 0 FAIL.
  • Полный функциональный E2E без заведомо устаревших visual baselines: 323 PASS, 49 skipped, 0 FAIL.
  • npm run check — PASS: formatting, ESLint, Stylelint, 124/124 unit, TypeScript и production build.
  • npm run quality:ci — PASS: coverage 95.61% statements / 88.45% branches / 93.72% functions / 96.4% lines, changed-line coverage, architecture fixtures 14 PASS, cycles, bundle budget, links и SEO.
  • Полный Lighthouse gate на Node 22.23.3 — PASS для /ru/, /ru/partners/, /ru/careers/ в mobile и desktop: Performance 97–100, Accessibility 96–100, Best Practices 100, SEO 100, LCP 484–2254 ms, responsiveness proxy 24–94 ms, CLS 0.000–0.017, TTFB 1–2 ms.
  • Для детерминированного Lighthouse canonical routes заданы явно; Yandex Metrika теперь действительно инициализируется только после сохранённого или нового согласия. До согласия внешний Yandex tag не загружается.
  • Manual visual review: просмотрены все 18/18 actual open-menu screenshots RU для home, partners и careers на 390/430/768/1024/1440/1920; дополнительно проверены modules и legal на mobile/tablet/desktop. Порядок, вложенность, прокрутка, CTA, общий legal header и отсутствие горизонтального переполнения соответствуют контракту. Visual-сценарий разделён на независимые closed/open assertions, поэтому устаревший closed baseline больше не скрывает diff новой панели. После ручного просмотра обновлены только 18 × 2 open-menu baselines для Darwin и Linux; контрольные запуски без update-флага: 18/18 PASS на каждой платформе. Порог сохранён: maxDiffPixelRatio: 0.003.
  • Visual fixture теперь штатно нажимает «Отклонить» и ждёт исчезновения cookie-consent panel перед full-page/closed/open screenshot. Это сохраняет пользовательский сценарий и исключает независимый fixed overlay из проверки навигации. После ручного review только трёх затронутых open-menu diff на 1920 соответствующие Darwin/Linux эталоны обновлены; повторно 18/18 PASS на каждой платформе без update-флага.
  • UI/behavior/SEO дельта: изменена информационная архитектура открытого меню и общий header/footer подключён к локализованным legal pages. Routes, metadata, page copy, цены и interaction contract меню не менялись. Дополнительно восстановлен предусмотренный CSS-отступ FAQ, который ранее перекрывался общим селектором и ломал существующий layout assertion.

Завершение визуальной и общей проверки — 2026-09-30​

  • После отдельного разрешения пользователя вручную просмотрены actual и diff всех оставшихся 28/28 full-page/closed сценариев на каждой платформе. В актуальном UI нет визуальных поломок; дельта соответствует более позднему состоянию текущего main.
  • Ручным копированием обновлены только эти проверенные 28 × 2 Darwin/Linux эталонов. Вместе с ранее проверенными open-menu эталонами задача изменяет 92 snapshot-файла; автоматический --update-snapshots не использовался.
  • Контрольный visual-запуск без update-флага: 36/36 PASS на Darwin и 36/36 PASS в официальном Linux Playwright container.
  • Полный npm run quality запущен из Git root на Node 22.23.3 и завершён с кодом 0. Vitest: 124/124 PASS; accessibility: 60/60 PASS; полный Playwright: 377 PASS, 49 skipped; coverage, changed coverage, architecture, cycles, bundle, links, SEO и Lighthouse gates — PASS.
  • Финальный Lighthouse: Performance 96–100, Accessibility 96–100, Best Practices 100, SEO 100 для home, partners и careers в mobile/desktop.

Итоговое рабочее дерево​

  • Изменены navigation data, общие header/footer consumers, legal page layout, consent-gated analytics bootstrap, относящиеся unit/E2E/Lighthouse tests и этот журнал.
  • Исходный пользовательский untracked AGENTS.md не изменён и не добавлен.
  • Commit/push/deploy: не выполнялись — требуется отдельное разрешение.