Compare commits

..

No commits in common. "8dab915edd1be0abf5d63558bdff62955bfdc0b9" and "b27d6ad83645c0ed24ef9f62ec44f9c4dab37d63" have entirely different histories.

9 changed files with 28 additions and 328 deletions

View File

@ -507,19 +507,13 @@ roadmap.md и inbox.md никогда не являются основанием
## graphify ## graphify
This project has a knowledge graph in `graphify-out/` with god nodes, community structure, and cross-file relationships. The graph is a local artifact, not a tracked repo asset. This project has a knowledge graph at graphify-out/ with god nodes, community structure, and cross-file relationships.
When the user types `/graphify`, invoke the `skill` tool with `skill: "graphify"` before doing anything else. When the user types `/graphify`, invoke the `skill` tool with `skill: "graphify"` before doing anything else.
Rules: Rules:
- Используй `graphify` в первую очередь, когда задача связана с архитектурой, границами модулей, кросс-файловым влиянием или трассировкой потока данных. - For codebase questions, first run `graphify query "<question>"` when graphify-out/graph.json exists. Use `graphify path "<A>" "<B>"` for relationships and `graphify explain "<concept>"` for focused concepts. These return a scoped subgraph, usually much smaller than GRAPH_REPORT.md or raw grep output.
- Для таких вопросов сначала запускай `graphify query "<question>"`, если существует `graphify-out/graph.json`. Для связей используй `graphify path "<A>" "<B>"`, для точечных концептов — `graphify explain "<concept>"`. Обычно это даёт гораздо более узкий подграф, чем `GRAPH_REPORT.md` или raw grep. - Dirty graphify-out/ files are expected after hooks or incremental updates; dirty graph files are not a reason to skip graphify. Only skip graphify if the task is about stale or incorrect graph output, or the user explicitly says not to use it.
- Предпочитай `graphify query` перед raw grep, когда нужен кратчайший путь между концептами, мост между комьюнити или трассировка того, как один подсистемный блок достигает другого. - If graphify-out/wiki/index.md exists, use it for broad navigation instead of raw source browsing.
- Для отладки багов начинай с симптома и спрашивай у graphify путь зависимости, bridge nodes или модули, которые могут объяснить неожиданное поведение. - Read graphify-out/GRAPH_REPORT.md only for broad architecture review or when query/path/explain do not surface enough context.
- Если `graphify` возвращает только общую структуру, переходи к `serena` за символ-уровневыми фактами и затем повторяй `graphify` с более узким вопросом, где названы конкретные файлы, модули или сервисы. - After modifying code, run `graphify update .` to keep the graph current (AST-only, no API cost).
- Dirty `graphify-out/` после хуков или инкрементальных обновлений считаются нормой; грязные файлы графа не повод пропускать `graphify`. Пропускать его можно только если задача именно про устаревший или некорректный граф, либо если пользователь прямо попросил не использовать его.
- В новом `worktree` сначала заново создай локальный граф командой `graphify extract .`.
- После первой сборки в этом `worktree` обновляй граф командой `graphify update .`.
- Если существует `graphify-out/wiki/index.md`, используй его для широкого обзора вместо ручного просмотра исходников.
- `graphify-out/GRAPH_REPORT.md` читай только для широкого архитектурного обзора или когда `query/path/explain` не дают достаточно контекста.
- После изменений в коде запускай `graphify update .`, чтобы держать граф актуальным (только AST, без затрат на LLM).

View File

@ -125,8 +125,6 @@ docs/
| `npm run format` | Prettier для всех `*.{ts,tsx}` | | `npm run format` | Prettier для всех `*.{ts,tsx}` |
| `npm run codegen -w apps/frontend` | `openapi-typescript` из запущенного локального Swagger → `src/api/types.ts` | | `npm run codegen -w apps/frontend` | `openapi-typescript` из запущенного локального Swagger → `src/api/types.ts` |
`graphify-out/` — локальный артефакт знания, он не хранится в git. В новом `worktree` сначала собери его заново: `graphify extract .`; дальше обновляй инкрементально: `graphify update .`. Для вопросов по коду используй `graphify query "..."`.
Docusaurus (`apps/docs`) — опубликованная документация для пользователей. Storybook (`packages/design-system`) — инженерный workbench для разработки компонентов. Docusaurus (`apps/docs`) — опубликованная документация для пользователей. Storybook (`packages/design-system`) — инженерный workbench для разработки компонентов.
Интеграционные тесты с MOEX: `npm run test:integration -w apps/backend`. Интеграционные тесты с MOEX: `npm run test:integration -w apps/backend`.

