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
Назначение: быстрый обзор главной страницы. Здесь допускаются только ссылки на секции локализованной главной.
| ID | RU label | Базовый href |
|---|---|---|
platform | Платформа | /#platform |
modules-overview | Модули | /#modules |
proctoring | BELF Прокторинг | /#proctoring |
deployment | Размещение | /#deployment |
calculator | Калькулятор | /#calculator |
Инвариант: каждый href группы product после удаления locale-префикса содержит
/#...; отдельных страниц в этой группе нет.
2. Модули / Modullar / Modules
Назначение: перейти к каталогу модулей или к отдельной странице продуктовой возможности.
| ID | RU label | Базовый href |
|---|---|---|
all-modules | Все модули | /modules/ |
time-tracking | Учёт рабочего времени | /time-tracking/ |
employee-monitoring | Мониторинг сотрудников | /employee-monitoring/ |
productivity | Аналитика продуктивности | /productivity/ |
screenshots | Снимки экрана | /screenshots/ |
Название all-modules должно явно отличаться от якоря «Модули» в «Продукте»:
первое ведёт на самостоятельную страницу, второе — к обзору на главной.
3. Внедрение / Joriy etish / Implementation
Назначение: собрать самостоятельные страницы о выборе конфигурации, размещении, доступе и начале работы. Этот блок нужен, чтобы не маскировать такие страницы под модули и при этом выполнить контракт «Продукт — только главная».
| ID | RU label | Базовый href |
|---|---|---|
security | Безопасность | /security/ |
self-hosted | Self-hosted | /self-hosted/ |
pricing | Стоимость | /pricing/ |
download | Скачать BELF | /download/ |
docs | Техническая документация | /docs/ (localizeHref: false) |
4. Компания / Kompaniya / Company
Назначение: информация о BELF и Digital Revolution Makers, сотрудничестве и контакте с командой.
| ID | RU label | Базовый href |
|---|---|---|
about | О BELF | /about/ |
partners | Партнёрская программа | /partners/ |
careers | Работа в BELF | /careers/ |
contact | Связаться с командой | /#contact |
5. Правовая информация как подраздел «Компании»
legal не является равноправной основной колонкой. Это вложенный subsection в
визуальном и семантическом контейнере company, расположенный после основных
ссылок компании.
Сохраняемый набор ссылок:
| ID | RU label | Базовый href |
|---|---|---|
privacy | Обработка данных | /legal/privacy/ |
terms | Условия использования | /legal/terms/ |
monitoring | Мониторинг сотрудников | /legal/monitoring/ |
acceptable-use | Допустимое использование | /legal/acceptable-use/ |
Добавление DPA или Cookies в меню не входит в эту задачу: их routes существуют, но пользователь просил перегруппировку текущей навигации, а не расширение юридического раздела.
Порядок восприятия и layout-контракт
Порядок в DOM и на mobile:
- Продукт.
- Модули.
- Внедрение.
- Компания.
- Правовая информация внутри «Компании».
- Контактная 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как subsectioncompany, а не 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 как побочный эффект.
Этап 4. Отвязать footer от позиции групп
- До добавления новых 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.
- Сохранить один
navdialog, существующее 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.css | Desktop layout и визуальная иерархия |
src/widgets/site-header/NavigationDialogResponsive.module.css | Tablet/mobile layout |
src/widgets/site-header/SiteHeader.localization.test.tsx | Локализованная структура и href |
src/widgets/site-header/SiteHeader.test.tsx или отдельный data test | Component/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/124unit, TypeScript и production build.npm run quality:ci— PASS: coverage95.61% statements / 88.45% branches / 93.72% functions / 96.4% lines, changed-line coverage, architecture fixtures14 PASS, cycles, bundle budget, links и SEO.- Полный Lighthouse gate на Node
22.23.3— PASS для/ru/,/ru/partners/,/ru/careers/в mobile и desktop: Performance97–100, Accessibility96–100, Best Practices100, SEO100, LCP484–2254 ms, responsiveness proxy24–94 ms, CLS0.000–0.017, TTFB1–2 ms. - Для детерминированного Lighthouse canonical routes заданы явно; Yandex Metrika теперь действительно инициализируется только после сохранённого или нового согласия. До согласия внешний Yandex tag не загружается.
- Manual visual review: просмотрены все
18/18actual 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 × 2open-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/28full-page/closed сценариев на каждой платформе. В актуальном UI нет визуальных поломок; дельта соответствует более позднему состоянию текущегоmain. - Ручным копированием обновлены только эти проверенные
28 × 2Darwin/Linux эталонов. Вместе с ранее проверенными open-menu эталонами задача изменяет 92 snapshot-файла; автоматический--update-snapshotsне использовался. - Контрольный visual-запуск без update-флага:
36/36 PASSна Darwin и36/36 PASSв официальном Linux Playwright container. - Полный
npm run qualityзапущен из Git root на Node22.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, Accessibility96–100, Best Practices100, SEO100для 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: не выполнялись — требуется отдельное разрешение.