81 lines
12 KiB
Markdown
81 lines
12 KiB
Markdown
## Контекст
|
||
|
||
Frontend уже использует React, FSD, generated OpenAPI types и React Query, но получает OpenAPI непосредственно из работающего backend и вручную создаёт query/mutation hooks. Bearer header одновременно добавляется общим HTTP transport и передаётся отдельными вызовами. Локальная проверка состоит из разрозненных команд и не проверяет generated artifact, не изолирует API-тесты и не контролирует границы FSD-слоёв.
|
||
|
||
Причина изменения описана в `proposal.md`, а контрактные требования — в `specs/api-contract-generation/spec.md`.
|
||
|
||
## Цели и нецели
|
||
|
||
**Цели:**
|
||
|
||
- Сделать настройку frontend, генерацию API-контракта и локальную проверку воспроизводимыми без запущенного backend, кроме явной синхронизации контракта.
|
||
- Централизовать типизированную интеграцию React Query и auth transport без изменения существующих пользовательских сценариев и семантики cache.
|
||
- Создать чистый, проверяемый и ориентированный на агентов baseline разработки с API mocks только для тестов.
|
||
- Зафиксировать реализованный workflow в документации frontend и постоянной документации проекта.
|
||
|
||
**Нецели:**
|
||
|
||
- Не мигрируются routes, forms, state-views, view-model и ErrorBoundary; они относятся к `align-frontend-ui-patterns`.
|
||
- Не добавляются Storybook, Playwright, browser MSW worker, mock-режим разработки и CI configuration.
|
||
- Не меняются владение backend OpenAPI, API routes, authentication protocol и доменная терминология WealthLedger.
|
||
|
||
## Решения
|
||
|
||
### Воспроизводимый frontend baseline
|
||
|
||
Frontend будет объявлять Node 22 через `.nvmrc` и `package.json#engines`. Зависимости будут использовать точные версии, а lockfile будет перегенерирован. Toolchain перейдёт на совместимый baseline template, включая Mantine 9, строгие опции TypeScript, aliases Vite/TypeScript и tooling статического анализа.
|
||
|
||
Aliases будут одинаково определены в Vite и TypeScript. Существующие cross-slice imports будут использовать публичные API через `index.ts`; файлы внутри slice могут использовать относительные imports. `dependency-cruiser` будет проверять только направление FSD-слоёв, а использование public API останется документированным правилом review.
|
||
|
||
Точные версии выбраны вместо semver ranges, чтобы установки агентов и разработчиков воспроизводили один dependency graph. Собственный Node version checker отклонён: `.nvmrc` и `engines` сообщают ограничение без дополнительного пути к ошибке.
|
||
|
||
### Генерация OpenAPI из snapshot
|
||
|
||
`src/shared/api/spec/` будет хранить committed raw JSON snapshot из backend OpenAPI endpoint, а `src/shared/api/generated/schema.d.ts` останется committed generated artifact. Явная sync-команда получит endpoint, настроенный `VITE_API_BASE_URL`, провалидирует его генерацией и заменит оба artifacts только после успеха всех шагов. Временные файлы не позволят неудачному fetch или generation частично обновить контракт.
|
||
|
||
`openapi:generate` будет генерировать из committed snapshot. `openapi:check` независимо сгенерирует ожидаемую schema во временную директорию и сравнит её с committed artifact. Команда не обращается к backend, поэтому `verify` остаётся доступным offline.
|
||
|
||
Генерация напрямую из работающего backend отклонена, потому что обычные локальные проверки станут зависимы от его доступности. Преобразование snapshot в YAML отклонено, потому что сохранение опубликованного JSON исключает ненужную трансформацию.
|
||
|
||
### Типизированная интеграция queries и auth boundary
|
||
|
||
Shared OpenAPI client остаётся единственной HTTP entry point. `openapi-react-query` будет получать из него типизированные React Query operations; существующие query keys, `enabled`, stale times, retry policies, invalidations и отображение ошибок сохранятся. API request и response types продолжат выводиться из generated `paths`, а не дублировать DTOs.
|
||
|
||
Реализация authenticated fetch становится единственным владельцем Bearer header. Она исключает auth endpoints, делает ровно один retry только после `401` с `UNAUTHORIZED` и успешного refresh, а при неудачном refresh очищает session state. Query и mutation calls больше не передают Authorization самостоятельно. Initial session restoration должен обновлять и React state, и token reference, используемый transport; logout и неудачный refresh очищают оба и cache QueryClient.
|
||
|
||
Ручная передача headers отклонена: она дублирует cross-cutting security concern и может разойтись с поведением transport. Замена refresh semantics на library interceptor отклонена, потому что существующие refresh single-flight и browser lock уже являются корректным product behavior.
|
||
|
||
### MSW только для тестов и целевые regression tests
|
||
|
||
MSW будет запускаться только через Vitest setup и handlers для текущего WealthLedger API. Не будут добавлены service worker, команда `dev:mock`, mock build и application mock mode. Поэтому unit и hook tests смогут выполнять успешные и ошибочные API scenarios без backend.
|
||
|
||
Целевые transport tests проверят Bearer injection, исключение auth endpoints, один refresh/retry для `UNAUTHORIZED`, очистку session после неудачного refresh и авторизацию восстановленной session. Coverage формируется как report, но не получает числовой threshold до стабилизации UI patterns.
|
||
|
||
Browser mocking отклонён, потому что он создаёт незапрошенный второй application mode. Coverage threshold отклонён, потому что текущий baseline слишком мал для стабильной и содержательной цели.
|
||
|
||
### Единый локальный quality gate и постоянная документация
|
||
|
||
`npm run verify` будет запускать OpenAPI drift detection, typecheck, Biome, unit tests, coverage reporting, Knip, dependency-cruiser и production build. Все проверки должны проходить без baseline suppressions или allowlists. Husky устанавливается через `prepare`; pre-commit форматирует staged files и запускает contract и dependency checks, а commit-msg проверяет Conventional Commits.
|
||
|
||
Frontend `AGENTS.md` остаётся коротким индексом «задача → документ». Его локальные docs описывают API workflow, test setup, structure и conventions. После реализации `docs/development/` получит постоянное cross-repository описание frontend workflow: требуемую Node version, contract synchronization и quality-gate commands. Так знания о реализованном процессе не останутся только в frontend repository.
|
||
|
||
Запуск полного gate в каждом pre-commit hook отклонён, потому что tests и builds замедляют обычные commits; `verify` остаётся единственным явным полным gate. Storybook и e2e build steps исключены вместе с их tools.
|
||
|
||
## Риски и компромиссы
|
||
|
||
- [Обновления Mantine и совместимых зависимостей могут выявить несовместимости исходного кода] → Устранить все type, lint и build errors до принятия нового lockfile.
|
||
- [Committed snapshot может отставать от backend] → Backend остаётся источником истины; явный sync обновляет snapshot, а локальная проверка гарантирует только внутреннюю согласованность.
|
||
- [Централизация Bearer injection может сломать восстановленные sessions] → Синхронизировать token reference во время initial refresh и покрыть поведение transport tests.
|
||
- [Static analyzers могут сообщить о существующем коде] → Исправить код или точно настроить tool до получения зелёного baseline; не скрывать findings временными waivers.
|
||
- [Hooks запускаются не во всех окружениях разработчиков] → `npm run verify` остаётся независимо запускаемым и документированным completion gate.
|
||
|
||
## План миграции
|
||
|
||
1. Обновить и зафиксировать frontend toolchain, настроить aliases и static-analysis tools, привести текущий исходный код к новым checks.
|
||
2. Добавить OpenAPI snapshot, sync/generate/check commands, затем проверить generated artifact из committed snapshot без доступа к backend.
|
||
3. Мигрировать API queries и mutations на typed integration, централизовать Bearer handling и добавить transport regression coverage.
|
||
4. Добавить MSW только для тестов, coverage reporting, git hooks и единый скрипт `verify`.
|
||
5. Обновить frontend agent documentation и `docs/development/` описанием реализованного workflow, затем запустить полный quality gate.
|
||
|
||
Изменение локально для frontend и может быть отменено откатом его frontend и documentation commits. Backend contract не меняется.
|