docs: make project documentation self-contained
This commit is contained in:
+20
-11
@@ -1,13 +1,22 @@
|
||||
# Разработка
|
||||
# Сопровождение системы
|
||||
|
||||
Работа начинается с задачи пользователя; обязательного OpenSpec/SDD lifecycle нет.
|
||||
Проектные факты выбирайте через [AI_INDEX](../AI_INDEX.md).
|
||||
Здесь описаны локальное окружение, согласованность компонентов, проверка
|
||||
качества и поддержание проектных знаний. Материалы самостоятельны и не
|
||||
требуют открытия внутренних файлов приложений.
|
||||
|
||||
- [Engineering governance](engineering-governance.md) — выбор решения/dependency, risk-based tests, local gates, UI и опасные изменения.
|
||||
- [Context discipline](agent-token-efficiency.md) — semantic/path routing, sources, recovery и проверка эффективности.
|
||||
- [Routing eval cases](agent-context-evals.md) — реальные decision cases и counterexamples для conventions.
|
||||
- [Frontend workflow](frontend-workflow.md) / [backend workflow](backend-workflow.md) — запуск и существующие checks.
|
||||
- [HTTP contract workflow](runtime-openapi-verification.md) — Nest OpenAPI → snapshot → generated types и контрактная проверка.
|
||||
- [Дизайн-система](design-system.md) / [UI-каталог](ui-catalog.md) — theme/tokens, реальные components/stories и ограничения.
|
||||
- [Remediation registry](audit-remediation.md) — найденная запись Audit ID и historical evidence.
|
||||
- [OpenSpec](openspec-authority-and-lifecycle.md) — optional legacy workflow, только по явному запросу.
|
||||
- [Локальное окружение](local-workspace.md) — предпосылки работы, первый пользовательский сценарий и диагностика.
|
||||
- [Frontend](frontend-workflow.md) / [backend](backend-workflow.md) — ответственность приложений и границы проверки.
|
||||
- [HTTP contract](runtime-openapi-verification.md) — направление генерации OpenAPI и проверка совместимости.
|
||||
- [Дизайн-система](design-system.md) / [UI-каталог](ui-catalog.md) — визуальные роли, реальные состояния и ограничения примеров.
|
||||
- [Принципы изменений](engineering-governance.md) — связность системы, риск и доказательства результата.
|
||||
- [Ведение документации](documentation.md) — самостоятельные объяснения и их обновление вместе с системой.
|
||||
- [Контекст знаний](agent-token-efficiency.md) / [проверочные вопросы](agent-context-evals.md) — поиск ответа и обнаружение пробелов документации.
|
||||
- [OpenSpec](openspec-authority-and-lifecycle.md) — роль сохранённых требований и статус прежнего процесса.
|
||||
|
||||
## Исторические свидетельства
|
||||
|
||||
[Remediation registry](audit-remediation.md) и [Completion Evidence](completion-evidence.md)
|
||||
сохраняют статусы, исходные адреса и результаты прежних проверок.
|
||||
[Аудиты](../audits/README.md) — неизменяемые снимки своего времени. Эти материалы
|
||||
не входят в самостоятельное описание текущей системы; их внутренние ссылки
|
||||
могут требовать архивного окружения и не являются условием чтения документации.
|
||||
|
||||
@@ -1,50 +1,36 @@
|
||||
# Проверка agent context
|
||||
# Проверка полноты проектных знаний
|
||||
|
||||
Это небольшой corpus решений для настройки routing. Выполняйте cases по текущим
|
||||
AGENTS/router/conventions: сначала определите решение и необходимые источники,
|
||||
затем сравните с ожиданием. Это не unit tests, повторяющие Markdown, и не новый
|
||||
verification framework. Для проверки изменения правила нужны activating case,
|
||||
допустимое исключение и unrelated counterexample.
|
||||
Эти вопросы помогают оценить, объясняет ли документация систему без доступа
|
||||
к исходникам. Для каждого вопроса важны правильный ответ, существенное
|
||||
ограничение и отсутствие ошибочного вывода из похожего сценария.
|
||||
|
||||
## Cases
|
||||
|
||||
| Задача | Необходимый контекст / ожидаемое решение | Что не должно активироваться без новой границы |
|
||||
| Вопрос | Объяснение | Существенная граница |
|
||||
| --- | --- | --- |
|
||||
| Изменить props и layout existing finance view | Frontend UI; props остаются presentation, derived collection values — у VM | API, Prisma, architecture, tests без risk/test change |
|
||||
| Исправить только продуктовую строку/Zod message | UI section «Строки и валидация»; locale/validationMessage, mandatory review | Остальные UI sections, HTTP/structure/testing |
|
||||
| Добавить page-local фильтр без сети | Frontend architecture + UI; оставить у page, если нет independent capability | Новый shared abstraction/feature ради click; API |
|
||||
| Добавить business summary component | Architecture + UI; business meaning и existing owner определяют placement | shared только из-за reuse; widgets layer |
|
||||
| Изменить query refetch/error recovery | Frontend data + testing; cached snapshot/current generation и exact feature source | Backend data при неизменном server behavior |
|
||||
| Добавить новый HTTP response field | Backend HTTP + общий contract workflow + применимые tests; Nest → snapshot → generated TS, affected client data rules | Второй editable OpenAPI в specs; ручной generated TS |
|
||||
| Добавить account endpoint с новым RPC | Backend HTTP, architecture при новом use case, security/access, integrations, testing; TbankAccessService/TbankClient | Прямой gRPC из controller; доверие accountId без ownership |
|
||||
| Исправить только Prisma query без HTTP/auth boundary | Backend data, testing при data-risk; existing PrismaService | Весь HTTP/security guide автоматически |
|
||||
| Атомарно обновить связанные записи | Data + testing; transaction/constraint у инварианта, isolated DB proof | Generic repository; mock как доказательство реальной atomicity |
|
||||
| Изменить конкурентный refresh | Security + data + testing; ADR 009; один winner, superseded не отзывает его session | Replay-history/grace window без задачи; новый coordinator |
|
||||
| Изменить DTO validation error | HTTP + testing + exact error source; configured HTTP case проверяет pipe/filter pair | Success по одному direct controller call/Swagger snapshot |
|
||||
| Изменить gRPC retry/deadline | Integrations + testing; bounded existing client path, controlled upstream failure | Вложенный retry loop; реальная сеть/secret |
|
||||
| Добавить безопасное scalar log field | Architecture/logging; проверить allowlist и event | Весь auth guide без sensitive boundary; считать message автоматически redacted |
|
||||
| Изменить только тест | Testing соответствующего repo; source guides только по проверяемой границе | Все production conventions из-за расширения `.ts` |
|
||||
| Добавить dependency/adapter для одной задачи | Общий выбор/dependencies; existing owner/platform/library прежде нового кода | Новый interface только для hypothetical reuse |
|
||||
| Исправить опечатку в общей документации | Docs AGENTS и затронутый source | Любые frontend/backend conventions |
|
||||
| После UI начала появились mutation/schema/new files | Routing повторяется по staged/unstaged/new, новые границы читаются до решения | Продолжать по первоначальному UI-only scope |
|
||||
| Отсутствует обязательный security source / источники конфликтуют | Остановить зависимое решение, восстановить факт/уточнить задачу | Догадка из соседнего code или жёсткий лимит на число документов |
|
||||
| Кто подтверждает доступ к брокерскому счёту? | [Обзор](../architecture/system-overview.md#предметная-модель) | Сессия подтверждает пользователя, но идентификатор счёта не доказывает доступ |
|
||||
| Как меняются финансовые данные при замене token? | [Подключение](../features/tbank-connection.md#граница-финансового-кэша) | Данные прежнего поколения не становятся сохранённым снимком нового подключения |
|
||||
| Что происходит при конкурентном refresh? | [Authentication](../features/authentication.md), [ADR 009](../adr/009-concurrent-refresh-rotation-policy.md) | Один победитель; заменённый token не отзывает его сессию сам по себе |
|
||||
| Как восстанавливается интерфейс после ошибки обновления? | [UI resilience](../features/frontend-ui-resilience.md) | Фоновая ошибка отличается от первой загрузки и смены пользователя |
|
||||
| Чем будущая выплата отличается от дохода? | [События](../features/brokerage-account-upcoming-events.md), [доходы](../features/brokerage-account-income-analytics.md) | Прогноз не подтверждает личное зачисление |
|
||||
| Можно ли складывать разные валюты или заменить неизвестное нулём? | [Money](../architecture/domain-glossary.md#money) | Точность, валюта и отсутствие значения сохраняются отдельно |
|
||||
| Откуда рейтинг и доходность облигации? | [Bond detail](../features/bond-detail.md) | Рейтинг эмитента не заменяет рейтинг выпуска; рыночная доходность не равна личному результату |
|
||||
| Доказывает ли OpenAPI правильность ошибки запроса? | [HTTP API](../architecture/http-api.md#error-contract) | Равенство схем не доказывает полный HTTP-поток |
|
||||
| Что гарантирует проверка хранения данных? | [Backend](backend-workflow.md#локальная-проверка) | Проверка с подставными ответами не доказывает атомарность реальной базы |
|
||||
| Как ограничиваются обращения к внешнему сервису? | [T-Bank](../features/tbank-connection.md#конфигурация-и-ограничения) | Повторы, очередь и лимит ограничены; TLS остаётся включённым |
|
||||
| Защищает ли фильтрация логов любое сообщение? | [ADR 008](../adr/008-pino-backend-logging.md) | Секрет в свободном тексте требует отдельной проверки |
|
||||
| Есть ли восстановление пароля по письму? | [Ограничения auth](../features/authentication.md#limitations) | Пример будущего сценария не является поставленной возможностью |
|
||||
|
||||
## Что измерять
|
||||
|
||||
Для startup/working-set измерения перечислите ровно прочитанные файлы/sections,
|
||||
инструмент подсчёта и unit (символы или tokenizer). Required source нельзя
|
||||
исключать только ради хорошего числа. Число доступных файлов на диске не является
|
||||
стоимостью конкретной задачи.
|
||||
|
||||
Для реальной first-pass оценки выполните одинаковые задачи с одинаковой моделью,
|
||||
version/tools и comparable prompts: прежний context, только новые indexes,
|
||||
затем полный routing. Считайте принятие без substantive correction, iterations,
|
||||
ошибки placement/contract/security, лишние abstractions и пропущенные sources.
|
||||
Routing review и зелёные application tests сами по себе такого улучшения не доказывают.
|
||||
Полезное объяснение позволяет найти ответ, назвать ограничение и связать его
|
||||
с другими сценариями. Оцениваются неверные выводы о доступе, деньгах, полноте
|
||||
данных и источниках, а также число уточнений до правильного понимания.
|
||||
Время поиска и объём чтения имеют смысл только вместе с точностью ответа.
|
||||
|
||||
## Изменение правил
|
||||
|
||||
Если нужный source не прочитан — исправьте trigger. Если source прочитан, но
|
||||
не разрешает выбор — уточните decision/safe path/example. Если дефект
|
||||
детерминирован — используйте подходящий existing test/linter. Не добавляйте
|
||||
новый always-on paragraph для каждого отдельного случая.
|
||||
Если знание есть, но его трудно найти, уточняется навигация. Если документ
|
||||
найден, но не объясняет различие понятий или ограничение, уточняется объяснение.
|
||||
При конфликте источников сохраняется отметка о ручном решении; догадка не
|
||||
подменяет установленный факт.
|
||||
|
||||
@@ -1,62 +1,42 @@
|
||||
# Context discipline
|
||||
# Контекст знаний о системе
|
||||
|
||||
Цель — получить правила, которые меняют текущее решение, и не читать остальные
|
||||
заранее. Это процедура прямой работы по задаче, без обязательных SDD artifacts,
|
||||
ролей, approval fingerprints или подсчёта документов как delivery gate.
|
||||
Цель навигации — дать читателю знания, необходимые для конкретного вопроса,
|
||||
без предварительного чтения всей документации. Самостоятельное объяснение
|
||||
связывает понятия, сценарии и ограничения, а не воспроизводит устройство кода.
|
||||
|
||||
## Routing context
|
||||
|
||||
1. Определи требуемое поведение, тип решения и affected repos до supporting reads.
|
||||
2. Прочитай root/local AGENTS, затем CONVENTIONS и SOURCES affected code repo.
|
||||
3. Объедини сработавшие semantic, path и boundary triggers. Путь — сигнал ответственности, а не повод загружать всё по расширению `.tsx`/`.ts`.
|
||||
4. Прочитай выбранные conventions или явно указанные sections до зависимого решения. При domain/API/security вопросе открой точный source через [docs index](../AI_INDEX.md).
|
||||
5. Проследи ближайший существующий owner и подходящие код/тесты. Его поведение не заменяет canonical fact.
|
||||
6. Повтори routing при новой потребности и по финальным staged, unstaged и новым файлам. Содержимое работы важнее первоначального названия задачи.
|
||||
|
||||
Первый проход работает без diff. Auth + refresh, например, активирует API,
|
||||
security и testing вместе. Отображение query state без изменения запросов не
|
||||
добавляет transport rules. Docs-only опечатка не требует frontend/backend conventions.
|
||||
Обычно хватает нескольких тем; это наблюдение, не лимит. Обязательный source
|
||||
нельзя пропускать ради числа файлов или token budget.
|
||||
|
||||
Новая граница внутри задачи требует дочитать правила до работы. Расширение
|
||||
самой задачи сначала сообщи пользователю; уже данное разрешение не запрашивай
|
||||
повторно. Чужой concurrent diff учитывай при разграничении ownership.
|
||||
[Тематический индекс](../AI_INDEX.md) направляет к нужному предмету:
|
||||
аутентификация связана с безопасностью и сессиями, денежный показатель —
|
||||
с его происхождением и валютой, ошибка интерфейса — с восстановлением данных.
|
||||
Вопрос о внешнем виде не требует автоматически изучать хранение данных.
|
||||
При обнаружении новой существенной границы расширяется и нужный контекст.
|
||||
|
||||
## Источники и конфликты
|
||||
|
||||
Прямое указание пользователя определяет задачу. Текущий executable HTTP contract
|
||||
генерируется backend; docs описывает проектные факты/решения; conventions задают
|
||||
выбор реализации; code показывает существующие аналоги. Generic framework advice
|
||||
используется после проектных источников. Research содержит рекомендации, которые
|
||||
нужно сверить с actual code/config, а не автоматически превращать в новый контракт.
|
||||
Публичный HTTP-контракт описывается OpenAPI backend; документация объясняет
|
||||
систему, ADR сохраняют причины решений, исследования предлагают варианты.
|
||||
Существующее поведение не отменяет согласованное требование, а рекомендация
|
||||
из исследования не становится принятым решением автоматически.
|
||||
|
||||
Если задача намеренно меняет контракт, обновляй его source и зависимые материалы
|
||||
согласованно. Missing input, противоречие security/data правил или неоднозначный
|
||||
контракт блокируют только зависимое решение до установления фактов/уточнения.
|
||||
История чата, случайный аналог и предполагаемый путь не заменяют источник.
|
||||
При расхождении возможны устаревшее объяснение, дефект реализации или
|
||||
незавершённое изменение. Неустановленный смысл, особенно в безопасности,
|
||||
данных и публичном контракте, явно отмечается для ручного решения.
|
||||
Карта ответственности за знания — [ведение документации](documentation.md).
|
||||
|
||||
## Recovery и handoff
|
||||
|
||||
Для продолжения достаточно текущей задачи, сделанных изменений, remaining work,
|
||||
точных checks/results и blockers. Не создавай параллельную копию требований,
|
||||
Design, state registry или обязательный handoff-файл.
|
||||
|
||||
В новом контексте восстанови необходимые sources; в том же переиспользуй уже
|
||||
прочитанные неизменившиеся inputs. Supporting reads добавляй по возникшему вопросу.
|
||||
Git status/diff показывают staged и unstaged; новые файлы учитывай отдельно.
|
||||
Relevant ignored/workspace-owned inputs (например `.env`, root AGENTS) не
|
||||
теряются только потому, что Git их не показывает. Секреты в evidence не печатай.
|
||||
Продолжение работы опирается на ожидаемый результат, выполненные изменения,
|
||||
оставшиеся вопросы, результаты проверок и ограничения. Дублирование требований
|
||||
в нескольких независимых пересказах создаёт риск расхождения. Исторические
|
||||
проверки сохраняют своё значение только для того состояния системы, в котором
|
||||
они выполнялись; секреты не являются допустимым содержимым свидетельств.
|
||||
|
||||
## Проверка эффективности
|
||||
|
||||
Используй [набор routing cases](agent-context-evals.md) для настройки новых правил.
|
||||
Проверяй activating case, safe exception и unrelated counterexample по реальным
|
||||
инструкциям. Source links и gates дополняют эту проверку, но не доказывают first-pass quality.
|
||||
|
||||
Сравнивай startup context и реально выбранные sections, фиксируя способ измерения.
|
||||
Не объявляй меньшее число файлов или зелёный application test улучшением качества
|
||||
агента. Для first-pass acceptance нужны одинаковые реальные задачи/модель/tools,
|
||||
наблюдённые ошибки ownership/contract/security и число исправлений.
|
||||
Добавляй convention по повторяющейся decision error; уточняй trigger при missed
|
||||
source; deterministic regression отдавай существующему test/linter, если он подходит.
|
||||
[Проверочные вопросы](agent-context-evals.md) показывают, можно ли получить
|
||||
правильную модель системы и отличить близкие понятия. Качество оценивается по
|
||||
верности ответа, найденным ограничениям и необходимости дополнительных уточнений.
|
||||
Число документов, их краткость или успешная проверка Markdown сами по себе
|
||||
не доказывают полезность знания. Сравнение результатов требует одинаковых
|
||||
вопросов и сопоставимых условий.
|
||||
|
||||
@@ -1,34 +1,31 @@
|
||||
# Рабочий процесс backend
|
||||
# Backend: ответственность и проверка
|
||||
|
||||
## Предварительные условия
|
||||
|
||||
Backend требует Node 22. Создайте `backend/.env` на основе
|
||||
`backend/.env.example` и замените placeholder-значения `JWT_SECRET` и
|
||||
`TOKEN_ENCRYPTION_KEY`; token T-Bank в этот файл не записывается.
|
||||
Backend обслуживает публичный HTTP API, локальные сессии, хранение данных
|
||||
и интеграции с внешними источниками. Локальная поставка использует Node 22
|
||||
и SQLite. Окружению нужны адрес frontend, адрес базы, секрет подписи сессий
|
||||
и отдельный ключ шифрования подключения. T-Bank token вводится пользователем
|
||||
через настройки и не является общим секретом окружения.
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
cp .env.example .env
|
||||
npm ci
|
||||
```
|
||||
Назначение параметров, согласование адресов и сохранение данных описаны в
|
||||
[локальном окружении](local-workspace.md).
|
||||
|
||||
## Локальная проверка
|
||||
|
||||
Canonical gate не изменяет versioned-файлы:
|
||||
Проверка backend объединяет статический анализ, проверку типов приложения
|
||||
и тестов, автоматические сценарии и сборку. Она не изменяет исходные материалы;
|
||||
автоматическое исправление форматирования не считается доказательством проверки.
|
||||
Диагностика покрытия доступна отдельно, общего числового порога для backend нет.
|
||||
|
||||
```bash
|
||||
npm run verify
|
||||
```
|
||||
[Сравнение OpenAPI](runtime-openapi-verification.md) проверяет соответствие
|
||||
публичного контракта ожиданиям frontend. Валидация запросов, cookie, доступ
|
||||
и ошибки требуют полного HTTP-потока; целостность и конкурентные изменения
|
||||
данных — проверки с изолированной реальной базой.
|
||||
|
||||
Он последовательно запускает lint, application/test TypeScript, Jest и build. `npm run lint:fix` — явная
|
||||
записывающая команда, а `npm run test:cov` — отдельная диагностика без общего
|
||||
числового threshold. Runtime OpenAPI сверяется с frontend snapshot из workspace:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
npm run test:openapi-contract
|
||||
```
|
||||
|
||||
`npm run test:e2e` временно не является passing gate: Prisma schema engine
|
||||
останавливает migration до Jest. Точная диагностика и trigger пересмотра
|
||||
зафиксированы в [audit remediation registry](audit-remediation.md).
|
||||
**Известное ограничение:** движок Prisma 7.9.1 при применении миграций к новой
|
||||
SQLite-базе возвращает `Schema engine error` до запуска сквозных тестов.
|
||||
Это воспроизведено и при проверке локального окружения 12 сентября 2026 года.
|
||||
Успех остальных проверок не подтверждает прохождение этой границы. Условие
|
||||
пересмотра — стабильная версия с тремя последовательными успешными применениями
|
||||
миграций на новых базах под Node 22.
|
||||
|
||||
+53
-104
@@ -1,135 +1,84 @@
|
||||
# Дизайн-система WealthLedger
|
||||
|
||||
Общий фундамент находится в
|
||||
[`frontend/src/shared/theme`](../../frontend/src/shared/theme/index.ts).
|
||||
Его public API экспортирует `theme`, `cssVariablesResolver`, `colorRoles`, `designTokens` и
|
||||
подключает базовые CSS. App владеет MantineProvider; Storybook подключает свой
|
||||
изолированный provider к тому же API. Тема и значения не копируются в preview.
|
||||
Оба runtime используют светлую схему; dark theme не заявлена как поддерживаемая.
|
||||
Приложение и UI-каталог используют одну визуальную основу: цветовые роли,
|
||||
типографику, интервалы, радиусы, тени и адаптивные размеры. Общая тема основана
|
||||
на Mantine; её значения не дублируются отдельно в каталоге.
|
||||
Поддерживается светлая схема, тёмная тема не заявлена.
|
||||
|
||||
## Тема и токены
|
||||
|
||||
[`tokens.json`](../../frontend/src/shared/theme/tokens.json) — единственный
|
||||
редактируемый источник опубликованных токенов WealthLedger. Он содержит восемь
|
||||
палитр по десять оттенков: blue, gray, dark, red, green, yellow, grape и orange;
|
||||
базовые white/black, оттенки по умолчанию, семантические роли с описаниями,
|
||||
типографику, интервалы, радиусы, тени и breakpoints. Существующие значения
|
||||
приняты из темы приложения и Mantine 9.5.1; теперь ими владеет JSON. Default
|
||||
radius остаётся md, font family заголовков совпадает с общей.
|
||||
Опубликованная система включает восемь палитр по десять оттенков: blue, gray,
|
||||
dark, red, green, yellow, grape и orange; базовые white/black, оттенки
|
||||
по умолчанию и семантические роли. Общая гарнитура применяется и к заголовкам,
|
||||
стандартный радиус — средний. Настройки являются доверенной локальной частью
|
||||
приложения; загрузка внешних или пользовательских токенов не предусмотрена.
|
||||
|
||||
[`theme.ts`](../../frontend/src/shared/theme/theme.ts) напрямую адаптирует JSON
|
||||
в Mantine. Файл — доверенная конфигурация репозитория; приложение не загружает
|
||||
внешние или пользовательские токены и не проверяет JSON runtime-схемой.
|
||||
Размеры px преобразуются native `rem`, сохраняя `--mantine-scale`, тени собираются
|
||||
из слоёв с `rgba`, а breakpoints остаются em без масштабирования. Неопубликованные
|
||||
палитры и настройки поведения компонентов остаются defaults Mantine.
|
||||
Небольшой [`theme.test.ts`](../../frontend/src/shared/theme/theme.test.ts)
|
||||
проверяет преобразования адаптера; корректность изменений локального JSON
|
||||
проверяется при review, сборке и проверке внешнего вида.
|
||||
|
||||
Используйте props Mantine (`gap="md"`, `p="xl"`, `radius="md"`, `shadow="xs"`)
|
||||
или `--mantine-spacing-*`, `--mantine-radius-*` и другие native CSS variables.
|
||||
[Foundations](http://localhost:6006/?path=/story/design-system-foundations--colors)
|
||||
читает эффективную тему и описания из JSON, показывает фактические значения
|
||||
и образцы. Обновление Mantine не заменяет принятые шкалы автоматически и требует
|
||||
повторной проверки адаптера и внешнего вида приложения.
|
||||
|
||||
`colorRoles` связывает смысл и native Mantine reference; resolver создаёт
|
||||
`--wl-color-<role>`, ссылающийся на Mantine variable, без повторного hex-значения.
|
||||
|
||||
| Role | Native reference | Применение |
|
||||
| Роль | Цветовая основа | Применение |
|
||||
| --- | --- | --- |
|
||||
| canvas | gray.2 | Фон приложения |
|
||||
| surface | white | Paper и формы в светлой схеме |
|
||||
| surface | white | Поверхности и формы |
|
||||
| subtle | gray.0 | Приглушённая поверхность |
|
||||
| text | dark.7 | Основной текст страницы |
|
||||
| muted | gray.6 | Вторичный текст (dimmed светлой схемы) |
|
||||
| text | dark.7 | Основной текст |
|
||||
| muted | gray.6 | Вторичный текст |
|
||||
| border | gray.3 | Граница поверхности |
|
||||
| primary | blue filled | Основное действие и активная навигация |
|
||||
| info | blue.6 | Информация |
|
||||
| positive | green.6 | Положительный результат с текстом/знаком |
|
||||
| negative | red.6 | Ошибка или отрицательный результат с текстом/знаком |
|
||||
| warning | yellow.6 | Предупреждение, не мелкий текст на белом |
|
||||
| positive | green.6 | Положительный результат с текстом или знаком |
|
||||
| negative | red.6 | Ошибка или отрицательный результат с текстом или знаком |
|
||||
| warning | yellow.6 | Предупреждение; не мелкий текст на белом |
|
||||
|
||||
Базовые CSS используют canvas/text aliases. Остальные роли доступны для
|
||||
постепенного использования; существующие локальные Mantine references не
|
||||
переписаны массово. Цвет не заменяет подпись статуса. Палитра не гарантирует
|
||||
доступный контраст произвольных сочетаний: для текста и фона проверяйте контекст.
|
||||
Grape и orange используются Product; предметные значения задают их FSD-владельцы.
|
||||
Цвет не заменяет подпись или знак. Палитра не гарантирует доступный контраст
|
||||
произвольного сочетания текста и фона. Дополнительные grape/orange и отдельные
|
||||
оформления карточек сохраняют предметный смысл соответствующего экрана;
|
||||
они не образуют универсальную финансовую классификацию всей системы.
|
||||
|
||||
Особые card gradients/shadows, размеры страницы и финансовые цвета CSS остаются
|
||||
у своих FSD-владельцев. Это сохранение существующего UI, а не завершённый редизайн
|
||||
или миграция всех literals в tokens. Новую общую шкалу стоит вводить только при
|
||||
реальном повторном использовании, если native Mantine scale не подходит.
|
||||
Общие шкалы основаны на принятых значениях приложения и Mantine 9.5.1.
|
||||
Обновление библиотеки не заменяет их автоматически. Масштабируемые размеры,
|
||||
тени и адаптивные границы требуют сохранения единиц и визуальной проверки.
|
||||
Отдельные градиенты, тени и размеры экранов остаются локальными визуальными
|
||||
решениями; переход всех существующих значений в общую шкалу не завершён.
|
||||
|
||||
## Переносимый JSON
|
||||
|
||||
Файл использует собственный формат WealthLedger `formatVersion: 1`, без runtime
|
||||
imports, CSS variables или исполняемого кода. Это контракт данных, а не заявление
|
||||
о совместимости с DTCG или importer конкретной системы.
|
||||
Опубликованные токены представлены в собственном формате WealthLedger,
|
||||
версия 1. Это данные без исполняемого кода и зависимостей от runtime приложения.
|
||||
Совместимость с DTCG или импортом конкретного инструмента не заявлена.
|
||||
|
||||
| Данные | Представление |
|
||||
| --- | --- |
|
||||
| Цвета | Hex; palette — массив оттенков 0–9; base — именованные white/black. |
|
||||
| Семантическая роль | `color`, `shade`, `description`; ссылка на palette или base. Для palette `shade: null` означает `primaryShade.light`, для base оттенок не нужен. |
|
||||
| Типографика | CSS font stacks; размеры и headings в px, веса числовые, line heights без единиц. |
|
||||
| Интервалы и радиусы | Именованные `values` xs–xl с `unit: "px"`; `radius.default` выбирает имя шкалы. |
|
||||
| Тени | Упорядоченные слои: offsetX/offsetY/blur/spread в px, ссылка `color` на base и opacity 0–1. |
|
||||
| Breakpoints | Именованные `values` xs–xl с `unit: "em"`, не зависят от масштаба UI. |
|
||||
| Цвета | Hex, палитры оттенков 0–9 и именованные базовые цвета |
|
||||
| Семантические роли | Ссылка на цвет и оттенок, описание; отсутствие оттенка палитры означает основной оттенок светлой схемы |
|
||||
| Типографика | Наборы шрифтов, размеры в px, числовые веса и безразмерная высота строки |
|
||||
| Интервалы и радиусы | Именованные шкалы xs–xl в px и выбранный радиус по умолчанию |
|
||||
| Тени | Упорядоченные слои: смещения, размытие и растяжение в px, базовый цвет и непрозрачность |
|
||||
| Адаптивные границы | Именованные размеры xs–xl в em, независимые от масштаба интерфейса |
|
||||
|
||||
Не используйте для палитр специальные имена Mantine `dimmed` и `bright`;
|
||||
`white` и `black` принадлежат base colors. Задавайте вес шрифта в диапазоне
|
||||
CSS 1–1000. Это правила редактирования формата, а не runtime-проверки.
|
||||
|
||||
Внешний потребитель читает raw JSON напрямую. Например, из workspace root,
|
||||
без Node, React или Mantine:
|
||||
|
||||
```python
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
tokens = json.loads(Path("frontend/src/shared/theme/tokens.json").read_text())
|
||||
assert tokens["formatVersion"] == 1
|
||||
colors = tokens["color"]
|
||||
role = colors["roles"]["primary"]
|
||||
shade = role["shade"]
|
||||
if shade is None:
|
||||
shade = colors["primaryShade"]["light"]
|
||||
primary_hex = colors["palettes"][role["color"]][shade]
|
||||
```
|
||||
|
||||
`shared/theme/index.ts` предназначен для frontend: он подключает CSS и Mantine
|
||||
runtime. При интеграции с другой системой сопоставьте единицы, font stacks,
|
||||
слои теней и semantic references с её форматом; парсер JSON сам этого не делает.
|
||||
Несовместимое изменение требует новой версии контракта. Внешняя интеграция,
|
||||
Перенос в другую систему требует сопоставления единиц, шрифтов, слоёв теней
|
||||
и семантических ссылок. Само чтение JSON не обеспечивает такой совместимости.
|
||||
Несовместимое изменение формата требует новой версии; внешняя интеграция,
|
||||
генератор артефактов и публикация пакета пока не реализованы.
|
||||
|
||||
## Общие компоненты
|
||||
|
||||
Public API — [`shared/ui`](../../frontend/src/shared/ui/index.ts). Минимальный
|
||||
каталог включает две существующие реализации, реально используемые приложением:
|
||||
|
||||
| Компонент | Контракт и правила |
|
||||
| Представление | Поведение и ограничения |
|
||||
| --- | --- |
|
||||
| StateView | Empty/error с title, text, необязательным action; error получает role alert. Кнопке нужен доступный текст; не использовать для initial loading. |
|
||||
| LoadingSkeleton | Общая status/busy-область с доступной label; caller задаёт только декоративные shapes без фокуса. Структура skeleton принадлежит section/page. |
|
||||
| Пустой результат или ошибка | Заголовок, пояснение и необязательное действие; ошибка объявляется вспомогательным технологиям, кнопка имеет доступное название |
|
||||
| Загрузка | Доступная область состояния занятости с пояснением и декоративными фигурами без фокуса; структура отражает ожидаемый экран |
|
||||
| Действия | Основной, вторичный и вспомогательный варианты; состояния выполнения и недоступности |
|
||||
|
||||
Они не импортируют API, auth, счета или позиции. Не создаются wrappers над всеми
|
||||
примитивами: для действий используется Mantine Button с общей темой. В каталоге
|
||||
показаны filled для основного действия, default для вторичного/retry и subtle
|
||||
для вспомогательного, а также loading и disabled. Provider не меняет defaults
|
||||
Button или Paper ради каталога. Loading действия не заменяет loading страницы;
|
||||
при refetch сохраняются данные и показывается локальное состояние.
|
||||
Общие представления не получают финансовые данные и не управляют
|
||||
аутентификацией. Состояние выполнения действия отличается от загрузки всей
|
||||
страницы. При фоновом обновлении доступные данные сохраняются с локальным
|
||||
индикатором; правила восстановления описаны в
|
||||
[UI resilience](../features/frontend-ui-resilience.md).
|
||||
|
||||
Route-aware AppShell не входит в заявленный общий набор. Бизнес-компоненты
|
||||
и композиции остаются у entities/pages и показываются в Product; витрина не
|
||||
определяет FSD ownership. Подробности запуска, взаимодействий и coverage —
|
||||
[UI-каталог Storybook](ui-catalog.md).
|
||||
Каркас с продуктовой навигацией не входит в заявленный общий набор.
|
||||
Предметные карточки и композиции представлены в [UI-каталоге](ui-catalog.md).
|
||||
|
||||
## Границы доказательств
|
||||
|
||||
Каталог использует synthetic fixtures, локальные Actions и MemoryRouter, без
|
||||
application API/auth/storage runtime. Dependency-cruiser проверяет FSD и
|
||||
транзитивную runtime-изоляцию stories. Browser проверяет виды, размеры, focus и
|
||||
действия. Эти примеры не доказывают API recovery и прохождение инвестиционного
|
||||
сценария. Продуктовый пилот остаётся отдельным change и здесь не проводился.
|
||||
Каталог использует вымышленные данные и локальные действия без входа,
|
||||
сохранённого пользовательского состояния и application API. Проверки отделяют
|
||||
его от исполнения продуктовых запросов. Вид, размеры, фокус и взаимодействия
|
||||
проверяются в браузере; каталог не доказывает восстановление реального API
|
||||
или прохождение инвестиционного сценария.
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
# Ведение документации
|
||||
|
||||
Документация объясняет систему независимо от размещения исходного кода.
|
||||
За актуальность затронутого объяснения отвечает автор изменения предметной
|
||||
области; проверка сопоставляет изложение с фактическим поведением и принятыми
|
||||
решениями. Ответственность подсистем описана в [карте возможностей](../features/README.md).
|
||||
|
||||
## Владельцы фактов
|
||||
|
||||
| Тип знания | Где объясняется | Граница достоверности |
|
||||
| --- | --- | --- |
|
||||
| Устройство и взаимодействие системы | [Обзор](../architecture/system-overview.md) | Описывает существующие подсистемы, данные и потоки |
|
||||
| Наблюдаемое поведение | [Возможности](../features/README.md) | Сценарий, инвариант, ошибка и ограничение объясняются здесь полностью |
|
||||
| Значение терминов | [Глоссарий](../architecture/domain-glossary.md) | Одно определение, ссылки из связанных сценариев |
|
||||
| HTTP-контракт | [HTTP API](../architecture/http-api.md), публичный OpenAPI backend | Объяснение семантики не создаёт второй независимо редактируемый wire contract |
|
||||
| Причины значимого решения | [ADR](../adr/README.md) | Контекст, решение и последствия относятся к указанному статусу решения |
|
||||
| Окружение и восстановление | [Локальное окружение](local-workspace.md) | Предпосылки и ограничения описаны без знания устройства репозиториев |
|
||||
| Принципы сопровождения | [Engineering governance](engineering-governance.md) | Объясняют согласованность и доказательства результата |
|
||||
| Гипотезы и внешние наблюдения | [Исследования](../research/README.md) | Рекомендация не означает реализованную возможность |
|
||||
| Результаты прежних проверок | [Исторические свидетельства](README.md#исторические-свидетельства) | Действительны для состояния и условий своего времени |
|
||||
|
||||
Поведенческие требования и предложения изменений могут отдельно согласовываться
|
||||
в OpenSpec. Их роль описана [здесь](openspec-authority-and-lifecycle.md);
|
||||
понимание текущего сценария не требует доступа к хранилищу спецификаций.
|
||||
|
||||
При конфликте возможны устаревший текст, нарушение договорённости реализацией
|
||||
или незавершённое изменение. Текущее поведение не отменяет согласованное
|
||||
требование автоматически. Неустановленный смысл явно отмечается для ручного
|
||||
решения; особенно это важно для безопасности, данных и публичного контракта.
|
||||
|
||||
## Куда поместить знание
|
||||
|
||||
Объяснение принадлежит существующему документу о соответствующей области.
|
||||
Понятие определяется в глоссарии; сценарий связывает его с поведением и
|
||||
ограничениями; ADR сохраняет причину выбора; исследование — ещё не принятый
|
||||
вариант и его источники. Новый документ нужен для самостоятельного вопроса,
|
||||
которому нет подходящего места. Навигация делает его доступным из индекса.
|
||||
|
||||
Один факт имеет одно полное объяснение, на которое ссылаются остальные страницы.
|
||||
Ссылка внутри документации уточняет контекст, а не скрывает необходимое условие
|
||||
понимания за внутренним файлом другого репозитория.
|
||||
|
||||
## Содержание страницы
|
||||
|
||||
Связное объяснение содержит назначение, ответственность компонентов,
|
||||
предпосылки и инварианты, основной поток, ошибки, восстановление и ограничения.
|
||||
Диаграмма нужна, когда помогает понять взаимодействие. Это ориентир, а не
|
||||
обязательный набор пустых разделов.
|
||||
|
||||
Вместо имён классов, внутренних вспомогательных функций и настроек разработки
|
||||
излагается их архитектурный или функциональный смысл. Публичные API, единицы
|
||||
показателей, внешние системы и принятые технологические решения остаются
|
||||
частью объяснения, если нужны читателю. Детали разработки и инструкции
|
||||
инструментам не входят в описание системы.
|
||||
|
||||
Статус понятен из вступления или индекса: текущее поведение, объяснение решения,
|
||||
исследование или история. Дата наблюдения не гарантирует актуальность спустя
|
||||
время. Для замены принятого решения сохраняются его прежний контекст и ссылка
|
||||
на последующее решение.
|
||||
|
||||
## Обновление вместе с кодом
|
||||
|
||||
| Что изменилось в системе | Какое знание затронуто |
|
||||
| --- | --- |
|
||||
| Сценарий, инвариант, ошибка или восстановление | Объяснение возможности и её ограничений |
|
||||
| Ответственность, внешний источник или поток данных | Обзор, схема и причина значимого решения |
|
||||
| Значение понятия | Глоссарий и связанные сценарии |
|
||||
| Окружение, диагностика или граница проверки | Материалы сопровождения |
|
||||
| Новая возможность | Карта возможностей и тематический индекс |
|
||||
| Только внутреннее устройство без изменения описанных знаний | Изменение документации может не требоваться |
|
||||
|
||||
Изменения нескольких компонентов относятся к общей задаче; объяснение
|
||||
поставленного результата не должно обещать ещё отсутствующую часть.
|
||||
Смысловая согласованность важнее совпадения названий задач и формальных отметок.
|
||||
|
||||
## Проверка
|
||||
|
||||
Проверка охватывает Markdown, внутренние ссылки и якоря, доступность страниц
|
||||
через навигацию и чтение основной документации без соседних репозиториев.
|
||||
Внешние URL и HTML-ссылки не проверяются правилом относительных ссылок.
|
||||
Исторические аудиты, журнал устранения замечаний и свидетельства завершения
|
||||
сохраняют исходные адреса отдельно от основной книги.
|
||||
|
||||
Смысловая проверка подтверждает, что читатель понимает ответственность,
|
||||
инвариант и ограничение; будущая возможность не выдана за существующую;
|
||||
API и архитектура не изменены редакторским пересказом. Непонятный смысл
|
||||
внешней ссылки отмечается для ручной проверки, а не восполняется догадкой.
|
||||
Успешная синтаксическая проверка не доказывает актуальность знания.
|
||||
@@ -1,103 +1,82 @@
|
||||
# Engineering governance
|
||||
# Принципы изменения и проверки системы
|
||||
|
||||
Это общий owner решений о scope, dependencies, testing и проверке результата.
|
||||
Работа начинается с задачи пользователя и выполняется напрямую. OpenSpec/SDD
|
||||
не обязателен; прежняя [процедура](openspec-authority-and-lifecycle.md) доступна
|
||||
только по явному запросу. Исторические artifacts не переписываются.
|
||||
Ожидаемый результат определяется задачей пользователя. Сопровождение сохраняет
|
||||
ответственность подсистем, безопасность, точность данных и проверяемость результата.
|
||||
OpenSpec остаётся [необязательным средством согласования](openspec-authority-and-lifecycle.md);
|
||||
исторические свидетельства не становятся обязательной процедурой новой задачи.
|
||||
|
||||
## Выбор реализации
|
||||
|
||||
Читай этот раздел при новой abstraction/dependency, refactor, multi-module
|
||||
изменении или неоднозначном ownership.
|
||||
Связное поведение принадлежит ответственной подсистеме. Существующая возможность
|
||||
используется повторно, если сохраняет нужный смысл и инварианты. Новая граница
|
||||
оправдана самостоятельной ответственностью, общей потребностью нескольких
|
||||
потребителей либо необходимостью отделить доступ и целостность данных.
|
||||
|
||||
1. Требуемое поведение уже существует — используй его.
|
||||
2. У поведения есть подходящий owner/helper — расширь его, сохранив связность.
|
||||
3. Задачу решает платформа, стандартная библиотека или принятая dependency — используй её.
|
||||
4. Иначе добавь небольшую реализацию там, где принадлежит инвариант.
|
||||
5. Если текущая структура мешает правильному ownership, сделай необходимый связный refactor с проверкой сохранения поведения.
|
||||
|
||||
Оптимизируй ясность всей системы. Число файлов/строк само по себе не определяет
|
||||
качество: coherent refactor лучше дублированного guard в нескольких callers.
|
||||
|
||||
**Безопасный путь:** при неопределённом будущем reuse оставь код у ближайшего
|
||||
подходящего владельца. Выделение оправдано текущей общей ответственностью,
|
||||
несколькими реальными consumers или необходимой trust/transaction boundary.
|
||||
Один consumer не запрещает модуль с самостоятельным инвариантом, но не оправдывает
|
||||
interface/factory/registry только для воображаемой расширяемости.
|
||||
|
||||
Примеры: фильтр одного экрана остаётся page-local; чистое денежное преобразование
|
||||
использует существующий decimal helper; запрос Prisma не требует generic repository.
|
||||
Security validation, доступность, error handling и защита данных сохраняются
|
||||
даже в маленькой реализации.
|
||||
Простота оценивается по ясности всей системы и стоимости сопровождения,
|
||||
а не по размеру изменения. Предполагаемая будущая возможность сама по себе
|
||||
не оправдывает новую подсистему. Упрощение сохраняет валидацию, доступность,
|
||||
обработку ошибок и защиту от потери данных.
|
||||
|
||||
## Dependencies
|
||||
|
||||
Перед новой dependency проверь installed stack и существующий helper. Если
|
||||
подходящего решения нет, оцени поддерживаемую библиотеку, совместимость,
|
||||
maintenance/security cost и точную недостающую возможность. Собственный код
|
||||
выбирай по совокупной стоимости, а не ради отсутствия dependency любой ценой.
|
||||
|
||||
Версии и scripts принадлежат package.json/lockfile. Frontend сохраняет exact
|
||||
versions; backend использует свою текущую policy. Transitive package не считается
|
||||
прямо принятой dependency. Не меняй весь lockfile или инструментарий ради
|
||||
устаревшей рекомендации в Markdown. Новые сервисы, CI и browser mocking требуют
|
||||
задачи, в которой они действительно нужны.
|
||||
При выборе внешней зависимости учитываются текущая потребность, совместимость,
|
||||
поддержка, безопасность и стоимость сопровождения. Использование принятой
|
||||
платформы может быть проще собственной реализации; зависимость ради одной
|
||||
воображаемой будущей возможности не является самостоятельной потребностью.
|
||||
Новый сервис или общая инфраструктура должны решать актуальную задачу.
|
||||
|
||||
## Risk-based testing
|
||||
|
||||
Автоматический тест обязателен для изменённого security/privacy поведения,
|
||||
денежных вычислений, data integrity/migration, concurrency, публичного контракта,
|
||||
критического journey и подтверждённой регрессии.
|
||||
Изменения безопасности и приватности, денежных расчётов, целостности данных,
|
||||
миграций, конкурентного доступа, публичного контракта, критического сценария
|
||||
и подтверждённой регрессии требуют автоматической проверки соответствующего
|
||||
риска на наблюдаемой потребителем границе.
|
||||
|
||||
Выбирай самую дешёвую надёжную границу, наблюдаемую потребителем. Тест нужен
|
||||
для собственного branching, преобразования или инварианта; не для каждого
|
||||
DTO, декларативной конфигурации, thin adapter или поведения библиотеки.
|
||||
Меняющийся тест тоже активирует testing convention, даже без production diff.
|
||||
Frontend coverage — anti-regression constraint; backend общего threshold не имеет.
|
||||
Не пиши тесты только ради процента или повторения Markdown.
|
||||
Статические проверки не доказывают финансовую или функциональную корректность.
|
||||
Покрытие frontend служит ограничителем регрессий; для backend общего числового
|
||||
порога нет. Проверки поведения библиотеки или проценты сами по себе не заменяют
|
||||
проверку собственного инварианта системы.
|
||||
|
||||
## Проверка результата
|
||||
|
||||
В итерации используй targeted check из применимого convention. Перед завершением
|
||||
запусти `npm run verify` каждого изменённого code/docs repo под его `.nvmrc`
|
||||
после lockfile install. Для HTTP contract — дополнительно
|
||||
[contract checks](runtime-openapi-verification.md). Общего CI сейчас нет.
|
||||
Результат оценивается по исходной задаче: сохранены ли смысл данных и контракты,
|
||||
правильно ли разграничен доступ, учтены ли ошибки и доступность интерфейса.
|
||||
Проверки приложений и документации дополняются
|
||||
[согласованием HTTP-контракта](runtime-openapi-verification.md), если он меняется.
|
||||
Общего CI сейчас нет.
|
||||
|
||||
Проверь actual staged/unstaged/new scope и результат против задачи: ownership,
|
||||
сохранение данных/контрактов, ошибки, доступность, отсутствие лишних abstractions.
|
||||
Неизменившийся успешный gate можно использовать повторно, если известны команда,
|
||||
его полный relevant input scope и неизменные prerequisites; при сомнении выполни
|
||||
его снова. Auto-fix не заменяет non-mutating gate.
|
||||
Успешная проверка применима к тому состоянию системы и тем предпосылкам,
|
||||
на которых выполнена. При их изменении старое свидетельство не доказывает
|
||||
новый результат. Автоматическое исправление материалов и проверка без их
|
||||
изменения — разные действия.
|
||||
|
||||
В ответе достаточно: что поставлено, как проверено, какие ограничения остались.
|
||||
Не создавай role records, fingerprints всех repositories, Completion Evidence
|
||||
или delivery commits только ради процесса. Существующие рабочие изменения
|
||||
других задач сохраняются. Нужный review не заменяется количеством checkboxes.
|
||||
[Влияние на документацию](documentation.md#обновление-вместе-с-кодом) входит
|
||||
в оценку результата: описанные понятия, сценарии, решения и ограничения
|
||||
обновляются вместе с системой. Отсутствие влияния может быть обоснованным
|
||||
результатом. Отчёт о поставке различает выполненное, проверенное и остающиеся
|
||||
ограничения; количество формальных отметок не заменяет смысловую проверку.
|
||||
|
||||
## Guardrails и local gates
|
||||
|
||||
- **Автоматический invariant:** существующий deterministic checker блокирует нарушение в фактическом scope с документированными исключениями.
|
||||
- **Обязательное semantic правило/процедура:** исполнитель и reviewer проверяют решение; отсутствие checker не переводит i18n, validation или authorization в пожелание.
|
||||
- **Guidance:** необязательное предпочтение, например эстетический выбор между эквивалентными вариантами.
|
||||
|
||||
Не обещай enforcement, отсутствующий в config/tests. Новая автоматическая проверка
|
||||
оправдана реальным риском или повторяющимся дефектом, а не возможностью написать
|
||||
ещё один checker. Механические правила принадлежат tools; выбор правильного owner
|
||||
и полезного теста остаётся semantic judgement.
|
||||
Автоматические проверки гарантируют только свойства, охваченные их областью.
|
||||
Смысловые требования — например, правильный владелец данных, авторизация,
|
||||
локализация и полезность выбранных проверок — требуют отдельной оценки.
|
||||
Предпочтение между равноценными вариантами отличается от обязательного
|
||||
инварианта. Новая автоматизация оправдана реальным риском или повторяющимся
|
||||
дефектом; её наличие само по себе не является целью.
|
||||
|
||||
## UI-решения
|
||||
|
||||
Для изменяемого UI определи ожидаемые экраны, states, interactions и responsive
|
||||
поведение из задачи. Используй существующий [каталог](ui-catalog.md) и
|
||||
[дизайн-систему](design-system.md). Сложный или неоднозначный вариант покажи
|
||||
пользователю в конкретной форме до дорогой реализации; простой согласованный
|
||||
вариант делай сразу. Визуальные материалы нужны по задаче, не как обязательный
|
||||
SDD-пакет. Сборка Storybook не доказывает доступность или визуальное соответствие.
|
||||
Ожидаемые экраны, состояния, взаимодействия и поведение на разных размерах
|
||||
экрана определяются пользовательским сценарием. [Каталог](ui-catalog.md)
|
||||
и [дизайн-система](design-system.md) показывают существующую визуальную основу.
|
||||
Неоднозначный вариант можно оценить по конкретному примеру до реализации.
|
||||
Успешная сборка каталога не доказывает доступность и визуальное соответствие.
|
||||
|
||||
## Изменение опасного контракта
|
||||
|
||||
При public/security/data/billing или труднообратимом выборе заранее уточни
|
||||
существенную неопределённость. Для миграции определи trigger отката, действия,
|
||||
сохранность уже созданных данных и проверку восстановления. Сначала подготовь
|
||||
конкретное reviewable решение; обычные обратимые edits не требуют ритуального approval.
|
||||
Источники и конфликтующие версии разрешай через [context discipline](agent-token-efficiency.md).
|
||||
Для публичного контракта, безопасности, данных, платежей и труднообратимого
|
||||
изменения существенная неопределённость разрешается до применения решения.
|
||||
Для миграции важны условия отката, сохранность уже созданных данных и проверка
|
||||
восстановления. Порядок разрешения конфликтов знаний описан в
|
||||
[контексте системы](agent-token-efficiency.md#источники-и-конфликты).
|
||||
|
||||
@@ -1,51 +1,34 @@
|
||||
# Frontend Workflow
|
||||
# Frontend: ответственность и проверка
|
||||
|
||||
Frontend требует Node 22. В `frontend/` чистая установка и полный локальный quality gate выполняются так:
|
||||
Frontend предоставляет пользовательские экраны, навигацию и представление
|
||||
финансовых данных. Он получает данные только через публичный API backend;
|
||||
credentials T-Bank остаются на сервере. Состав приложения и потоки показаны
|
||||
в [обзоре системы](../architecture/system-overview.md).
|
||||
|
||||
```bash
|
||||
nvm use --silent
|
||||
npm ci
|
||||
npm run verify
|
||||
```
|
||||
## Совместимость с backend
|
||||
|
||||
`verify` проверяет OpenAPI drift, TypeScript, Biome, один coverage-backed запуск Vitest, Knip,
|
||||
FSD dependency rules, runtime graph stories и отдельные сборки приложения и
|
||||
Storybook. Он работает без backend. Coverage
|
||||
остаётся anti-regression constraint; правила выбора тестов зафиксированы в
|
||||
[engineering governance](engineering-governance.md).
|
||||
Типизированный клиент frontend производится из опубликованного backend
|
||||
OpenAPI. Согласованность клиента с сохранённым описанием API и согласованность
|
||||
этого описания с работающим backend проверяются отдельно.
|
||||
Изменение публичного контракта требует обновления производного клиента;
|
||||
подробности — [согласованность OpenAPI](runtime-openapi-verification.md).
|
||||
|
||||
Изолированные примеры реальных компонентов и композиций запускаются в Storybook
|
||||
через `npm run dev:catalog`. `npm run build:catalog` создаёт `storybook-static/`,
|
||||
а `npm run preview:catalog` обслуживает эту статическую сборку. Структура каталога,
|
||||
работа с Docs, Controls и Actions, доступность и ограничения описаны в
|
||||
[UI-каталоге Storybook](ui-catalog.md).
|
||||
## Проверка интерфейса
|
||||
|
||||
Для UI задачи используйте каталог как reference существующего решения.
|
||||
Ожидаемые экраны, states и interactions определите по [задаче](engineering-governance.md#ui-решения).
|
||||
Storybook показывает реализацию; визуальное соответствие и доступность
|
||||
проверяются отдельно от сборки. SDD-пакет для этого не обязателен.
|
||||
Локальная проверка frontend охватывает корректность типов, статический анализ,
|
||||
автоматические сценарии, зависимости и сборку приложения и UI-каталога.
|
||||
Она может выполняться без запущенного backend. Покрытие тестами ограничивает
|
||||
регрессии; само по себе число покрытых строк не доказывает правильность
|
||||
финансового расчёта, доступность или прохождение пользовательского сценария.
|
||||
|
||||
Backend остаётся источником OpenAPI. После изменения опубликованного
|
||||
backend-контракта разработчик обновляет в `frontend/` committed snapshot
|
||||
`src/shared/api/spec/openapi.json` копированием backend OpenAPI document, затем
|
||||
запускает:
|
||||
|
||||
```bash
|
||||
npm run openapi:generate
|
||||
```
|
||||
|
||||
Команда использует только committed snapshot и регенерирует
|
||||
`src/shared/api/generated/schema.d.ts` offline. Проверку соответствия backend
|
||||
runtime contract и frontend snapshot выполняют отдельной backend-командой
|
||||
`npm run test:openapi-contract`.
|
||||
[Каталог](ui-catalog.md) показывает существующие визуальные решения.
|
||||
Соответствие задаче, широкий и узкий экран, клавиатурная навигация и восстановление
|
||||
после ошибок проверяются в интерфейсе отдельно от успешной сборки.
|
||||
|
||||
## Состояние тестового клиента
|
||||
|
||||
`frontend/src/test/query.tsx` предоставляет `createTestQueryClient` с отключёнными
|
||||
test retries и query-only `createQueryWrapper`. Независимый case получает свой
|
||||
client до React wrapper render; rerender сохраняет тот же экземпляр и seeded
|
||||
cache. Auth и T-Bank tests используют эту же фабрику. Mantine, Router и
|
||||
AuthProvider остаются явно выбранными локальными providers.
|
||||
|
||||
Общий teardown последовательно выполняет RTL cleanup, сброс auth client и
|
||||
сброс MSW handlers. Production query defaults этой инфраструктурой не меняются.
|
||||
Независимые проверки получают изолированное состояние клиента. Обновление
|
||||
представления внутри одного сценария сохраняет его кэш; следующий сценарий
|
||||
не наследует сессию и ответы предыдущего. Повторные попытки в тестовой среде
|
||||
могут быть отключены для предсказуемого результата. Это не меняет
|
||||
[политику обновления данных приложения](../adr/007-react-query-fetch-policy.md).
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
# Локальное окружение и восстановление
|
||||
|
||||
WealthLedger поставляется как локальное приложение: frontend работает
|
||||
в браузере, backend обслуживает API и обращается к SQLite и внешним источникам.
|
||||
Это описание предпосылок и ограничений работы, без привязки к устройству
|
||||
исходного кода. Production-развёртывание в текущую поставку не входит.
|
||||
|
||||
## Подготовка backend
|
||||
|
||||
Локальная серверная среда использует Node 22 и SQLite. Для работы нужны:
|
||||
|
||||
| Параметр | Назначение и ограничение |
|
||||
| --- | --- |
|
||||
| Адрес локальной базы | Одинаковая база используется при подготовке схемы и работе приложения; относительный адрес зависит от рабочей директории процесса |
|
||||
| Разрешённый origin frontend | Определяет browser-источник, которому разрешён доступ к API с credentials |
|
||||
| Порт API | По умолчанию 3000 |
|
||||
| Секрет подписи сессий | Секрет не короче 32 символов; отличается от ключа шифрования подключения |
|
||||
| Ключ шифрования подключения | 32 байта в base64; требуется для чтения сохранённого T-Bank token |
|
||||
| Параметры интеграции | Адрес T-Bank, лимит запросов и при необходимости доверенный CA; [ограничения](../features/tbank-connection.md#конфигурация-и-ограничения) |
|
||||
|
||||
T-Bank token вводится пользователем через интерфейс после входа и не является
|
||||
общим параметром окружения. Существующая база и её ключ шифрования сохраняются
|
||||
при обновлении. До миграции необходима резервная копия; восстановление проверяется
|
||||
на отдельной копии. Потеря или замена ключа не является безвредным сбросом:
|
||||
прежнее подключение нельзя расшифровать новым ключом.
|
||||
|
||||
**Известное ограничение:** проверка новой временной SQLite-базы 12 сентября
|
||||
2026 года под Node 22 воспроизвела `Schema engine error` до создания схемы.
|
||||
Полный первый запуск на чистой базе пока не подтверждён; пользовательская база
|
||||
в этой проверке не использовалась. Условия пересмотра —
|
||||
[проверка backend](backend-workflow.md#локальная-проверка).
|
||||
|
||||
В development доступна [локальная Swagger UI](http://localhost:3000/api/docs)
|
||||
при стандартном порте API. Она показывает контракт, но не доказывает доступность
|
||||
T-Bank и не используется frontend как источник данных во время работы.
|
||||
|
||||
## Подготовка frontend
|
||||
|
||||
Стандартные адреса: API `http://localhost:3000`, frontend `http://localhost:5173`.
|
||||
Адрес API в клиенте должен совпадать с работающим сервером, а разрешённый origin
|
||||
backend — с origin браузера. Смена порта требует согласованного изменения
|
||||
адресов. Смесь `localhost` и `127.0.0.1` меняет границу browser cookie и CORS.
|
||||
|
||||
Локальный HTTP предполагает development-режим backend: в других режимах
|
||||
refresh-cookie получает Secure flag и требует защищённого соединения.
|
||||
Поведение сессии описано в [Authentication](../features/authentication.md).
|
||||
|
||||
## Первый сценарий
|
||||
|
||||
1. Пользователь регистрируется или входит. Новый профиль получает сессию;
|
||||
после перезагрузки приложение пытается её восстановить.
|
||||
2. В настройках пользователь сохраняет собственный T-Bank Invest token.
|
||||
Успех означает проверенный доступ к брокеру и сохранённое подключение.
|
||||
3. В разделе «Счета» доступны отдельный и общий портфель. Отсутствие доступных
|
||||
счетов является допустимым пустым результатом.
|
||||
4. «Доходы» показывают полученные выплаты, «События» — будущие.
|
||||
5. При выходе локальная сессия и её клиентский кэш очищаются.
|
||||
|
||||
Без T-Bank token доступны регистрация, вход и состояние отсутствующего
|
||||
подключения. Это не подтверждает работу финансовых сценариев.
|
||||
|
||||
## Если запуск или сценарий не работает
|
||||
|
||||
| Симптом | Проверка и безопасное восстановление |
|
||||
| --- | --- |
|
||||
| Порт занят | Адрес действующего процесса или выбранный свободный порт должен совпадать с настройками клиента и разрешённым origin |
|
||||
| Ошибка CORS или сессия теряется после reload | Согласованность адресов, hostname и режима cookie проверяется на стороне browser и backend |
|
||||
| Ошибка подготовки базы | Установленный blocker не устраняется удалением пользовательской базы или обходом миграций; сохраняются версия среды и текст ошибки |
|
||||
| `TBANK_NOT_CONNECTED` | Подключение создаётся в настройках текущего пользователя |
|
||||
| `INVALID_TBANK_TOKEN` | После проверки token и прав у брокера подключение заменяется через настройки |
|
||||
| `TBANK_UNAVAILABLE`, TLS или rate limit | Проверяются сеть, лимиты и доверенный CA; проверка TLS сохраняется |
|
||||
| НКР/MOEX недоступен при работающих остальных секциях | Состояние источника и повторная попытка относятся к конкретной секции; недоступность не означает отсутствия рейтинга |
|
||||
| Подключение не читается после смены ключа | Восстанавливается прежний ключ из защищённой копии; если он утрачен, собственный token вводится заново через настройки |
|
||||
|
||||
HTTP-запросы связываются с безопасными журналами через `X-Request-ID`.
|
||||
Пароли, cookies, Authorization и broker token не включаются в диагностический
|
||||
отчёт. Ограничения журналирования — [ADR 008](../adr/008-pino-backend-logging.md).
|
||||
|
||||
## Проверка первого изменения
|
||||
|
||||
Успешная сборка, запуск и прохождение сценария — разные доказательства.
|
||||
Границы проверки описаны для [frontend](frontend-workflow.md),
|
||||
[backend](backend-workflow.md) и [HTTP-контракта](runtime-openapi-verification.md).
|
||||
Завершённость результата учитывает фактические проверки и остающиеся ограничения.
|
||||
@@ -1,35 +1,25 @@
|
||||
# OpenSpec: optional legacy workflow
|
||||
# OpenSpec: роль требований и история процесса
|
||||
|
||||
Обязательный SDD lifecycle отменён для обычной разработки. Текущие правила —
|
||||
[engineering governance](engineering-governance.md),
|
||||
[context discipline](agent-token-efficiency.md) и root/local AGENTS.
|
||||
Задача пользователя не требует Proposal/Delta/Design/Tasks, отдельных agent roles,
|
||||
Completion Evidence или archive как условия завершения.
|
||||
Обязательный SDD lifecycle отменён для обычной разработки согласно
|
||||
[ADR 012](../adr/012-task-driven-development-with-scoped-context.md).
|
||||
Задача пользователя определяет ожидаемый результат; дополнительные planning
|
||||
artifacts и архивирование не являются условием её завершения.
|
||||
|
||||
## Существующие материалы
|
||||
|
||||
`specs/openspec` сохраняет behavioral specs, active changes, schemas и archives.
|
||||
Существующий planning artifact описывает только свой прежний scope и не доказывает
|
||||
готовность нового запроса. Датированные evidence/archives не переписываются.
|
||||
Нужную behavioral spec выбирай через [specs index](../../specs/AI_INDEX.md).
|
||||
OpenSpec сохраняет поведенческие требования, предложенные изменения и историю
|
||||
согласования. Существующее описание изменения относится только к своему объёму
|
||||
и не доказывает готовность другой возможности. Текущее поведение системы
|
||||
объясняется в [карте возможностей](../features/README.md).
|
||||
|
||||
## Если OpenSpec запрошен явно
|
||||
|
||||
Canonical store прежнего workflow — `wealth-ledger-specs`, физически
|
||||
`specs/openspec`. Перед Node-командами выбери frontend `.nvmrc`, если у specs
|
||||
нет своей. Для чтения/изменения change всегда задавай store явно:
|
||||
OpenSpec остаётся необязательным средством согласования требований, дизайна
|
||||
и задач. Его собственная модель определяет состав и порядок артефактов;
|
||||
подтверждение человеком и смысловая проверка результата не выводятся из
|
||||
одного наличия файлов. Обновление требований и архивирование меняют историю,
|
||||
поэтому относятся к явно выбранной работе с этой историей.
|
||||
|
||||
```bash
|
||||
openspec status --change <change> --json --store wealth-ledger-specs
|
||||
openspec instructions <artifact> --change <change> --json --store wealth-ledger-specs
|
||||
```
|
||||
|
||||
Native status/instructions определяют фактические artifacts и schema. Получай
|
||||
разрешение на именно запрошенное изменение, не выводи approval из наличия файлов.
|
||||
Sync/archive меняют existing specs/history и выполняются только в рамках такой
|
||||
явной задачи, после проверки ожидаемого semantic diff и сохранности данных.
|
||||
Structural validation не доказывает соответствие реализации задаче.
|
||||
|
||||
Прежнее rationale — [ADR 010](../adr/010-native-openspec-sdd-and-local-orchestration.md)
|
||||
и [011](../adr/011-native-openspec-lifecycle-with-repository-gates.md);
|
||||
текущий выбор прямой работы — [ADR 012](../adr/012-task-driven-development-with-scoped-context.md).
|
||||
Причины прежнего процесса и его упрощения сохранены в
|
||||
[ADR 010](../adr/010-native-openspec-sdd-and-local-orchestration.md) и
|
||||
[ADR 011](../adr/011-native-openspec-lifecycle-with-repository-gates.md).
|
||||
|
||||
@@ -2,55 +2,40 @@
|
||||
|
||||
## Назначение
|
||||
|
||||
`npm run test:openapi-contract` в `backend/` строит configured Nest application,
|
||||
создаёт runtime OpenAPI document и сверяет его с committed snapshot
|
||||
`frontend/src/shared/api/spec/openapi.json` после детерминированной canonicalization.
|
||||
Проверка сравнивает OpenAPI, сформированный настроенным backend-приложением,
|
||||
с описанием API, на котором основан frontend. Backend остаётся единственным
|
||||
источником исполняемого HTTP-контракта; frontend-клиент является производным.
|
||||
Причины выбора описаны в [ADR 002](../adr/002-nest-generated-openapi-contract.md).
|
||||
|
||||
Это отдельный контрактный gate, а не общий verifier всех репозиториев. Он обязателен перед завершением задачи, меняющей
|
||||
backend API или frontend transport contract и не заменяет
|
||||
локальные lint/typecheck команды приложений.
|
||||
Эта проверка подтверждает согласованность публичного контракта, но не заменяет
|
||||
проверки каждого приложения и наблюдаемого HTTP-поведения.
|
||||
|
||||
## Выбор и направление изменения
|
||||
|
||||
1. Определите, меняется wire contract (route, request/response field, status, error shape) или только внутренний код/UI model. Во втором случае snapshot не меняется.
|
||||
2. Прочитайте [HTTP semantics](../architecture/http-api.md) и нужный feature/domain source. Backend Nest controllers/DTO/Swagger metadata — единственный editable источник OpenAPI; specs repo не является вторым OpenAPI source.
|
||||
3. Измените этот source и проверьте representative HTTP behavior. При изменении контракта скопируйте generated runtime OpenAPI в committed frontend snapshot, затем в frontend выполните `npm run openapi:generate`.
|
||||
4. Выполните frontend `npm run openapi:check` и backend `npm run test:openapi-contract`, а также verify affected repos. Эти команды проверяют разное: schema parity не доказывает validation/auth/error behavior.
|
||||
Изменением контракта считается изменение маршрута, входного или выходного поля,
|
||||
статуса либо формы ошибки. Внутреннее изменение представления без изменения
|
||||
API не требует нового описания контракта.
|
||||
|
||||
Generated frontend TS и backend Prisma client вручную не редактируются.
|
||||
Frontend domain/UI type допустим, когда он отличается от transport DTO по смыслу.
|
||||
Перед compatibility-sensitive изменением оцените существующих consumers и
|
||||
rollback/data constraints; одного обновления snapshot недостаточно.
|
||||
|
||||
## Запуск
|
||||
|
||||
Из корня workspace:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
nvm use --silent
|
||||
npm run test:openapi-contract
|
||||
```
|
||||
|
||||
Перед первым запуском в backend выполняют `npm ci` под Node 22.
|
||||
Направление согласования: публичный API backend → OpenAPI → производное
|
||||
описание и типизированный клиент frontend. Две независимо редактируемые версии
|
||||
контракта создавали бы риск расхождения. Перед изменением, влияющим на
|
||||
совместимость, учитываются существующие потребители и сохранность данных.
|
||||
Семантика запросов и ошибок описана в [HTTP API](../architecture/http-api.md).
|
||||
|
||||
## Границы и результат
|
||||
|
||||
Команда:
|
||||
Сравнение выполняется на границе настроенного приложения, нормализует порядок
|
||||
ключей JSON-объектов и сохраняет порядок массивов. Оно не обновляет сравниваемые
|
||||
описания и клиент автоматически и не обращается к T-Bank или другим внешним
|
||||
источникам. Несовпадение указывает на рассогласование контракта.
|
||||
|
||||
- использует configured Nest application на integration boundary;
|
||||
- рекурсивно сортирует только ключи JSON objects и сохраняет порядок arrays;
|
||||
- не записывает snapshot или generated frontend types.
|
||||
|
||||
Она не записывает committed snapshot или generated frontend types и не
|
||||
обращается к T-Bank либо другому внешнему сервису. Если контракт действительно
|
||||
изменён, snapshot обновляют явным копированием backend OpenAPI document в
|
||||
`frontend/src/shared/api/spec/openapi.json`, затем в `frontend` запускают
|
||||
`npm run openapi:generate` и снова выполняют эту проверку.
|
||||
Равенство схем не доказывает фактическую работу валидации, авторизации,
|
||||
статусов, cookie и обработки ошибок: для этого нужны наблюдения полного
|
||||
HTTP-потока. Согласованность описаний и функциональная корректность —
|
||||
разные доказательства.
|
||||
|
||||
## Ограничение e2e
|
||||
|
||||
Проверка Swagger не запускает backend e2e tests. WL-P2-05 (runnable e2e) и
|
||||
WL-P2-13 (единый workspace verdict) отложены из-за нестабильного Prisma 7.9.1
|
||||
migration gate; дата, rationale и trigger пересмотра находятся в
|
||||
[audit remediation registry](audit-remediation.md).
|
||||
Сравнение OpenAPI не запускает сквозные проверки с миграциями базы.
|
||||
Известная ошибка движка миграций и условие пересмотра описаны в
|
||||
[проверке backend](backend-workflow.md#локальная-проверка).
|
||||
|
||||
+50
-98
@@ -1,120 +1,72 @@
|
||||
# UI-каталог Storybook
|
||||
|
||||
Storybook 10.6.0 показывает реальные компоненты и композиции WealthLedger
|
||||
на общей визуальной основе приложения без входа и подключения backend.
|
||||
Storybook 10.6.0 показывает реальные представления WealthLedger на общей
|
||||
визуальной основе приложения без входа и подключения backend.
|
||||
|
||||
## Запуск и сборка
|
||||
|
||||
Из `frontend/` выберите Node 22 и установите зависимости из lockfile:
|
||||
|
||||
```bash
|
||||
nvm use --silent
|
||||
npm ci
|
||||
npm run dev:catalog
|
||||
```
|
||||
|
||||
Storybook запускается на [localhost:6006](http://localhost:6006); браузер
|
||||
автоматически не открывается. Отдельная статическая сборка и её preview:
|
||||
|
||||
```bash
|
||||
npm run build:catalog
|
||||
npm run preview:catalog
|
||||
```
|
||||
|
||||
Результат находится в `frontend/storybook-static/`, вход — `index.html`.
|
||||
Команда preview выводит адрес статической витрины в терминале. Обычный
|
||||
`npm run build` сохраняет приложение в `frontend/dist/`; stories не входят
|
||||
в его entrypoint и продуктовые маршруты. Публикация отдельным сервисом не настроена.
|
||||
Каталог работает как отдельная локальная витрина по адресу
|
||||
[localhost:6006](http://localhost:6006) либо как самостоятельная статическая
|
||||
сборка. Его примеры не входят в пользовательские маршруты приложения.
|
||||
Публикация отдельным сервисом не настроена.
|
||||
|
||||
## Компоненты и работа с примерами
|
||||
|
||||
В дереве доступны два блока, 9 групп / 30 историй:
|
||||
Два блока каталога включают 9 групп и 30 примеров:
|
||||
|
||||
| Блок / группа | Что показывает |
|
||||
| Группа | Что показывает |
|
||||
| --- | --- |
|
||||
| `Design System/Foundations` | Восемь палитр и семантические роли, типографику, интервалы, радиусы, тени и breakpoints из общей темы, адаптированной из tokens.json. |
|
||||
| `Design System/Components/StateView` | Четыре empty/error варианта с действием и без. |
|
||||
| `Design System/Components/LoadingSkeleton` | Общую доступную busy-область с нейтральными structural shapes. |
|
||||
| `Design System/Components/Button` | Прямой Mantine Button: primary, default, subtle, loading, disabled; локальное действие и keyboard interaction. |
|
||||
| `Product/BrokerageAccountList` | Сводки счетов в нескольких валютах, недоступную/пустую сводку и длинное название. |
|
||||
| `Product/PositionCard` | Акцию с положительным результатом, облигацию с отрицательным, прочий инструмент и позицию без оценки. |
|
||||
| `Product/RecentEvents` | Полученные события, loading/error/empty и неизвестную ожидаемую сумму. |
|
||||
| `Product/PortfolioRefreshState` с `PortfolioTotals` | Сохранённые суммы при обновлении и ошибке, локальный retry. |
|
||||
| `Product/AccountPageLoading` | Реальный skeleton заголовка, сводки и строк страницы счёта. |
|
||||
| Основы дизайн-системы | Палитры, семантические роли, типографику, интервалы, радиусы, тени и адаптивные размеры |
|
||||
| Пустой результат и ошибки | Четыре варианта с действием и без |
|
||||
| Загрузка | Доступную область занятости с нейтральными фигурами |
|
||||
| Кнопки | Основное, вторичное и вспомогательное действие, выполнение и недоступность, работу с клавиатурой |
|
||||
| Список счетов | Несколько валют, недоступную и пустую сводку, длинное название |
|
||||
| Карточка позиции | Акцию с положительным результатом, облигацию с отрицательным, прочий инструмент и отсутствие оценки |
|
||||
| Последние события | Успешный, загружаемый, ошибочный и пустой результат; неизвестную сумму |
|
||||
| Обновление портфеля | Сохранённые суммы при обновлении и ошибке, локальную повторную попытку |
|
||||
| Загрузка страницы счёта | Контур ожидаемых заголовка, сводки и строк |
|
||||
|
||||
Быстрые входы: [Design System — цвета](http://localhost:6006/?path=/story/design-system-foundations--colors)
|
||||
и [Product — карточка позиции](http://localhost:6006/?path=/story/product-positioncard--stock-gain).
|
||||
Все исходные 21 истории сохранены; 9 новых добавляют foundations и общие примеры.
|
||||
Бизнес-компоненты остаются в entities/pages, а общие StateView и LoadingSkeleton
|
||||
— в shared/ui. Button показан напрямую: новое имя-wrapper не вводится.
|
||||
Каталог не перечисляет все элементы библиотеки или приложения. Отсутствие
|
||||
представления в витрине не означает его отсутствия в продукте. Основы показывают
|
||||
опубликованные шкалы и смысл ролей; особые размеры и тени конкретных экранов
|
||||
не объявляются общими токенами. Границы описаны в [дизайн-системе](design-system.md).
|
||||
|
||||
Каталог не перечисляет весь Mantine или все компоненты приложения. AppShell
|
||||
с product navigation не объявлен компонентом общего набора. Отсутствие компонента
|
||||
в каталоге не запрещает его использование. Foundations показывает опубликованные
|
||||
шкалы из `shared/theme/tokens.json`, описания ролей и эффективные Mantine значения.
|
||||
Локальные размеры и особые тени не объявляются глобальными токенами;
|
||||
неопубликованные defaults остаются у Mantine. [Дизайн-система](design-system.md)
|
||||
описывает JSON-формат, внешнее чтение, ownership и правила расширения.
|
||||
Canvas показывает выбранный пример. Docs поясняет назначение и ограничения,
|
||||
Controls меняет доступные свойства, Actions показывает локальные действия.
|
||||
Вымышленные исходные данные не редактируются через Controls: другой набор
|
||||
данных выбирается отдельным примером. Свойства можно сбросить, пример —
|
||||
смонтировать заново; изменение размера просмотра не сбрасывает выбранные значения.
|
||||
|
||||
Выберите историю в дереве, чтобы открыть её состояние в Canvas. Docs описывает
|
||||
назначение, ограничения и свойства группы, а также её примеры. Controls меняют
|
||||
разрешённые свойства; синтетические объекты и callbacks недоступны для редактирования.
|
||||
Например, `kind` у `PositionCard` меняет вариант представления фиксированной позиции,
|
||||
а разные данные инструмента выбираются отдельной историей. Actions регистрирует
|
||||
локальные callbacks кнопок и retry.
|
||||
|
||||
Для возврата изменённых свойств используйте штатный reset args в Controls;
|
||||
для повторного монтирования примера — remount в панели Canvas. Размер preview
|
||||
можно менять без сброса args. Изолированный iframe позволяет отдельно проверить
|
||||
компонент на узком экране; навигацией самой витрины управляет Storybook.
|
||||
|
||||
Preview и приложение используют один public API `shared/theme`: theme,
|
||||
CSSVariablesResolver и базовые styles вместе с Mantine CSS. Preview использует
|
||||
русскую i18n и фиксированную светлую схему без чтения сохранённой темы.
|
||||
Stories находятся рядом с существующими presentation components и импортируют
|
||||
их реализации. Токены и описания их семантических ролей принадлежат
|
||||
`shared/theme/tokens.json`; `theme.ts` напрямую адаптирует этот локальный файл
|
||||
в Mantine, preview не хранит копию токенов. Error StateView сохраняет alert semantics,
|
||||
skeleton — busy-область с декоративными фигурами без фокуса. Проверяйте доступность
|
||||
действий и ссылок с клавиатуры вместе с визуальным состоянием.
|
||||
Витрина и приложение используют одну тему. Примеры показываются по-русски
|
||||
в светлой схеме. Ошибка сохраняет доступное объявление, загрузка — состояние
|
||||
занятости; декоративные фигуры не получают фокус.
|
||||
|
||||
## Границы и сопровождение
|
||||
|
||||
Все счета, позиции, события и суммы вымышлены. Stories не читают application
|
||||
storage, cookies, секреты или реальные пользовательские данные. Внешние логотипы
|
||||
не загружаются: примеры используют буквенный fallback существующего компонента.
|
||||
Storybook manager может сохранять собственные настройки витрины; telemetry отключена.
|
||||
Все счета, позиции, события и суммы вымышлены. Каталог не читает сессии,
|
||||
cookies, секреты и реальные пользовательские данные. Вместо внешних логотипов
|
||||
показываются буквенные заглушки. Сама витрина может сохранять свои настройки;
|
||||
телеметрия отключена.
|
||||
|
||||
Stories не подключают AuthProvider, QueryClient, API clients и исполняемые VM.
|
||||
Действия не обращаются к application API. Ссылки меняют только локальный маршрут
|
||||
MemoryRouter: страница назначения не отображается, URL приложения не меняется.
|
||||
Retry демонстрирует локальный callback и не доказывает восстановление API или
|
||||
полный пользовательский сценарий. Loading/error относятся к выбранному примеру.
|
||||
Действия не обращаются к application API. Ссылки меняют только локальное
|
||||
состояние примера, не открывают продуктовую страницу назначения и не меняют
|
||||
адрес приложения. Повторная попытка демонстрирует локальное действие и не
|
||||
доказывает восстановление реального запроса.
|
||||
|
||||
Композиция сохранённых сумм показывает представление Client Cached Snapshot;
|
||||
сам query lifecycle не исполняется. Для запросных экранов действует
|
||||
[UI Pattern](../../frontend/.ai/conventions/frontend-ui.md#состояния-и-recovery): сохранение данных при refetch,
|
||||
structural skeleton для initial loading и контекстный индикатор mutation.
|
||||
Skeleton конкретной страницы остаётся ответственностью страницы.
|
||||
Сохранённые суммы иллюстрируют Client Cached Snapshot, но его жизненный цикл
|
||||
здесь не исполняется. В приложении первичная загрузка показывает контур
|
||||
ожидаемого содержимого, фоновое обновление сохраняет данные, а выполняемое
|
||||
действие имеет контекстный индикатор. Подробности —
|
||||
[состояния интерфейса](../features/frontend-ui-resilience.md).
|
||||
|
||||
При изменении включённого компонента проверяйте вместе с ним его пример,
|
||||
описание и ограничения. `npm run verify` включает Storybook в strict TypeScript,
|
||||
Biome, Vitest, Knip и dependency-cruiser, затем собирает приложение и статическую
|
||||
витрину. Основная проверка FSD сохраняется; отдельный `deps:storybook` проверяет
|
||||
runtime graph stories и preview, запрещая достижимость application data.
|
||||
Type-only ссылки на типы VM и API стираются и не запускают запросы.
|
||||
Declarative stories не требуют искусственного unit coverage, а продуктовые
|
||||
coverage floors сохраняются. Клавиатура, реальные размеры и визуальное
|
||||
соответствие проверяются в браузере; автоматической visual regression нет.
|
||||
Автоматические проверки frontend охватывают каталог и его изоляцию от
|
||||
продуктовых запросов. Примеры и их пояснения обновляются вместе с включёнными
|
||||
представлениями. Клавиатура, реальные размеры и визуальное соответствие
|
||||
проверяются в браузере; автоматической визуальной регрессии нет.
|
||||
|
||||
## Использование в UI задаче
|
||||
|
||||
Каталог помогает выбрать existing component, состояние и ограничения. Ожидаемое
|
||||
поведение определите из задачи: экраны, states, interactions и узкий viewport.
|
||||
Для сложного варианта покажите конкретный макет/пример до дорогой реализации;
|
||||
простой согласованный вариант реализуйте сразу по [UI policy](engineering-governance.md#ui-решения).
|
||||
|
||||
Story — reference текущей реализации. Сборка не доказывает visual match,
|
||||
keyboard accessibility или работу настоящего API. Проверяйте соответствие задаче
|
||||
и применимые states в браузере. Использование установленного каталога не требует
|
||||
повторного approval установки или OpenSpec Design artifact.
|
||||
Каталог помогает сравнить существующие состояния с ожидаемым пользовательским
|
||||
сценарием. Он дополняет [принципы UI-решений](engineering-governance.md#ui-решения)
|
||||
конкретными примерами, но успешная сборка не доказывает доступность,
|
||||
визуальное соответствие и работу настоящего API.
|
||||
|
||||
Reference in New Issue
Block a user