docs: make project documentation self-contained

This commit is contained in:
2026-09-12 13:09:37 +03:00
parent aa9afc15e4
commit 3a99af1a6e
36 changed files with 1006 additions and 703 deletions
+27 -26
View File
@@ -2,25 +2,24 @@
## Источник контракта
Nest controllers/DTO/Swagger metadata генерируют runtime OpenAPI. Настройка
приложения — [configureApp](../../backend/src/main.ts); frontend хранит derived
snapshot и generated TS. Изменения проходят
Backend генерирует OpenAPI из собственного публичного API. Frontend использует
производное описание контракта и типизированный клиент. Изменения проходят
[contract workflow](../development/runtime-openapi-verification.md).
API имеет prefix `/api/v1`; Swagger публикуется для локальной разработки по
environment policy, а не используется frontend в runtime.
## Validation и identity
Global ValidationPipe использует `transform: true`, `whitelist: true`.
Unknown properties удаляются, а их rejection не обещается без
`forbidNonWhitelisted`. Runtime DTO validators и преобразования задают допустимый
вход; бизнес-ограничения и доступ к account проверяются service/access boundary.
Guard подтверждает identity; accountId из URL сам по себе не доказывает доступ.
Backend преобразует и проверяет входные данные на общей HTTP-границе.
Неизвестные свойства запроса удаляются; сам факт их передачи не обещает отказа.
Проверка формата не заменяет бизнес-ограничения и проверку доступа к счёту.
Аутентификация подтверждает личность пользователя; accountId из URL сам по себе
не доказывает доступ к брокерским данным.
## Error contract
Общий [HttpExceptionFilter](../../backend/src/common/filters/http-exception.filter.ts)
возвращает `application/problem+json` со `status` и публичным `code`.
Общая граница обработки HTTP-ошибок возвращает `application/problem+json`
со `status` и публичным `code`.
Неожиданный exception возвращает `500` / `INTERNAL_SERVER_ERROR`, без исходного
message/stack. Типичный ответ:
@@ -30,21 +29,22 @@ message/stack. Типичный ответ:
Для input validation контракт требует `400`, `VALIDATION_ERROR` и `errors` как
массив `{ pointer, detail }`, где pointer адресует поле запроса. Это требование
не считается проверенным одним Swagger snapshot: direct controller call не
запускает ValidationPipe. Текущий filter преобразует `ValidationError.constraints`,
а default Nest pipe формирует массив строк; корректность field details в
configured HTTP pipeline нужно проверять отдельно и не копировать этот seam
как доказанно полный пример.
не считается проверенным одним описанием OpenAPI: нужна проверка реального
HTTP-ответа после всех стадий обработки запроса.
Документированный DTO — [ProblemDetailsDto](../../backend/src/common/decorators/api-safe-error-response.decorator.ts).
Filter не добавляет автоматически все поля из RFC (`type`, `title`, `instance`).
Не вводи дополнительные обязательные поля без согласованного изменения wire contract.
Caller выбирает поведение по public code, не по внутреннему тексту exception.
**Требует ручной проверки:** согласованность деталей ошибок валидации полей
в полном HTTP-потоке пока не подтверждена. Известно расхождение формата ошибок
между стадиями валидации и формирования ответа; наличие описания в OpenAPI
не доказывает передачу ожидаемых `pointer` и `detail`.
Ответ не включает автоматически все поля RFC (`type`, `title`, `instance`).
Добавление обязательного поля является изменением публичного контракта.
Клиент выбирает поведение по публичному коду, а не по внутреннему тексту ошибки.
## Domain errors и auth
Специальный code задаётся ответственным use case; generic mapping и безопасный
envelope принадлежат filter. Auth endpoints используют свои status и cookie
Специальный code определяется сценарием; общее преобразование ошибок и безопасная
форма ответа принадлежат HTTP-границе. Auth endpoints используют свои status и cookie
operations: [Authentication](../features/authentication.md).
T-Bank token failure и временная недоступность имеют разные значения:
[Connection API](../features/tbank-connection.md#api). Raw upstream/Prisma errors
@@ -52,8 +52,9 @@ T-Bank token failure и временная недоступность имеют
## Граница доказательства
OpenAPI integration проверяет равенство schemas, а не результат каждого request.
Filter unit test проверяет безопасный unexpected error. Для изменения validation,
guard, status/cookie или domain error нужны representative configured HTTP cases;
известный e2e environment blocker не превращает отсутствующую проверку в success.
Выбор уровня и команд — [backend testing](../../backend/.ai/conventions/backend-testing.md).
Сравнение OpenAPI подтверждает согласованность схем, а не результат каждого
запроса. Безопасная обработка неожиданной ошибки проверяется отдельно.
Валидация, доступ, статусы и cookie требуют проверки полного HTTP-потока;
атомарность хранения — проверки с изолированной реальной базой.
Известное ограничение сквозных проверок описано в
[проверке backend](../development/backend-workflow.md#локальная-проверка).