docs: establish architecture records
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
# Docs
|
||||||
|
|
||||||
|
## Назначение
|
||||||
|
|
||||||
|
Репозиторий постоянной документации WealthLedger. Функциональные изменения планируются в `../specs/openspec` до реализации; docs фиксирует согласованные и фактически реализованные решения.
|
||||||
|
|
||||||
|
## Проверка
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
## Границы
|
||||||
|
|
||||||
|
- `adr/` - долгоживущие решения, `architecture/` - устройство системы, `development/` - процесс разработки, `features/` - фактическое поведение завершенных фич.
|
||||||
|
- Для диаграмм использовать Mermaid в Markdown. Feature-документация описывает пользовательский поток, API-сценарий и ограничения.
|
||||||
|
- Не хранить OpenSpec-артефакты, код приложений или секреты; требования и task-план остаются в `../specs/openspec`.
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# 001. Prisma и SQLite для локального MVP
|
||||||
|
|
||||||
|
**Status:** Accepted, baseline decision
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
MVP нужен воспроизводимый локальный доступ к данным без инфраструктуры развёртывания. Доменные таблицы и миграции на baseline отсутствуют.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Backend использует Prisma с SQLite из конфигурации окружения. Первые доменные таблицы и миграции появятся в соответствующем будущем OpenSpec change.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
Локальный запуск прост и типизированный доступ к данным готов заранее. SQLite не считается решением для production-развёртывания; его замена потребует отдельного ADR и change.
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# 002. OpenAPI, генерируемый NestJS, как контракт API
|
||||||
|
|
||||||
|
**Status:** Accepted, baseline decision
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Ручные frontend-типы и описания маршрутов расходятся с backend и создают дублирование.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
NestJS генерирует OpenAPI из контроллеров и DTO для API с префиксом `/api/v1`. Frontend локальной воспроизводимой командой генерирует и хранит API-клиент в своем репозитории; runtime использует только этот клиент, а не OpenAPI endpoint.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
Изменение HTTP-контракта требует регенерации клиента. Swagger/OpenAPI публикуется для локальной разработки и не является runtime-зависимостью frontend.
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# 003. Серверная gRPC-граница T-Bank
|
||||||
|
|
||||||
|
**Status:** Accepted, baseline decision
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
T-Bank требует секретов и внешняя интеграция должна быть управляемой, наблюдаемой и независимой от браузера.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Только backend обращается к T-Bank через выделенную gRPC-границу. Frontend вызывает только собственный HTTP API и никогда не получает T-Bank credentials или gRPC-клиент.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
F[Frontend] --> B[Backend API]
|
||||||
|
B --> T[T-Bank gRPC]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
Контроль секретов, повторов и лимитов централизован на сервере. Реализация boundary будет добавлена будущим OpenSpec change подключения T-Bank.
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# 004. Шифрование T-Bank токена пользователя
|
||||||
|
|
||||||
|
**Status:** Accepted, baseline decision
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Токен T-Bank является секретом пользователя и не должен быть доступен браузеру или сохранён в открытом виде.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Для каждого пользователя backend хранит один токен, зашифрованный ключом `TOKEN_ENCRYPTION_KEY`. API не возвращает токен frontend; расшифровка допустима только серверу непосредственно для вызова T-Bank.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
Ключ обязателен только в server environment и не логируется. Ротация ключей, схема хранения и реализация будут добавлены в будущем change подключения T-Bank.
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# 005. Устойчивость к ограничениям T-Bank upstream
|
||||||
|
|
||||||
|
**Status:** Accepted, baseline decision
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Внешний API имеет ограничения и временные ошибки; параллельные запросы пользователей не должны их обходить.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Backend применяет глобальный конфигурируемый лимитер в 5 запросов в секунду к T-Bank, ограниченные временные повторы и повторы для `429`. In-memory TTL-кэш хранит данные 30 секунд, а инструменты не менее одного дня.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
Лимит действует на экземпляр backend и кэш не переживает перезапуск. Распределённые лимиты, кэш и точные параметры retry будут рассмотрены при появлении нескольких экземпляров или подтвержденных требований upstream.
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# 006. Политика access и refresh сессий
|
||||||
|
|
||||||
|
**Status:** Accepted, baseline decision
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Клиенту нужна короткая авторизация без передачи долгоживущего секрета JavaScript-коду.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Access token живёт 15 минут только в памяти frontend. Rotating refresh token живёт 7 дней и передаётся в cookie `httpOnly`, `SameSite=Lax`; сервер заменяет refresh token при обновлении сессии.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
Перезагрузка страницы требует обновления access token через cookie-сессию. Полная реализация сессий, хранилища и отзыва будет добавлена change авторизации.
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# 007. Политика запросов и кэша React Query
|
||||||
|
|
||||||
|
**Status:** Accepted, baseline decision
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Автоматические повторные запросы могут создавать лишнюю нагрузку на ограниченный T-Bank upstream.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
React Query запрашивает серверные данные только при открытии соответствующего экрана. Refetch по возврату фокуса отключён, обновление запускается пользователем вручную; backend TTL-кэш остаётся защитой от дублирующих запросов.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
Пользователь может видеть данные до ручного обновления или следующего открытия экрана. Live-обновления и иные триггеры появятся только при подтверждённой продуктовой необходимости.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# ADR
|
||||||
|
|
||||||
|
Здесь фиксируются долгоживущие технические решения. Новый ADR описывает контекст, решение и последствия; заменяемое решение получает новый ADR со ссылкой на прежний.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# Architecture
|
||||||
|
|
||||||
|
Здесь описывается фактическое устройство системы, общие границы компонентов и интеграций. Диаграммы Mermaid добавляются, когда они проясняют взаимодействие.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# Development
|
||||||
|
|
||||||
|
Здесь размещаются устойчивые правила разработки, локальной проверки и поставки. Требования и планы изменений остаются в `../specs/openspec`.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# Features
|
||||||
|
|
||||||
|
Здесь документируется фактическое поведение завершенных пользовательских фич: пользовательский поток, API-сценарий и ограничения. Не реализованные возможности сюда не добавляются.
|
||||||
Reference in New Issue
Block a user