План завершения архитектурной миграции BELF
Архив. Этот план заменён
docs/quality-gates-refactor-plan.mdкак единственным исполняемым документом для текущего цикла. Он сохранён только как исторический контекст и не должен использоваться как источник параллельных задач или критериев готовности.
1. Назначение
Этот документ описывает оставшиеся работы после миграции home, calculator, navigation и layout. План рассчитан на последовательное исполнение разработчиком или AI-агентом.
Цель: перевести partners и careers на локальное владение компонентами и CSS
Modules, перенести общий контент из src/data в src/shared/data, удалить
composition-файлы и завершить документацию без изменения интерфейса и поведения.
План сначала утверждается, затем исполняется строго по этапам. Commit, push и deploy в него не входят.
2. Зафиксированное текущее состояние
- Home, calculator, navigation и общий footer уже используют CSS Modules.
npm run qualityпроходит: 11 unit/component tests и 72 Playwright tests.- Visual regression покрывает открытый и закрытый navbar на трёх маршрутах и шести viewport.
partnersподключает шесть CSS-файлов черезsrc/styles/pages/partners.css.careersподключает пять CSS-файлов черезsrc/styles/pages/careers.css.PartnersOverviewSections.cssиPartnersProgramSections.cssвладеют сразу несколькими секциями и должны быть разделены по фактическим владельцам.CareersSections.cssвладеет несколькими секциями и также должен быть разделён.- Общие
assets,contacts,modules,navigationиpricingнаходятся вsrc/dataи импортируются из pages, components и features. - Рабочее дерево уже содержит пользовательские и ранее выполненные изменения. Они не должны быть сброшены, перезаписаны или включены в механическую очистку.
3. Неприкосновенные ограничения
Во время миграции запрещено:
- менять тексты, DOM-порядок, маршруты, hash-якоря и SEO;
- менять размеры, отступы, цвета, typography, breakpoints и анимации;
- менять navbar, его прозрачность, контраст, overlay и focus management;
- менять формулы calculator и содержимое mailto-заявок;
- обновлять существующие screenshots для сокрытия расхождений;
- одновременно мигрировать несколько несвязанных секций;
- добавлять
!important, отключения линтеров или ослаблять тесты; - создавать пустые архитектурные директории «на будущее»;
- добавлять новые зависимости без доказанной необходимости;
- выполнять commit, push или deploy без отдельного запроса владельца;
- удалять или форматировать несвязанные пользовательские изменения.
Допустимы только архитектурные изменения с нулевой визуальной и поведенческой дельтой.
4. Целевая структура
src/
pages/
partners/
PartnersPage.tsx
data.ts
partners-utilities.css
sections/
PartnersHero/
PartnershipIntroSection/
PartnerTypesSection/
PartnerBenefitsSection/
ClientsRegistry/
CommissionSection/
PartnershipRulesSection/
TerritorySection/
InternationalSection/
PartnershipProcessSection/
PartnershipApplicationSection/
components/
ApplicationForm/
PartnersFooter/
careers/
CareersPage.tsx
data.ts
careers-utilities.css
sections/
CareersHero/
CandidateProfileSection/
ResponsibilitiesSection/
TrainingSection/
RequirementsSection/
ResumeSection/
components/
ResumeForm/
CareersFooter/
shared/
data/
assets.ts
contacts.ts
modules.ts
navigation.ts
pricing.ts
utils/
Каждая папка секции создаётся только в момент переноса реального компонента.
Общие page-utilities остаются обычным CSS, импортируемым напрямую entrypoint,
поскольку их классы намеренно используются несколькими секциями одной страницы.
Все остальные стили принадлежат компоненту через *.module.css.
5. Gate 0 — неизменяемый baseline
Перед первой кодовой правкой:
git status --short
npm run quality
git diff --check
Дополнительно сохранить:
- список текущих изменённых и untracked-файлов;
- число существующих snapshot-файлов;
- screenshots
/partners/и/careers/на шести viewport; - результаты прямого открытия обоих URL;
- текущие href обеих mailto-форм для фиксированных входных данных.
Gate 0
npm run quality— PASS;- все 72 существующих Playwright tests — PASS;
git diff --check— PASS;- baseline не создаётся поверх красного теста;
- исходное dirty-состояние записано в статус миграции.
При FAIL выполнение останавливается до установления причины.
6. Этап 1 — усилить защиту до рефакторинга
Текущие visual tests проверяют navbar в пределах viewport и не гарантируют идентичность нижних секций. До переноса CSS добавить:
- Full-page visual baseline для
/partners/и/careers/на всех шести Playwright projects. - Проверку отсутствия horizontal overflow после прокрутки всей страницы.
- Проверку отсутствия
pageerrorиconsole.errorна обоих маршрутах. - Component tests для
ApplicationFormиResumeForm:- обязательные поля;
- прежние subject/body;
- кодирование кириллицы;
- использование единого
contacts.emailHref.
- Поведенческую проверку client registry: loading, данные и ошибка загрузки.
Новые baseline создаются только один раз до миграции и просматриваются вручную.
После начала этапа 2 любые --update-snapshots запрещены.
Gate 1
- новые тесты краснеют при намеренной локальной поломке и проходят после её отмены;
- 12 full-page baseline существуют и визуально соответствуют текущему сайту;
npm run quality— PASS;- существующие 72 snapshots не изменены;
git diff --check— PASS.
7. Этап 2 — миграция partners
Работать строго в указанном порядке. После каждого пункта выполнять локальный gate и не переходить дальше при visual diff.
2.1 Page utilities
- Перенести только реально общие классы из
PartnersShared.cssвpartners-utilities.css. - Подключить utilities напрямую из
src/app/partners.tsx. - Не переносить в utilities стили, используемые одним компонентом.
2.2 Overview
- Разделить
PartnersOverviewSections.tsxнаPartnersHero,PartnershipIntroSection,PartnerTypesSectionиPartnerBenefitsSection. - Разделить
PartnersOverviewSections.cssна четыре CSS Module без изменения деклараций и порядка media queries. - Обновить
PartnersPage.tsxкак тонкую композицию.
2.3 Registry
- Перенести
ClientsRegistry.tsxиClientsRegistry.cssв одну папку. - Сохранить загрузку
partners/clients.json, состояния loading/error и текущую таблицу без изменения содержимого.
2.4 Program sections
Последовательно выделить из PartnersProgramSections.css стили владельцев:
CommissionSection;PartnershipRulesSection;TerritorySection;InternationalSection;PartnershipProcessSection;PartnershipApplicationSection.
Правило: selector переносится к компоненту, JSX которого содержит целевой className. Общие селекторы сначала получают доказанное общее назначение; копирование одного правила в несколько модулей без объяснения запрещено.
2.5 Form и footer
- Перенести
ApplicationFormс собственным CSS Module и тестом. - Перенести
PartnersFooterс собственным CSS Module. - Удалить
src/styles/pages/partners.cssтолько когда его последний import исчез иrgне находит ссылок на старые CSS.
Локальный gate после каждой partners-секции
npm run format:check
npm run lint
npm run lint:css
npm run typecheck
npm run test
npm run build
npx playwright test tests/e2e/navigation.spec.ts --grep "partners"
Также запускать full-page visual test /partners/ на шести viewport без
обновления baseline.
Gate 2
/partners/открывается напрямую;- все anchors и CTA ведут на прежние цели;
- registry показывает те же данные и состояния;
- application mailto совпадает побайтно после URL-decoding;
- нет horizontal overflow, console errors и layout shift;
- navbar tests и full-page screenshots — PASS на шести viewport;
src/styles/pages/partners.cssи старые component CSS удалены;PartnersPage.tsxсодержит только композицию секций;npm run check— PASS.
8. Этап 3 — миграция careers
Порядок:
- Общие классы
CareersShared.css→careers-utilities.css, прямой import изsrc/app/careers.tsx. CareersHero→ отдельная папка и CSS Module.- Разделить
CareersSections.cssмежду:CandidateProfileSection;ResponsibilitiesSection;TrainingSection;RequirementsSection.
ResumeSectionиResumeFormразнести на section и внутренний component, каждому дать собственный CSS Module.CareersFooter→ отдельная папка и CSS Module.- Удалить
src/styles/pages/careers.cssпосле удаления последнего import.
Сохранить текущие input names, required-атрибуты, accept для файла, тексты, mailto subject/body и anchors.
Локальный gate после каждой careers-секции
Использовать тот же статический набор команд, затем:
npx playwright test tests/e2e/navigation.spec.ts --grep "careers"
И отдельно full-page visual test /careers/ на шести viewport.
Gate 3
/careers/открывается напрямую;- все CTA и
#resumeработают; - resume form имеет прежнюю клавиатурную доступность и mailto;
- выбранный файл отображается как раньше;
- нет horizontal overflow и console errors;
- navbar tests и full-page screenshots — PASS на шести viewport;
src/styles/pages/careers.cssи старые component CSS удалены;CareersPage.tsxостаётся тонкой композицией;npm run check— PASS.
9. Этап 4 — перенос общего контента
Этот этап начинается только после зелёных Gates 2 и 3.
Переносить по одному файлу:
assets.ts;contacts.ts;navigation.ts;modules.ts;pricing.ts.
Для каждого файла:
- перенести его без изменения exported values и public types;
- заменить потребителей на alias
@/shared/data/<name>; - выполнить
rgпо старому пути; - запустить typecheck, unit tests и build;
- для contacts дополнительно проверить navbar, footers и обе формы;
- для modules/pricing дополнительно прогнать calculator tests;
- удалить исходный файл только после нулевого числа старых импортов.
После последнего переноса добавить ESLint boundary, запрещающий новые импорты из
@/data/* и зависимости shared от pages, features или app. Barrel
export не создавать, если он скрывает владельца или создаёт циклическую
зависимость.
Gate 4
rgне находит импортов изsrc/data;- директория
src/dataотсутствует либо пуста и удалена; - значения контактов, assets, navigation, modules и pricing не изменились;
- calculator unit tests — PASS;
- navbar, оба footer и обе формы используют один contacts source;
- циклических импортов нет;
npm run quality— PASS;- full-page visual baseline — PASS без обновления.
10. Этап 5 — очистка и документация
- Удалить только доказанно неиспользуемые CSS и exports.
- Проверить отсутствие пустых папок и orphan CSS Modules.
- Обновить
README.md,CONTRIBUTING.md,docs/architecture.mdи файл статуса. - Добавить фактическое дерево
partners,careers,shared/data. - Удалить из документации слова «legacy» только после реального удаления composition-файлов.
- Проверить инструкции запуска с чистой установкой через
npm ciбез удаления текущегоnode_modulesи без модификации lockfile.
Gate 5
- каждый
*.module.cssимпортируется ровно своим владельцем; - нет
src/styles/pages/partners.cssиcareers.css; - глобальный CSS содержит только tokens, reset, fonts и документированные utilities;
- README и architecture docs соответствуют фактическому дереву;
- нет несуществующих команд или путей в документации;
npm run quality— PASS;git diff --check— PASS.
11. Финальный quality gate
Работа завершена только при одновременном PASS всех пунктов.
Статика
-
npm run format:check; -
npm run lint; -
npm run lint:css; -
npm run typecheck; -
npm run test; -
npm run build; -
npm run quality; -
git diff --check.
Архитектура
-
PartnersPageиCareersPage— тонкие композиции; - каждая смысловая секция имеет собственную папку;
- локальный компонент импортирует собственный CSS Module;
- отсутствуют page composition CSS;
- отсутствуют orphan CSS и неиспользуемые exports;
- общий контент находится в
shared/dataи имеет один источник истины; - page-specific data остаются рядом со своей страницей;
- ESLint проверяет направление импортов;
- не добавлены отключения линтеров, новые
!importantили зависимости.
Поведение
-
/,/partners/,/careers/открываются напрямую; - navigation и все hash-якоря работают;
- navbar сохраняет фон, opacity, backdrop-filter и контраст;
- mobile overlay полностью перекрывает viewport;
- обе формы создают прежние mailto-ссылки;
- registry загружает прежние данные;
- calculator выдаёт прежние результаты;
- нет
pageerror,console.error, horizontal overflow и layout shift.
Визуальная идентичность
- существующие navbar snapshots проходят для 3 маршрутов × 6 viewport;
- full-page snapshots проходят для partners и careers × 6 viewport;
- baseline не обновлялся после начала миграции;
- representative mobile, tablet и desktop screenshots просмотрены вручную;
- тексты, размеры, цвета, spacing, typography и breakpoints не изменились.
Git и CI
- исходные пользовательские изменения сохранены;
- deploy по-прежнему зависит от quality/e2e;
- commit, push и deploy не выполнялись без отдельного запроса;
- итоговый отчёт содержит
git status --short.
12. Стоп-условия
Текущая итерация немедленно останавливается, если:
- screenshot отличается от baseline;
- изменилась computed style, геометрия или DOM-последовательность;
- появился
pageerror,console.errorили horizontal overflow; - перестал работать URL, anchor, navbar, registry или форма;
- тест становится зелёным только после ослабления assertion;
- требуется
!importantили изменение CSS declaration для компенсации каскада; - обнаружено пересечение с неизвестным пользовательским изменением.
При остановке snapshot не обновляется. Сначала фиксируются точный selector, computed property и причина дельты, затем исправляется архитектурная ошибка и повторяется полный gate текущего этапа.
13. Формат отчёта после этапа
Этап
- какие владельцы и файлы мигрированы;
- какие старые файлы доказанно удалены;
- какие обязанности разделены.
Проверки
- каждая команда: PASS/FAIL;
- маршруты и viewport;
- количество unit/e2e tests;
- visual comparison без update: PASS/FAIL.
Визуальная дельта
- отсутствует;
- либо точная причина и статус остановки.
Риски и остаток
- что ещё не мигрировано;
- какие compatibility utilities временно сохранены.
Git
- status;
- commit/push/deploy status.