View File

@ -1,43 +1,27 @@
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from '@nestjs/testing';
import { ConfigService } from '@nestjs/config'; import { ConfigModule } from '@nestjs/config';
import { HealthService } from './health.service'; import { HealthService } from './health.service';
import { PrismaService } from '../prisma/prisma.service'; import { PrismaService } from '../prisma/prisma.service';
import configuration from '../../config/configuration';
describe('HealthService', () => { describe('HealthService', () => {
let service: HealthService; let service: HealthService;
const prisma = { $queryRaw: vi.fn() } as any; const prisma = { $queryRaw: vi.fn() } as any;
const config = {
get: vi.fn((key: string, fallback?: unknown) => {
const values: Record<string, unknown> = {
'app.moex.baseUrl': 'https://iss.moex.test/iss',
'app.tbank.token': 'token-1',
};
return values[key] ?? fallback;
}),
} as unknown as ConfigService;
const fetchMock = vi.fn();
beforeEach(async () => { beforeEach(async () => {
vi.clearAllMocks(); vi.clearAllMocks();
vi.stubGlobal('fetch', fetchMock);
fetchMock.mockResolvedValue({ ok: true, status: 200 });
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
imports: [ConfigModule.forRoot({ load: [configuration], isGlobal: true })],
providers: [ providers: [
HealthService, HealthService,
{ provide: PrismaService, useValue: prisma }, { provide: PrismaService, useValue: prisma },
{ provide: ConfigService, useValue: config },
], ],
}).compile(); }).compile();
service = module.get<HealthService>(HealthService); service = module.get<HealthService>(HealthService);
}); });
afterEach(() => {
vi.unstubAllGlobals();
});
it('returns ok when all dependencies are healthy', async () => { it('returns ok when all dependencies are healthy', async () => {
prisma.$queryRaw.mockResolvedValue([{ 1: 1 }]); prisma.$queryRaw.mockResolvedValue([{ 1: 1 }]);

View File

@ -1,87 +0,0 @@
# Architecture Quality Backlog Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** publish a canonical architecture backlog in `docs/` and reconcile roadmap/audit statuses without changing runtime code.
**Architecture:** this feature is a documentation workflow. We inventory the already completed architecture work, collapse stale and duplicated backlog entries, and publish one normalized backlog that future features can implement independently.
**Tech Stack:** Markdown docs in `docs/`, Docusaurus-published architecture pages in `apps/docs/docs/`, repository search and patch tooling.
---
### Task 1: Promote canonical feature docs
**Files:**
- Create: `docs/features/architecture-quality-backlog/spec.md`
- Create: `docs/features/architecture-quality-backlog/plan.md`
- Create: `docs/features/architecture-quality-backlog/tasks.md`
- [x] **Step 1: Move the worktree draft into canonical docs**
Create the feature directory in the main workspace and copy the prepared `spec/plan/tasks` structure.
- [x] **Step 2: Rewrite the feature around the actual output**
Describe the feature as completed docs-only normalization work rather than an unexecuted draft.
- [x] **Step 3: Publish the normalized backlog**
Keep one ordered backlog with explicit risks, dependencies, and future feature boundaries.
### Task 2: Reconcile related source-of-truth docs
**Files:**
- Modify: `docs/features/frontend-debt-audit/spec.md`
- Modify: `docs/features/backend-architecture-refactor/spec.md`
- [x] **Step 1: Remove stale already-closed debt notes**
Reclassify items already covered by `api-envelope-contract` and `backend-architecture-refactor`.
- [x] **Step 2: Point remaining open debt at the canonical backlog**
Avoid competing backlog lists by linking residual items to `architecture-quality-backlog`.
- [x] **Step 3: Synchronize status wording**
Update `backend-architecture-refactor` from draft to completed state to match its finished tasks.
### Task 3: Publish roadmap changes
**Files:**
- Modify: `docs/roadmap.md`
- [x] **Step 1: Mark completed architecture refactor work as done**
`Backend Architecture Refactor` must no longer appear as open if the feature tasks and verification log are complete.
- [x] **Step 2: Add the new completed docs-only feature**
Record `architecture-quality-backlog` in the completed work history as the canonical backlog publication step.
- [x] **Step 3: Replace the loose candidate list with normalized tracks**
Publish the same ordered backlog from the feature spec so roadmap and feature docs match.
### Task 4: Final consistency pass
**Files:**
- Read: `docs/features/architecture-quality-backlog/spec.md`
- Read: `docs/features/architecture-quality-backlog/plan.md`
- Read: `docs/features/architecture-quality-backlog/tasks.md`
- Read: `docs/features/frontend-debt-audit/spec.md`
- Read: `docs/features/backend-architecture-refactor/spec.md`
- Read: `docs/roadmap.md`
- [x] **Step 1: Confirm docs-only scope**
Only documentation files should change.
- [x] **Step 2: Confirm consistent backlog ordering**
The five normalized directions must appear with the same meaning everywhere they are referenced.
- [x] **Step 3: Confirm no duplicate stale backlog remains**
Historical docs can keep audit context, but they should no longer compete with the canonical backlog.

View File

@ -1,169 +0,0 @@
# Architecture Quality Backlog
Дата: 2026-06-26
Статус: выполнено
## Контекст
После нескольких завершённых волн cleanup и refactor в проекте остались два типа проблем:
- часть архитектурного долга всё ещё открыта, но описана фрагментами в разных backlog-документах;
- часть документации отстаёт от фактического состояния кода и уже закрытых feature-итераций.
До этой фичи backlog был распределён между `frontend-debt-audit`, `backend-architecture-refactor`,
`roadmap` и отдельным worktree-драфтом `architecture-quality-backlog`. Из-за этого было неочевидно,
что уже закрыто, что требует только синхронизации docs, а что должно стать следующими отдельными
refactor-фичами.
Эта фича не меняет runtime-поведение. Она фиксирует canonical architecture backlog и приводит
source-of-truth документы к одному состоянию.
## Цель
Собрать и опубликовать единый архитектурный backlog проекта, синхронизировать roadmap и связанные
audit/refactor docs и определить нормализованный порядок следующих follow-up фич без изменения кода.
## Требования
### 1. Инвентаризация текущего состояния
Нужно сверить:
- `docs/features/frontend-debt-audit/spec.md`;
- `docs/features/backend-architecture-refactor/spec.md` и `tasks.md`;
- `docs/roadmap.md`;
- опубликованные архитектурные документы в `apps/docs/docs/frontend/` и `apps/docs/docs/backend/`.
### 2. Удаление устаревших и уже закрытых пунктов
Backlog не должен повторно открывать задачи, которые уже закрыты отдельными feature-итерациями.
Минимум нужно убрать или переотнести:
- `API envelope double-wrapping` после `api-envelope-contract`;
- первичное production config/error masking hardening после `backend-architecture-refactor`;
- устаревшие статусы, где roadmap или spec остались в промежуточном состоянии.
### 3. Публикация нормализованного backlog
Оставшийся architecture backlog должен быть опубликован как пять независимых направлений, чтобы каждое
можно было позже оформить отдельной feature-spec:
1. **T-Bank Data Isolation and Ownership Boundaries**
2. **Backend Runtime and Auth Hardening**
3. **Local T-Bank Read Path**
4. **Session Model for Multiple Surfaces**
5. **Contract, Type-Safety, and Frontend Delivery Hardening**
### 4. Явные границы каждого backlog item
Для каждого направления должны быть описаны:
- цель;
- риск;
- зависимости;
- ожидаемая граница follow-up фичи;
- причина, почему item не закрывается в рамках текущей docs-only фичи.
### 5. Никаких runtime-изменений
Фича не должна:
- менять пользовательские сценарии;
- менять API или модель данных;
- править `apps/frontend/src/**` или `apps/backend/src/**`;
- превращать backlog-публикацию в непосредственный refactor runtime-кода.
## Нормализованный backlog
### 1. T-Bank Data Isolation and Ownership Boundaries
**Цель:** изолировать T-Bank accounts, positions, operations и derived views по пользователю и закрепить
ownership boundary до дальнейших data-flow изменений.
**Риск:** без этого остаётся риск multi-tenant data leak и неявной shared ownership-модели.
**Зависимости:** текущая T-Bank integration, Prisma data model, auth identity boundary.
**Граница follow-up фичи:** backend/domain feature про ownership model, query filtering и migration-safe
изоляцию данных.
**Почему не закрыто сейчас:** требует runtime-изменений, data model decisions и отдельной спецификации.
### 2. Backend Runtime and Auth Hardening
**Цель:** закрыть оставшиеся production-grade security/runtime policy вопросы после первичной refactor
волны.
**Риск:** частично остаются недооформленные rate limiting, auth policy и surface-level security guards.
**Зависимости:** результаты `backend-architecture-refactor`, текущая auth/session модель,
deployment/runtime env policy.
**Граница follow-up фичи:** backend/security feature без смешивания с multi-tenancy или session redesign.
**Почему не закрыто сейчас:** требует отдельной threat-model driven runtime работы, а не docs sync.
### 3. Local T-Bank Read Path
**Цель:** перевести чтение операций и истории на локальную persisted модель вместо прямого read-through в
T-Bank там, где это необходимо для стабильности и контроля данных.
**Риск:** текущая зависимость от external read path усложняет устойчивость, latency control и auditability.
**Зависимости:** ownership boundary для T-Bank данных, sync model, persisted operation schema.
**Граница follow-up фичи:** backend data-flow feature про local persistence, sync and read model.
**Почему не закрыто сейчас:** требует runtime data-flow changes и, вероятно, schema/runtime planning.
### 4. Session Model for Multiple Surfaces
**Цель:** определить явную session model для web/PWA/extension-like surfaces, включая device-level
sessions, rotation и reuse detection.
**Риск:** текущая модель остаётся слишком узкой для нескольких клиентских поверхностей и finer-grained
session control.
**Зависимости:** auth boundary, refresh-token policy, future surface strategy.
**Граница follow-up фичи:** auth/session feature без смешивания с общим backend security backlog.
**Почему не закрыто сейчас:** требует product/security decisions и отдельного session contract.
### 5. Contract, Type-Safety, and Frontend Delivery Hardening
**Цель:** сократить остаточную type unsafety, стабилизировать frontend API/query boundaries и усилить
quality/performance gates.
**Риск:** остаются `as any`, слабые boundary-contracts, нет полного покрытия performance/testing gates.
**Зависимости:** существующий API envelope contract, generated types, frontend routing/query architecture.
**Граница follow-up фичи:** набор узких quality-hardening features, начиная с type-safety и frontend
delivery constraints, без смешивания с backend domain refactor.
**Почему не закрыто сейчас:** это уже не backlog sync, а серия отдельных implementation changes.
## Ограничения
- Только `docs/` и согласование опубликованных архитектурных описаний с backlog.
- Не дублировать один и тот же долг в нескольких независимых backlog-списках.
- Не создавать новый epic только ради этой docs-only нормализации.
## Критерии приемки
- В основном workspace существует canonical feature `docs/features/architecture-quality-backlog/`.
- `docs/roadmap.md` отражает эту фичу и использует тот же нормализованный порядок backlog-направлений.
- `frontend-debt-audit` и `backend-architecture-refactor` больше не противоречат текущему состоянию
закрытых работ.
- Для каждого backlog item указаны цель, риск, зависимости, follow-up boundary и причина defer.
- В рамках фичи не изменены runtime-файлы `apps/frontend/src/**` и `apps/backend/src/**`.
## Источники
- `docs/features/frontend-debt-audit/spec.md`
- `docs/features/backend-architecture-refactor/spec.md`
- `docs/features/backend-architecture-refactor/tasks.md`
- `docs/roadmap.md`
- `apps/docs/docs/frontend/overview.md`
- `apps/docs/docs/backend/modules.md`

View File

@ -1,9 +0,0 @@
# Architecture Quality Backlog — tasks
Статус: completed
- [x] Инвентаризировать текущие frontend/backend architecture backlog документы и completed refactor waves.
- [x] Перенести `architecture-quality-backlog` из отдельного worktree в canonical `docs/features/`.
- [x] Убрать или переотнести stale backlog items, уже закрытые отдельными feature-итерациями.
- [x] Опубликовать единый нормализованный backlog в feature docs и `docs/roadmap.md`.
- [x] Выполнить финальную consistency-проверку и подтвердить docs-only scope.

View File

@ -1,7 +1,7 @@
# Backend Architecture Refactor # Backend Architecture Refactor
Дата: 2026-06-25 Дата: 2026-06-25
Статус: выполнено Статус: draft
## Контекст ## Контекст

View File

@ -120,26 +120,21 @@ tooling и часть архитектурных cleanup-задач. После
- `frontend-shared-boundary-cleanup` — сужение shared/public API - `frontend-shared-boundary-cleanup` — сужение shared/public API
- `frontend-test-hygiene` — минимизация test helpers - `frontend-test-hygiene` — минимизация test helpers
**Открыто и перенесено в canonical architecture backlog:** **Открыто, не покрыто ни одной фичей (нуждается в новых задачах):**
| # | Приоритет | Debt item | Риск | | # | Приоритет | Debt item | Риск |
|---|-----------|-----------|------| |---|-----------|-----------|------|
| 1 | P0/P1 | T-Bank data isolation by user | multi-tenant data leak | | 1 | P0/P1 | T-Bank data isolation by user | multi-tenant data leak |
| 2 | P1 | Local T-Bank history read-path | история читается напрямую из T-Bank | | 2 | P1 | API envelope double-wrapping | runtime-ответы не соответствуют Swagger |
| 3 | P1/P2 | Session model for multiple surfaces | single-token, нет device-level сессий | | 3 | P1 | Production config & auth security hardening | дефолтные секреты, CORS, error leaking |
| 4 | P2 | Reduce type unsafety (`as any`, `no-explicit-any`) | остаточная type unsafety в contract/runtime boundaries | | 4 | P1 | Local T-Bank history read-path | история читается напрямую из T-Bank |
| 5 | P2 | Expand testing strategy (coverage thresholds, E2E) | нет coverage gates, нет Playwright smoke | | 5 | P1/P2 | Session model for multiple surfaces | single-token, нет device-level сессий |
| 6 | P3 | Route-level lazy loading + performance budgets | eager delivery без явных budgets | | 6 | P2 | Reduce type unsafety (`as any`, `no-explicit-any`) | 95+ в коде, в основном gRPC/T-Bank/screener |
| 7 | P2 | Expand testing strategy (coverage thresholds, E2E) | нет coverage gates, нет Playwright |
Эти направления больше не должны жить как независимый frontend-only backlog. Их canonical форма и | 8 | P3 | Route-level lazy loading + performance budgets | 471 KB JS bundle eager, нет budgets |
порядок ведутся в `docs/features/architecture-quality-backlog/spec.md` и `docs/roadmap.md`.
**Устарело и подлежит пересмотру:** **Устарело и подлежит пересмотру:**
- P1 `API envelope double-wrapping`**resolved**: закрыто фичей `api-envelope-contract`
- P1 `Production config & auth security hardening` — первичный scope закрыт в
`backend-architecture-refactor`; оставшийся policy/runtime backlog перенесён в
`architecture-quality-backlog`
- P2 «Eliminate dual frontend API type system» — **resolved**: codegen unification выполнена, `responses.ts` удалён - P2 «Eliminate dual frontend API type system» — **resolved**: codegen unification выполнена, `responses.ts` удалён
- P2 «Decompose large modules» — частично выполнена через shared-boundary-cleanup, backend-декомпозиция вне scope audit-фичи - P2 «Decompose large modules» — частично выполнена через shared-boundary-cleanup, backend-декомпозиция вне scope audit-фичи
- P3 «Prepare financial types for future ledger» — перенесена в deferred, не актуальна без инициативы ledger - P3 «Prepare financial types for future ledger» — перенесена в deferred, не актуальна без инициативы ledger

View File

@ -31,7 +31,7 @@ Roadmap отражает порядок продуктовой работы, н
- [x] [Backend Architecture Improvements](features/backend-architecture-improvements/spec.md) — envelope - [x] [Backend Architecture Improvements](features/backend-architecture-improvements/spec.md) — envelope
DTO, screener TTL, domain exceptions, health checks, middleware DI, MoexClient split. DTO, screener TTL, domain exceptions, health checks, middleware DI, MoexClient split.
- [x] [Backend Architecture Refactor](features/backend-architecture-refactor/spec.md) — refactor-only - [ ] [Backend Architecture Refactor](features/backend-architecture-refactor/spec.md) — refactor-only
итерация: error masking, production config hardening, DTO validation, typed T-Bank boundary, cache итерация: error masking, production config hardening, DTO validation, typed T-Bank boundary, cache
metadata, backend docs sync. metadata, backend docs sync.
@ -93,8 +93,6 @@ Roadmap отражает порядок продуктовой работы, н
- [x] [MVP](features/moex-vibe/spec.md) — поиск, карточки акций/облигаций, графики, дивиденды. - [x] [MVP](features/moex-vibe/spec.md) — поиск, карточки акций/облигаций, графики, дивиденды.
- [x] [Frontend debt audit and backlog](features/frontend-debt-audit/spec.md) — audit frontend-техдолга, - [x] [Frontend debt audit and backlog](features/frontend-debt-audit/spec.md) — audit frontend-техдолга,
разделение open items на 4 follow-up фичи, синхронизация inbox/roadmap разделение open items на 4 follow-up фичи, синхронизация inbox/roadmap
- [x] [Architecture quality backlog](features/architecture-quality-backlog/spec.md) — docs-only
нормализация architecture backlog, синхронизация roadmap и audit/refactor статусов
- [x] [frontend-docs-sync](features/frontend-docs-sync/spec.md) — синхронизация docs с состоянием кода - [x] [frontend-docs-sync](features/frontend-docs-sync/spec.md) — синхронизация docs с состоянием кода
- [x] [frontend-infrastructure-hardening](features/frontend-infrastructure-hardening/spec.md) — - [x] [frontend-infrastructure-hardening](features/frontend-infrastructure-hardening/spec.md) —
browser mock mode, env validation, tooling consistency, contract freshness browser mock mode, env validation, tooling consistency, contract freshness
@ -114,20 +112,16 @@ Roadmap отражает порядок продуктовой работы, н
## Кандидаты следующих фич ## Кандидаты следующих фич
Ниже опубликован canonical architecture backlog после `architecture-quality-backlog`. Старые granular
заметки folded into these tracks и не должны вестись как параллельные независимые backlog-списки.
- [x] [Миграция таблиц на дизайн-систему](features/table-migration/spec.md) — DividendsTable, - [x] [Миграция таблиц на дизайн-систему](features/table-migration/spec.md) — DividendsTable,
ScreenerTable, SharePositionTable, BondPositionTable мигрированы на `DataTable`. Legacy `shared/ui/Table` ScreenerTable, SharePositionTable, BondPositionTable мигрированы на `DataTable`. Legacy `shared/ui/Table`
и `TableSkeleton` удалены. и `TableSkeleton` удалены.
- [ ] T-Bank data isolation and ownership boundaries (P0/P1) — изоляция T-Bank данных по пользователям, - [ ] T-Bank data isolation and multi-tenancy (P0/P1) — изолировать данные T-Bank по пользователям,
ownership model и backend query boundary до следующих data-flow изменений ownership модель
- [ ] Backend runtime and auth hardening (P1) — отдельная security/runtime policy итерация: rate limiting, - [x] API envelope runtime contract (P1) — устранить double-wrapping, унифицировать envelope
auth surface hardening, explicit production rules - [ ] Auth security hardening (P1) — production-секреты, CORS allowlist, error masking, rate limiting
- [ ] Local T-Bank read-path (P1) — локальная persisted read-модель операций/истории вместо прямого - [ ] Local T-Bank read-path (P1) — чтение истории операций из локальной БД вместо прямого вызова T-Bank
read-through из T-Bank - [ ] Session model for multiple surfaces (P1/P2) — device-level сессии, rotation, reuse detection
- [ ] Session model for multiple surfaces (P1/P2) — device-level sessions, rotation, reuse detection, - [ ] Type safety hardening (P2) — включение `no-explicit-any`, устранение `as any` в gRPC/screener/tests
явный session contract для нескольких клиентских поверхностей - [ ] Testing strategy expansion (P2) — coverage thresholds, contract tests, Playwright smoke
- [ ] Contract, type-safety, and frontend delivery hardening (P2/P3) — устранение остаточного `as any`, - [ ] Frontend delivery optimization (P3) — route-level lazy loading, performance budgets
укрепление API/query boundaries, quality/performance gates и lazy-loading budgets
- [x] Broker-events — UX доработки и смешанный календарь. - [x] Broker-events — UX доработки и смешанный календарь.