docs: translate quality gate spec to russian

This commit is contained in:
Sergey Krylov 2026-06-14 21:50:58 +03:00
parent ee88b29181
commit 2e79e69403

View File

@ -1,92 +1,94 @@
# Quality Gate, API Contract, and Documentation Refresh Design # Дизайн стабилизации quality gate, API-контракта и документации
## Status ## Статус
Approved for specification on 2026-06-14. Одобрено для спецификации 2026-06-14.
## PRD ## PRD
### Problem ### Проблема
MoexVibe has accumulated coordination debt between tests, generated contracts, and documentation. В MoexVibe накопился координационный технический долг между тестами, сгенерированными контрактами
The application still builds, but the default backend quality gate is not trustworthy: и документацией. Приложение всё ещё собирается, но стандартный backend quality gate сейчас нельзя
считать надёжным:
- `npm run lint` fails on an unused variable in a backend test. - `npm run lint` падает из-за неиспользуемой переменной в backend-тесте.
- `npm run test:backend` fails because some backend tests call the live MOEX API through the real - `npm run test:backend` падает, потому что часть backend-тестов обращается к живому MOEX API через
`MoexClientService`. настоящий `MoexClientService`.
- The live MOEX failures surface as Vitest `DataCloneError` reports because Axios errors contain - Ошибки live MOEX-запросов проявляются как Vitest `DataCloneError`, потому что `AxiosError`
non-cloneable request configuration functions. содержит функции в конфигурации запроса, которые нельзя клонировать между worker'ами.
- `docs/openapi/openapi.yaml` and `apps/frontend/src/api/types.ts` do not include current `auth`, - `docs/openapi/openapi.yaml` и `apps/frontend/src/api/types.ts` не содержат актуальные эндпоинты
`portfolios`, and `securities/screener` endpoints. `auth`, `portfolios` и `securities/screener`.
- README, AGENTS, and Docusaurus pages describe an older state of the repo in several places. - README, AGENTS и страницы Docusaurus местами описывают старое состояние репозитория.
- `npm run build:docs` succeeds but emits Docusaurus broken-link warnings for `/`. - `npm run build:docs` успешно генерирует статические файлы, но выводит предупреждения Docusaurus о
broken link на `/`.
This makes future feature work slower: contributors cannot tell which command output matters, which Из-за этого следующие задачи делать медленнее: разработчику неочевидно, какой вывод команд важен,
API contract is current, or whether backend tests are failing because of application behavior or a какой API-контракт актуален и почему backend-тесты падают: из-за поведения приложения или из-за
network dependency. сетевой зависимости.
### Goals ### Цели
1. Make default quality checks deterministic and suitable for local development and CI. 1. Сделать стандартные проверки детерминированными и пригодными для локальной разработки и CI.
2. Keep live MOEX checks available, but move them out of the default unit-test path. 2. Сохранить live MOEX-проверки, но вынести их из стандартного unit-test пути.
3. Re-establish a clear source of truth for the OpenAPI contract. 3. Вернуть понятный источник правды для OpenAPI-контракта.
4. Regenerate or synchronize frontend OpenAPI types with the current backend routes. 4. Перегенерировать или синхронизировать frontend OpenAPI-типы с текущими backend routes.
5. Bring README, AGENTS, and Docusaurus docs in line with the current repo. 5. Привести README, AGENTS и Docusaurus-документацию к текущему состоянию репозитория.
6. Remove actionable Docusaurus broken-link warnings from the docs build. 6. Убрать actionable предупреждения Docusaurus о broken links из `npm run build:docs`.
### Non-Goals ### Не входит в задачу
- No user-facing feature changes. - Пользовательские feature-изменения.
- No deep refactor of `PortfolioService` or `MoexClientService`. - Глубокий рефакторинг `PortfolioService` или `MoexClientService`.
- No migration to a fully generated frontend API client. - Переход frontend API-клиента на полностью сгенерированный клиент.
- No Redis, database, auth model, or portfolio analytics redesign. - Redis, изменение схемы БД, redesign auth-модели или portfolio analytics.
- No CI provider migration. - Миграция CI-провайдера.
## Current Findings ## Текущие находки
### Passing Checks ### Проходящие проверки
- `npm run test:frontend` passes: 22 files, 95 tests. - `npm run test:frontend` проходит: 22 файла, 95 тестов.
- `npm run format:check` passes. - `npm run format:check` проходит.
- `npm run build:backend` passes. - `npm run build:backend` проходит.
- `npm run build:frontend` passes. - `npm run build:frontend` проходит.
- `npm run build:docs` produces static files successfully. - `npm run build:docs` успешно генерирует статические файлы.
### Failing or Noisy Checks ### Падающие или шумные проверки
- `npm run lint` fails in - `npm run lint` падает в `apps/backend/src/modules/securities/screener.service.spec.ts`, потому
`apps/backend/src/modules/securities/screener.service.spec.ts` because `moexClient` is assigned что `moexClient` присваивается, но не используется.
but not used. - `npm run test:backend` падает с unhandled Vitest errors. Затронутые specs создают настоящий
- `npm run test:backend` fails with unhandled Vitest errors. The affected specs instantiate the real `MoexClientService` и ходят в MOEX:
`MoexClientService` and call MOEX:
- `apps/backend/src/modules/moex-client/moex-client.service.spec.ts` - `apps/backend/src/modules/moex-client/moex-client.service.spec.ts`
- `apps/backend/src/modules/securities/securities.service.spec.ts` - `apps/backend/src/modules/securities/securities.service.spec.ts`
- `apps/backend/src/modules/candles/candles.service.spec.ts` - `apps/backend/src/modules/candles/candles.service.spec.ts`
- similar service specs for shares and bonds also rely on live MOEX access. - похожие service specs для shares и bonds тоже зависят от live MOEX-доступа.
- `npm run build:docs` warns that many pages link to `/`. - `npm run build:docs` предупреждает, что многие страницы ссылаются на `/`.
### Stale Documentation and Contract Artifacts ### Устаревшая документация и контрактные артефакты
- `AGENTS.md` says `npm run lint` is backend-only and frontend tests are absent. - `AGENTS.md` говорит, что `npm run lint` проверяет только backend, а frontend-тестов нет.
- `apps/docs/docs/development/testing.md` says frontend tests are absent. - `apps/docs/docs/development/testing.md` говорит, что frontend-тестов нет.
- `apps/docs/docs/development/commands.md` omits `test:frontend`, docs scripts, and frontend lint. - `apps/docs/docs/development/commands.md` не описывает `test:frontend`, docs scripts и frontend
- `apps/docs/docs/frontend/routes.md` omits `/login`, `/register`, `/profile`, `/portfolios`, lint.
`/portfolios/:id`, and `/screener`. - `apps/docs/docs/frontend/routes.md` не описывает `/login`, `/register`, `/profile`,
- `apps/docs/docs/frontend/overview.md` omits auth, portfolio, screener, and test directories. `/portfolios`, `/portfolios/:id` и `/screener`.
- `apps/docs/docs/backend/api.md` omits portfolio and screener endpoints. - `apps/docs/docs/frontend/overview.md` не описывает auth, portfolio, screener и test-директории.
- `apps/docs/docs/backend/portfolio.md` documents `PATCH /api/v1/portfolios/:id/patch`, while the - `apps/docs/docs/backend/api.md` не содержит portfolio и screener endpoints.
controller implements `PATCH /api/v1/portfolios/:id`. - `apps/docs/docs/backend/portfolio.md` документирует `PATCH /api/v1/portfolios/:id/patch`, хотя
- `docs/openapi/openapi.yaml` and `apps/frontend/src/api/types.ts` only contain the early health, controller реализует `PATCH /api/v1/portfolios/:id`.
search, shares, bonds, and candles paths. - `docs/openapi/openapi.yaml` и `apps/frontend/src/api/types.ts` содержат только ранние paths для
health, search, shares, bonds и candles.
## Domain Model ## Доменная модель
### Quality Gate ### Quality Gate
A quality gate is a repeatable command that developers can run without external dependencies unless Quality gate: это повторяемая команда, которую разработчик может запускать без внешних зависимостей,
the command explicitly says otherwise. если сама команда явно не говорит обратного.
Default gates: Стандартные проверки:
- `npm run lint` - `npm run lint`
- `npm run test:backend` - `npm run test:backend`
@ -96,106 +98,108 @@ Default gates:
- `npm run build:docs` - `npm run build:docs`
- `npm run format:check` - `npm run format:check`
Opt-in gates: Opt-in проверки:
- Live MOEX integration checks. These may use network access and should not run in default unit-test - Live MOEX integration checks. Они могут требовать network access и не должны запускаться в
or CI jobs unless explicitly requested. стандартных unit tests или CI jobs без явного запроса.
### Contract Source ### Источник API-контракта
The authoritative backend contract is the NestJS Swagger document generated from controllers and DTO Авторитетный backend contract: NestJS Swagger document, который генерируется из controllers и DTO
decorators at `/api/docs-json`. decorators по `/api/docs-json`.
Generated or synchronized artifacts: Сгенерированные или синхронизированные артефакты:
- `docs/openapi/openapi.yaml` as a checked-in human-readable snapshot. - `docs/openapi/openapi.yaml`: checked-in человекочитаемый snapshot.
- `apps/frontend/src/api/types.ts` as generated TypeScript path and schema types. - `apps/frontend/src/api/types.ts`: сгенерированные TypeScript path и schema types.
- Docusaurus API pages as explanatory documentation, not the canonical machine contract. - Docusaurus API pages: поясняющая документация, но не канонический machine contract.
### Documentation Source ### Источник документации
Documentation should describe the current repository state, not a historical implementation plan. Документация должна описывать текущее состояние репозитория, а не исторический план реализации.
Superpowers specs and plans remain project history; README, AGENTS, and Docusaurus pages are the Superpowers specs и plans остаются историей проекта. README, AGENTS и Docusaurus pages являются
current onboarding surface. актуальной onboarding-поверхностью.
## ADR ## ADR
### Decision ### Решение
Split backend tests into deterministic unit tests and opt-in live MOEX integration tests. Разделить backend tests на детерминированные unit tests и opt-in live MOEX integration tests.
### Rationale ### Обоснование
The default backend test command currently mixes unit behavior with external network availability. Стандартная backend test command сейчас смешивает unit-поведение и доступность внешней сети. Это
That makes failures ambiguous and produces noisy Vitest serialization errors when Axios rejects with делает failures неоднозначными и порождает шумные Vitest serialization errors, когда Axios
non-cloneable configuration fields. Unit tests should verify application logic with controlled возвращает rejection с non-cloneable configuration fields. Unit tests должны проверять логику
fixtures. Live MOEX tests are still valuable, but they belong in a separately named command with an приложения на контролируемых fixtures. Live MOEX tests полезны, но должны быть отдельной явно
explicit environment requirement. названной командой с понятным требованием к окружению.
### Consequences ### Последствия
- `npm run test:backend` becomes stable offline. - `npm run test:backend` становится стабильной offline-командой.
- Live MOEX coverage remains available through a dedicated integration command. - Live MOEX coverage остаётся доступным через отдельную integration command.
- Some existing specs will change from "real MOEX smoke test" to "service behavior with mocked - Часть существующих specs изменится с "real MOEX smoke test" на "service behavior with mocked
`MoexClientService`". `MoexClientService`".
- Contract drift becomes visible because OpenAPI snapshots and frontend generated types are updated - Contract drift станет видимым, потому что OpenAPI snapshots и frontend generated types будут
as part of this work. обновлены в рамках этой работы.
## Backend Architecture ## Backend Architecture
### Unit Test Boundary ### Граница unit tests
Service tests for `SharesService`, `BondsService`, `CandlesService`, and `SecuritiesService` should Service tests для `SharesService`, `BondsService`, `CandlesService` и `SecuritiesService` должны
mock `MoexClientService` and `CacheService`. mock'ать `MoexClientService` и `CacheService`.
The mocked data should exercise behavior that matters to MoexVibe: Mocked data должны проверять поведение, важное для MoexVibe:
- normalized share data is returned from cached or fetched MOEX client data; - нормализованные share data возвращаются из cached или fetched MOEX client data;
- normalized bond data handles missing market fields as nullable values; - нормализованные bond data корректно обрабатывают отсутствующие market fields как nullable values;
- candles are mapped into the public response shape; - candles мапятся в public response shape;
- search and screener behavior uses deterministic fixture rows; - search и screener используют детерминированные fixture rows;
- cache metadata remains represented through `{ data, meta }` where service contracts require it. - cache metadata остаётся представленной через `{ data, meta }`, где этого требуют service
contracts.
### Live Integration Test Boundary ### Граница live integration tests
Live MOEX checks should be isolated in `*.integration.spec.ts` files or an equivalent explicit test Live MOEX checks должны быть изолированы в `*.integration.spec.ts` files или эквивалентном явном
path. They should only run through a dedicated command such as `npm run test:integration -w test path. Они должны запускаться только через отдельную команду, например
apps/backend` and should document that network access is required. `npm run test:integration -w apps/backend`, и должны документировать, что для них требуется network
access.
The integration command should not be part of the default `npm run test:backend` command. Integration command не должна входить в стандартный `npm run test:backend`.
### OpenAPI Decorators ### OpenAPI decorators
Controllers that already exist should expose enough Swagger metadata for generated path types: Существующие controllers должны отдавать достаточно Swagger metadata для generated path types:
- Auth routes: register, login, refresh, logout, me, profile update. - Auth routes: register, login, refresh, logout, me, profile update.
- Securities routes: search and screener. - Securities routes: search и screener.
- Portfolio routes: list, create, detail, update, delete, position mutations, analytics. - Portfolio routes: list, create, detail, update, delete, position mutations, analytics.
- Existing shares, bonds, candles, and health routes. - Существующие shares, bonds, candles и health routes.
The implementation should prefer existing DTOs and response DTOs. If a response lacks a DTO and В реализации нужно предпочитать существующие DTO и response DTO. Если для response нет DTO и
adding one would be large, the first pass may use minimal response decorators while keeping runtime добавление полного DTO слишком раздувает первый проход, можно использовать минимальные response
behavior unchanged. decorators без изменения runtime behavior.
## Frontend Architecture ## Frontend Architecture
### Generated Types ### Generated Types
`apps/frontend/src/api/types.ts` should be regenerated from the current backend Swagger JSON after `apps/frontend/src/api/types.ts` должен быть перегенерирован из текущего backend Swagger JSON после
backend Swagger metadata includes the current routes. того, как backend Swagger metadata будет покрывать актуальные routes.
The existing hand-written `responses.ts` and API wrapper modules remain in place for this epic. The Существующие hand-written `responses.ts` и API wrapper modules остаются на месте в этом эпике. Цель:
goal is contract freshness, not a full client rewrite. свежесть контракта, а не полный rewrite клиента.
### Tests ### Tests
Frontend tests already exist and pass. This epic should not rewrite frontend testing architecture. Frontend tests уже существуют и проходят. Этот эпик не должен переписывать frontend testing
If API response types change, update frontend tests only where the regenerated contract reveals a architecture. Если API response types изменятся, frontend tests нужно обновлять только там, где
real mismatch. перегенерированный contract выявит реальное несоответствие.
## OpenAPI Contract Scope ## OpenAPI Contract Scope
The synchronized contract should include at least these paths under `/api/v1`: Синхронизированный contract должен включать минимум эти paths под `/api/v1`:
- `GET /health` - `GET /health`
- `POST /auth/register` - `POST /auth/register`
@ -229,21 +233,22 @@ The synchronized contract should include at least these paths under `/api/v1`:
### README ### README
Update README so quickstart and test sections mention backend, frontend, and docs workspaces. Обновить README так, чтобы quickstart и test sections упоминали backend, frontend и docs
workspaces.
### AGENTS ### AGENTS
Update AGENTS to reflect: Обновить AGENTS:
- `apps/docs` is part of the workspace. - `apps/docs` является частью workspace.
- `npm run lint` runs backend and frontend lint. - `npm run lint` запускает backend и frontend lint.
- frontend tests exist. - frontend tests существуют.
- pre-commit checks exist through Husky and lint-staged. - pre-commit checks существуют через Husky и lint-staged.
- CI exists under `.gitea/workflows/ci.yml`. - CI существует в `.gitea/workflows/ci.yml`.
### Docusaurus ### Docusaurus
Update current onboarding pages: Обновить текущие onboarding pages:
- development commands; - development commands;
- testing; - testing;
@ -254,36 +259,36 @@ Update current onboarding pages:
- backend API; - backend API;
- backend portfolio. - backend portfolio.
Fix Docusaurus config or docs links so `npm run build:docs` no longer reports broken links to `/`. Исправить Docusaurus config или docs links так, чтобы `npm run build:docs` больше не сообщал о
The separate update-check warning about `/Users/ksv741/.config` permissions is external to the repo broken links на `/`. Отдельное update-check warning про permissions в `/Users/ksv741/.config`
and does not need to be fixed in this epic. является внешним к репозиторию и в этот эпик не входит.
## Implementation Phases ## Этапы реализации
### Phase 1: Stabilize Default Checks ### Этап 1: стабилизировать стандартные проверки
1. Fix the unused backend test variable that breaks lint. 1. Исправить неиспользуемую backend test variable, которая ломает lint.
2. Convert default backend service specs away from live MOEX calls. 2. Перевести стандартные backend service specs с live MOEX calls на mocked dependencies.
3. Move or add live MOEX smoke coverage under an opt-in integration command. 3. Вынести или добавить live MOEX smoke coverage под opt-in integration command.
4. Verify `npm run lint` and `npm run test:backend`. 4. Проверить `npm run lint` и `npm run test:backend`.
### Phase 2: Refresh Contract Artifacts ### Этап 2: обновить contract artifacts
1. Add or complete Swagger metadata for current routes. 1. Добавить или завершить Swagger metadata для актуальных routes.
2. Regenerate `apps/frontend/src/api/types.ts`. 2. Перегенерировать `apps/frontend/src/api/types.ts`.
3. Synchronize `docs/openapi/openapi.yaml` with the current contract. 3. Синхронизировать `docs/openapi/openapi.yaml` с текущим contract.
4. Verify generated paths include auth, screener, and portfolio routes. 4. Проверить, что generated paths включают auth, screener и portfolio routes.
### Phase 3: Refresh Documentation ### Этап 3: обновить документацию
1. Update README and AGENTS. 1. Обновить README и AGENTS.
2. Update Docusaurus development, frontend, backend, and portfolio pages. 2. Обновить Docusaurus development, frontend, backend и portfolio pages.
3. Fix Docusaurus broken `/` link warning. 3. Исправить Docusaurus broken `/` link warning.
4. Verify `npm run build:docs`. 4. Проверить `npm run build:docs`.
### Phase 4: Full Verification ### Этап 4: полная проверка
Run: Запустить:
```bash ```bash
npm run lint npm run lint
@ -297,30 +302,32 @@ npm run format:check
## Acceptance Criteria ## Acceptance Criteria
- `npm run lint` exits 0. - `npm run lint` завершается с exit code 0.
- `npm run test:backend` exits 0 without live MOEX/network dependency. - `npm run test:backend` завершается с exit code 0 без live MOEX/network dependency.
- `npm run test:frontend` exits 0. - `npm run test:frontend` завершается с exit code 0.
- `npm run build:backend` exits 0. - `npm run build:backend` завершается с exit code 0.
- `npm run build:frontend` exits 0. - `npm run build:frontend` завершается с exit code 0.
- `npm run build:docs` exits 0 and no longer reports Docusaurus broken links for `/`. - `npm run build:docs` завершается с exit code 0 и больше не сообщает о Docusaurus broken links на
- `npm run format:check` exits 0. `/`.
- `apps/frontend/src/api/types.ts` includes current auth, screener, and portfolio paths. - `npm run format:check` завершается с exit code 0.
- `docs/openapi/openapi.yaml` includes current auth, screener, and portfolio paths. - `apps/frontend/src/api/types.ts` содержит актуальные auth, screener и portfolio paths.
- README, AGENTS, and Docusaurus docs no longer claim that frontend tests are absent. - `docs/openapi/openapi.yaml` содержит актуальные auth, screener и portfolio paths.
- Portfolio docs use `PATCH /api/v1/portfolios/:id`, matching the controller. - README, AGENTS и Docusaurus docs больше не утверждают, что frontend tests отсутствуют.
- Portfolio docs используют `PATCH /api/v1/portfolios/:id`, что соответствует controller.
## Risks ## Риски
- Swagger decorators may expose DTO gaps that were previously hidden by hand-written frontend types. - Swagger decorators могут показать DTO gaps, которые раньше были скрыты hand-written frontend
Keep the first pass focused on path and schema freshness; defer API-client redesign. types. Первый проход должен оставаться сфокусированным на свежести paths и schemas; redesign
- Live MOEX tests may still fail under network restrictions. That is acceptable only for the API-клиента откладывается.
opt-in integration command, not for the default backend test command. - Live MOEX tests могут по-прежнему падать в окружениях с network restrictions. Это допустимо только
- Regenerating OpenAPI artifacts can produce broad diffs. Review generated changes separately from для opt-in integration command, но не для default backend test command.
hand-written docs changes. - Regenerating OpenAPI artifacts может дать большой diff. Generated changes нужно ревьюить отдельно
от hand-written docs changes.
## Spec Self-Review ## Self-Review спецификации
- Placeholder scan: no placeholder markers or incomplete sections. - Placeholder scan: placeholder markers и незавершённые sections отсутствуют.
- Internal consistency: default tests are offline; live MOEX checks are opt-in. - Internal consistency: default tests остаются offline, live MOEX checks являются opt-in.
- Scope check: focused on quality gates, contract snapshots, and docs freshness. - Scope check: scope ограничен quality gates, contract snapshots и актуальностью docs.
- Ambiguity check: acceptance criteria name concrete commands and contract paths. - Ambiguity check: acceptance criteria называют конкретные commands и contract paths.