From 8721e93849f72413ca065f9e738948f0ca10132e Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Sun, 6 Sep 2026 19:52:13 +0300 Subject: [PATCH] docs: record frontend audit remediation evidence --- development/audit-remediation.md | 54 +++++++++++---------- development/completion-evidence.md | 76 ++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 26 deletions(-) diff --git a/development/audit-remediation.md b/development/audit-remediation.md index 4fc011a..ba5dfca 100644 --- a/development/audit-remediation.md +++ b/development/audit-remediation.md @@ -21,14 +21,14 @@ ## Текущее состояние workflow - Bootstrap change: [`2026-08-23-establish-audit-remediation-workflow`](../../specs/openspec/changes/archive/2026-08-23-establish-audit-remediation-workflow/) — `archived`; это process foundation и не закрывает ни одного Audit ID. -- Последний завершённый audit remediation change: [`2026-08-26-harden-openspec-sdd-agent-resilience`](../../specs/openspec/changes/archive/2026-08-26-harden-openspec-sdd-agent-resilience/) — `archived`; SDD26R2-01–SDD26R2-06 закрыты. -- Единственный active remediation: `complete-frontend-audit-remediation`; [canonical change archived](../../specs/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/), terminal evidence ещё оформляется. +- Последний завершённый audit remediation change: [`2026-09-06-complete-frontend-audit-remediation`](../../specs/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/) — `archived`; FE26-02–FE26-18 закрыты, FE26-01 сохраняет прежнее evidence. +- Единственный active change: отсутствует. ## Текущая задача -Завершить delivery commits и Completion Evidence для -[`complete-frontend-audit-remediation`](../../specs/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/tasks.md). -Все tasks и независимая Validation завершены; до terminal evidence записи остаются `active`. +Frontend audit remediation завершена; [Completion Evidence][FE26-E] содержит +archive, delivery commits, verification и независимый verdict. Следующий +remediation change создаётся после выбора владельцем продолжения. ## Следующая рекомендуемая задача @@ -45,34 +45,36 @@ `S` — structural audit от 31 августа. Все 22 source findings сопоставлены 18 underlying claims ниже; одинаковые F IDs без source prefix неоднозначны. -Дата сопоставления: 06.09.2026. Текущий change всех `active` записей — -[`complete-frontend-audit-remediation`](../../specs/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/). -`already-covered` означает наличие проверяемой реализации, а `active` для неё — -незавершённое подтверждение текущей поставки, не повторную implementation task. +Дата сопоставления и закрытия FE26-02–FE26-18: 06.09.2026. +[Completion Evidence][FE26-E] содержит общий archive path, delivery commits +всех четырёх областей, точные commands/results и независимый PASS. +`already-covered` обозначает прежнюю реализацию, подтверждённую текущей +проверкой, без фиктивной повторной implementation task. Реализация прежних исправлений находится во frontend `c97f62b` и backend `55b100d`; эти идентификаторы не доказывают исторические approvals или gates. | Audit ID | Нормализованный claim | Sources | Disposition | Remediation status | Evidence / текущее состояние | | --- | --- | --- | --- | --- | --- | | FE26-01 | Общая граница финансового кэша при смене T-Bank connection. | [FE-A28] F1; [FE-S] F-01 | already-covered | done | 01.09.2026; [archive](../../specs/openspec/changes/archive/2026-09-01-harden-tbank-connection-cache-boundary/), delivery commits, gates и independent review — [существующее Completion Evidence](completion-evidence.md#2026-09-01-harden-tbank-connection-cache-boundary). | -| FE26-02 | Проверять соответствие generated types OpenAPI snapshot. | [FE-A28] F2; [FE-G] F-01 | already-covered | active | [check-openapi](../../frontend/scripts/check-openapi.mjs) включён в [verify](../../frontend/package.json); snapshot/types проверяются offline. Pre-commit состав честно описан в conventions. | -| FE26-03 | Events должен соблюдать принятую VM/view границу. | [FE-A28] F3 | confirmed | active | [Events VM](../../frontend/src/pages/account-events/ui/AccountEventsPage.vm.ts) владеет route/query/state/retry; [container](../../frontend/src/pages/account-events/ui/AccountEventsPage.tsx) использует прежние views. Остальные named pages уже разделены; см. FE26-13. | -| FE26-04 | Покрыть успешный public login journey. | [FE-G] F-02 | already-covered | active | [AppRoutes tests](../../frontend/src/app/routes/AppRoutes.test.tsx): форма, нормализованные credentials, реальный AuthProvider/MSW и protected landing. | -| FE26-05 | Безопасно отклонять невозможные календарные даты. | [FE-G] F-03 | already-covered | active | [Income VM](../../frontend/src/pages/account-income/ui/AccountIncomePage.vm.ts) проверяет finite date до ISO conversion; [regression tests](../../frontend/src/pages/account-income/ui/AccountIncomePage.test.tsx) покрывают invalid date и leap year. | -| FE26-06 | Включить type-only dependencies в public API guardrail. | [FE-G] F-04 | already-covered | active | [dependency-cruiser](../../frontend/dependency-cruiser.cjs) включает tsPreCompilationDeps; [shared API](../../frontend/src/shared/api/index.ts) экспортирует paths. | -| FE26-07 | Дать общим display/API primitives нейтральных владельцев. | [FE-G] F-05; [FE-S] F-07 | already-covered | active | [shared display](../../frontend/src/shared/lib/display.ts) владеет Money/date/logo; [apiErrorCode](../../frontend/src/shared/api/problem-details.ts) объединяет transport extraction. S F-07 расширяет тот же ownership claim API helper; повторной реализации нет. | -| FE26-08 | Синхронизировать entrypoint docs с фактическими gates. | [FE-G] F-06 | already-covered | active | [Frontend README](../../frontend/README.md), [conventions](../../frontend/docs/CONVENTIONS.md) и [workflow](frontend-workflow.md) описывают существующие команды, не обещая удалённые runtime/hygiene checks. | -| FE26-09 | Убрать механическое обязательное дробление каждого component. | [FE-G] F-07 | already-covered | active | [UI pattern](../../frontend/docs/UI-PATTERN.md) сохраняет semantic ownership и допускает tightly-coupled renderers; это guidance, а не line-count gate. Конкретное разделение крупных modules учтено отдельно FE26-13. | -| FE26-10 | Объединить protected query policy и endpoint query identity ownership. | [FE-G] F-08; [FE-S] F-05 | already-covered | active | [App defaults](../../frontend/src/app/ui/App.tsx), [T-Bank VM](../../frontend/src/features/tbank-connection/ui/TbankConnectionSection.vm.ts) и entity-owned options operations/portfolio; status использует общий authenticated query seam. | -| FE26-11 | Централизовать test cleanup и auth reset. | [FE-S] F-02 | already-covered | active | [Test setup](../../frontend/src/test/setup.ts): RTL cleanup, auth reset, MSW handler reset в общем afterEach. | -| FE26-12 | Убрать повтор server identity из Income view/model. | [FE-S] F-03 | confirmed | active | [Backend income service](../../backend/src/tbank/income-analytics.service.ts) передаёт instrumentKey; [Income VM](../../frontend/src/pages/account-income/ui/AccountIncomePage.vm.ts) проверяет и группирует готовую связь, не вычисляя identity. | -| FE26-13 | Выделить самостоятельные ответственности семи крупных TSX modules. | [FE-S] F-04 | already-covered | active | Income/Events/Accounts/Account state views, [route fallback](../../frontend/src/app/routes/RouteFallback.tsx), [guards](../../frontend/src/app/routes/RouteGuards.tsx), breadcrumbs и T-Bank loaded section выделены во frontend `c97f62b`. | -| FE26-14 | Устранить повтор test client policy и нестабильный cache lifetime. | [FE-S] F-06 | confirmed | active | [Test query factory](../../frontend/src/test/query.tsx) используется оставшимися auth/T-Bank harnesses; [auth test](../../frontend/src/features/auth/model/auth.test.tsx) проверяет сохранение client и seeded cache при rerender. | -| FE26-15 | Перенести компонентные стили из global CSS к владельцам. | [FE-S] F-08 | already-covered | active | [Global styles](../../frontend/src/app/styles.css) содержат базовые правила; AppShell, breadcrumbs и auth используют CSS Modules, StateView — Mantine props. | -| FE26-16 | Исправить source connectedAt contract вместо String coercion. | [FE-S] F-09 | already-covered | active | [Backend DTO](../../backend/src/tbank/tbank-connection.dto.ts) задаёт nullable date-time string; [frontend consumer](../../frontend/src/features/tbank-connection/ui/TbankConnectionSectionLoaded.tsx) не скрывает неверный transport type через String. | -| FE26-17 | Перенести auth validation и payment invariants из JSX к model owners. | [FE-S] F-10 | already-covered | active | [Auth validation](../../frontend/src/features/auth/model/validation.ts), [ledger display](../../frontend/src/entities/broker-operation/model/display.ts) владеют соответствующими правилами. | -| FE26-18 | Удалить redundant position modes и test-only proxy exports. | [FE-S] F-11 | already-covered | active | [PositionCard](../../frontend/src/pages/account/ui/components/PositionCard.view.tsx) выводит mode из kind; [StateView](../../frontend/src/shared/ui/StateView.tsx) не экспортирует Mantine Button; page barrels сохраняют product surface. | +| FE26-02 | Проверять соответствие generated types OpenAPI snapshot. | [FE-A28] F2; [FE-G] F-01 | already-covered | done | 06.09.2026; [FE26-E]. [check-openapi](../../frontend/scripts/check-openapi.mjs) включён в [verify](../../frontend/package.json); snapshot/types проверяются offline. Pre-commit состав честно описан в conventions. | +| FE26-03 | Events должен соблюдать принятую VM/view границу. | [FE-A28] F3 | confirmed | done | 06.09.2026; [FE26-E]. [Events VM](../../frontend/src/pages/account-events/ui/AccountEventsPage.vm.ts) владеет route/query/state/retry; [container](../../frontend/src/pages/account-events/ui/AccountEventsPage.tsx) использует прежние views. Остальные named pages уже разделены; см. FE26-13. | +| FE26-04 | Покрыть успешный public login journey. | [FE-G] F-02 | already-covered | done | 06.09.2026; [FE26-E]. [AppRoutes tests](../../frontend/src/app/routes/AppRoutes.test.tsx): форма, нормализованные credentials, реальный AuthProvider/MSW и protected landing. | +| FE26-05 | Безопасно отклонять невозможные календарные даты. | [FE-G] F-03 | already-covered | done | 06.09.2026; [FE26-E]. [Income VM](../../frontend/src/pages/account-income/ui/AccountIncomePage.vm.ts) проверяет finite date до ISO conversion; [regression tests](../../frontend/src/pages/account-income/ui/AccountIncomePage.test.tsx) покрывают invalid date и leap year. | +| FE26-06 | Включить type-only dependencies в public API guardrail. | [FE-G] F-04 | already-covered | done | 06.09.2026; [FE26-E]. [dependency-cruiser](../../frontend/dependency-cruiser.cjs) включает tsPreCompilationDeps; [shared API](../../frontend/src/shared/api/index.ts) экспортирует paths. | +| FE26-07 | Дать общим display/API primitives нейтральных владельцев. | [FE-G] F-05; [FE-S] F-07 | already-covered | done | 06.09.2026; [FE26-E]. [shared display](../../frontend/src/shared/lib/display.ts) владеет Money/date/logo; [apiErrorCode](../../frontend/src/shared/api/problem-details.ts) объединяет transport extraction. S F-07 расширяет тот же ownership claim API helper; повторной реализации нет. | +| FE26-08 | Синхронизировать entrypoint docs с фактическими gates. | [FE-G] F-06 | already-covered | done | 06.09.2026; [FE26-E]. [Frontend README](../../frontend/README.md), [conventions](../../frontend/docs/CONVENTIONS.md) и [workflow](frontend-workflow.md) описывают существующие команды, не обещая удалённые runtime/hygiene checks. | +| FE26-09 | Убрать механическое обязательное дробление каждого component. | [FE-G] F-07 | already-covered | done | 06.09.2026; [FE26-E]. [UI pattern](../../frontend/docs/UI-PATTERN.md) сохраняет semantic ownership и допускает tightly-coupled renderers; это guidance, а не line-count gate. Конкретное разделение крупных modules учтено отдельно FE26-13. | +| FE26-10 | Объединить protected query policy и endpoint query identity ownership. | [FE-G] F-08; [FE-S] F-05 | already-covered | done | 06.09.2026; [FE26-E]. [App defaults](../../frontend/src/app/ui/App.tsx), [T-Bank VM](../../frontend/src/features/tbank-connection/ui/TbankConnectionSection.vm.ts) и entity-owned options operations/portfolio; status использует общий authenticated query seam. | +| FE26-11 | Централизовать test cleanup и auth reset. | [FE-S] F-02 | already-covered | done | 06.09.2026; [FE26-E]. [Test setup](../../frontend/src/test/setup.ts): RTL cleanup, auth reset, MSW handler reset в общем afterEach. | +| FE26-12 | Убрать повтор server identity из Income view/model. | [FE-S] F-03 | confirmed | done | 06.09.2026; [FE26-E]. [Backend income service](../../backend/src/tbank/income-analytics.service.ts) передаёт instrumentKey; [Income VM](../../frontend/src/pages/account-income/ui/AccountIncomePage.vm.ts) проверяет и группирует готовую связь, не вычисляя identity. | +| FE26-13 | Выделить самостоятельные ответственности семи крупных TSX modules. | [FE-S] F-04 | already-covered | done | 06.09.2026; [FE26-E]. Income/Events/Accounts/Account state views, [route fallback](../../frontend/src/app/routes/RouteFallback.tsx), [guards](../../frontend/src/app/routes/RouteGuards.tsx), breadcrumbs и T-Bank loaded section выделены во frontend `c97f62b`. | +| FE26-14 | Устранить повтор test client policy и нестабильный cache lifetime. | [FE-S] F-06 | confirmed | done | 06.09.2026; [FE26-E]. [Test query factory](../../frontend/src/test/query.tsx) используется оставшимися auth/T-Bank harnesses; [auth test](../../frontend/src/features/auth/model/auth.test.tsx) проверяет сохранение client и seeded cache при rerender. | +| FE26-15 | Перенести компонентные стили из global CSS к владельцам. | [FE-S] F-08 | already-covered | done | 06.09.2026; [FE26-E]. [Global styles](../../frontend/src/app/styles.css) содержат базовые правила; AppShell, breadcrumbs и auth используют CSS Modules, StateView — Mantine props. | +| FE26-16 | Исправить source connectedAt contract вместо String coercion. | [FE-S] F-09 | already-covered | done | 06.09.2026; [FE26-E]. [Backend DTO](../../backend/src/tbank/tbank-connection.dto.ts) задаёт nullable date-time string; [frontend consumer](../../frontend/src/features/tbank-connection/ui/TbankConnectionSectionLoaded.tsx) не скрывает неверный transport type через String. | +| FE26-17 | Перенести auth validation и payment invariants из JSX к model owners. | [FE-S] F-10 | already-covered | done | 06.09.2026; [FE26-E]. [Auth validation](../../frontend/src/features/auth/model/validation.ts), [ledger display](../../frontend/src/entities/broker-operation/model/display.ts) владеют соответствующими правилами. | +| FE26-18 | Удалить redundant position modes и test-only proxy exports. | [FE-S] F-11 | already-covered | done | 06.09.2026; [FE26-E]. [PositionCard](../../frontend/src/pages/account/ui/components/PositionCard.view.tsx) выводит mode из kind; [StateView](../../frontend/src/shared/ui/StateView.tsx) не экспортирует Mantine Button; page barrels сохраняют product surface. | +[FE26-E]: completion-evidence.md#2026-09-06-complete-frontend-audit-remediation [FE-G]: ../audits/2026-08-frontend-repository-audits/frontend-repository-audit.md [FE-A28]: ../audits/2026-08-frontend-repository-audits/frontend-repository-audit-2026-08-28.md [FE-S]: ../audits/2026-08-frontend-repository-audits/frontend-structural-maintainability-audit.md diff --git a/development/completion-evidence.md b/development/completion-evidence.md index a02a43e..7444155 100644 --- a/development/completion-evidence.md +++ b/development/completion-evidence.md @@ -7,6 +7,82 @@ delivery commits, точные verification commands с наблюдёнными итог independent read-only review. Записи добавляются после archive и являются неизменяемой историей поставки. +## 2026-09-06-complete-frontend-audit-remediation + +**Change:** complete-frontend-audit-remediation (schema `wealth-ledger-sdd`) +**Archive:** [2026-09-06-complete-frontend-audit-remediation](../../specs/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/) +**Specs sync:** `skip_specs: true`; существующие Requirements не менялись. +Все 17 tasks завершены до archive; post-archive strict validation — +23 passed, 0 failed. + +### Delivery Map + +| Area | Status | Outcome | +| --- | --- | --- | +| frontend | affected | Income mapper потребляет и проверяет server membership; drill-down сохраняет repeated-ID entries при обновлении. Events использует page VM, auth/T-Bank tests — общую client factory со стабильным lifetime. Snapshot/types синхронизированы. | +| backend | affected | Income-specific entry subtype содержит required instrumentKey, вычисленный одним owner и используемый aggregation; Ledger DTO, exact Money и порядок сохранены. | +| specs | affected | Approved Proposal, Design, Tasks и metadata archived; искусственные Delta Specs не создавались. | +| docs | affected | Три immutable audit snapshots, index, 22 source findings в 18 registry records, as-built contract/ownership и backend-first update/rollback. | + +### Delivery commits + +| Repo | Commit | Subject | +| --- | --- | --- | +| frontend | `9e42148f6a9ad620b4fc9f6aef9ee2d80d73702b` | fix(frontend): complete audit remediation | +| backend | `bdc384766649bb48513055bb809f0d1b45b91f54` | fix(income): expose authoritative entry membership | +| specs (archive) | `ab231a6aac58f4e97377e4d4fb521e22d3f07fdb` | docs(specs): archive frontend audit remediation | +| docs (as-built) | `55d35c7f789478230c683a79e5c80563c75487b6` | docs: document frontend audit remediation delivery | + +### Verification + +Node-команды выполнены под Node 22 после `nvm use --silent` в affected repo; +для specs без `.nvmrc` использовался `nvm use --silent 22`. + +| Command / check | Наблюдённый результат | +| --- | --- | +| `npm run verify` (frontend, итоговая реализация) | PASS, exit 0; OpenAPI drift, TypeScript, Biome, 23 files / 108 tests, coverage, Knip, dependency boundaries и build. Coverage: statements 89.13%, branches 83.41%, functions 86.41%, lines 90.84%; 172 modules / 647 edges без violations. | +| `npm run test:run -- src/pages/account-income/ui/AccountIncomePage.test.tsx` (frontend) | PASS, exit 0; 19 tests, включая local errors/retry, opaque membership, signed payments и repeated-ID DOM updates. | +| `npm run test:run -- src/pages/account-income/ui/AccountIncomePage.test.tsx -t 'preserves every repeated-ID payment'` (frontend, до исправления VAL-01) | FAIL, exit 1: после reorder expected [C, A, B], received [A, C, A, B]. Тот же regression проходит в итоговом suite. | +| `npm run verify` (backend) | PASS, exit 0; lint, app/test TypeScript, 25 suites / 106 tests и build. | +| `npm run test:openapi-contract` (backend) | PASS, exit 0; 1 integration test, runtime Swagger соответствует frontend snapshot, включая income subtype и connectedAt. | +| `npm run verify` (docs, as-built перед delivery commit) | PASS, exit 0; 42 Markdown files, 0 issues и clean diff whitespace. | +| `openspec schema validate wealth-ledger-sdd --verbose` (specs) | PASS, exit 0; project-local schema valid. | +| `openspec validate complete-frontend-audit-remediation --type change --strict --store wealth-ledger-specs` (specs, перед archive) | PASS, exit 0; completed change valid. | +| `openspec archive complete-frontend-audit-remediation --yes --store wealth-ledger-specs` (specs) | PASS, exit 0; Task status Complete, archived as 2026-09-06-complete-frontend-audit-remediation. | +| `openspec validate --specs --strict --store wealth-ledger-specs` (specs, до и после archive) | PASS, exit 0; 23 passed, 0 failed. | +| Scoped local-file/source review (Python std-library) | PASS; три snapshots byte-equal originals с SHA-256 из index; 22 source IDs сопоставлены ровно один раз 18 FE26 records; 132 local file links разрешались до archive, archive links обновлены при finalization. | +| `git diff --check` (frontend/backend/specs/docs) | PASS. | +| Post-commit SHA-256 comparison (frontend/backend, Python std-library) | Все 14 поставленных files byte-equal прошедшему Validation дереву; commit hooks не внесли изменений. Frontend hooks также прошли formatting, dependency check и commitlint. | + +Raw snapshot 28 августа содержит исходное MD060 formatting и исключён из +Markdown style gate точным path по существующему raw-source pattern. Содержимое +сохранено byte-for-byte; live docs и index остаются в gate. + +### Semantic verification и independent read-only review + +Verdict: **PASS** в Validation #2. Critical findings — 0, Important findings — 0. +Проверены exact membership, UID/FIGI/ticker/type/operation fallback, currencies, +signed totals, receipt counts и порядок; повреждённая связь не выдаётся за +полный результат и восстанавливается retry. Полностью пустой ответ допустим. +Events state ownership и test-client lifetime соответствуют Design. + +Validation #1 обнаружила VAL-01: повторяющиеся operation IDs создавали +неуникальные React keys и лишние видимые payments после обновления. Локальные +occurrence keys устранили нарушение; regression на mounted drill-down проверяет +перестановку, две полностью одинаковые записи, удаление, отрицательные суммы +и сохранение открытой panel. Денежные вычисления и backend contract при этом +исправлении не менялись. + +FE26-02–FE26-18 закрыты текущей поставкой и проверкой. FE26-01 сохраняет +[собственное evidence](#2026-09-01-harden-tbank-connection-cache-boundary). +Прежние исправления frontend `c97f62b` и backend `55b100d` проверены как +существующее состояние; текущие gates не приписывают этим commits отсутствующих +исторических approvals или SDD lifecycle. + +Локальное обновление требует backend-first и перезагрузки frontend. Rollback +сначала возвращает consumer и snapshot/types, затем при необходимости provider; +сохранённые Ledger data, SQLite schema и credentials не изменяются. + ## 2026-09-01-harden-tbank-connection-cache-boundary **Change:** harden-tbank-connection-cache-boundary (schema `wealth-ledger-sdd`)