docs(ai): add scoped backend conventions
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
# Backend architecture
|
||||
|
||||
## Выбор владельца
|
||||
|
||||
Найди существующий use case, его collaborators и tests до создания module/service.
|
||||
Сохрани ответственность в текущем module, если новая возможность относится к нему.
|
||||
Module — граница связного набора providers, а не папка для каждого endpoint.
|
||||
|
||||
| Решение | Owner |
|
||||
| --- | --- |
|
||||
| Route, request/response mapping, status/cookie | Controller, [HTTP rules](backend-http-api.md) |
|
||||
| Business use case, orchestration, domain validation | Feature service |
|
||||
| Input shape/format | DTO + configured ValidationPipe |
|
||||
| Атомарность/DB query | Сервис use case через PrismaService, [Data](backend-data.md) |
|
||||
| Внешний protocol, deadline/retry/limiting | Existing client, [Integrations](backend-integrations.md) |
|
||||
| Чистое вычисление/mapper без lifecycle и DI | Обычная функция рядом с domain owner |
|
||||
| Bootstrap/config/global cross-cutting concern | AppModule, config, существующий common owner |
|
||||
|
||||
**Безопасный путь:** расширь текущий owner; выделяй collaborator, когда он скрывает
|
||||
самостоятельный инвариант или координацию. Не вводи CQRS, generic repository,
|
||||
interface с одной реализацией или base controller только ради шаблона Nest.
|
||||
Не превращай common в хранилище бизнес-логики и не переноси frontend модели сюда.
|
||||
|
||||
## Существующие seams
|
||||
|
||||
`TbankConnectionModule` уже объединяет счета, портфель, операции, доходы и события.
|
||||
Новый связанный use case обычно добавляется в него; создание отдельного module
|
||||
требует собственной ответственности, не только нового файла.
|
||||
|
||||
- [BrokerageOperationsController](../../src/tbank/brokerage-operations.controller.ts) передаёт user/account/query в service, без финансовых вычислений в controller.
|
||||
- [TbankAccessService](../../src/tbank/tbank-access.service.ts) владеет connection/account access и generation; новые account use cases используют его вместо копирования guard/decrypt logic.
|
||||
- [decimal.ts](../../src/tbank/decimal.ts) — пример pure domain helper; Injectable и adapter для арифметики не нужны.
|
||||
|
||||
Наличие guard подтверждает session, но не владение account. При пересечении
|
||||
access boundary добавь [Security](security-auth.md). Ошибка upstream не должна
|
||||
обходить общий HTTP filter или превращать чужой account в доступный.
|
||||
|
||||
## Logging
|
||||
|
||||
Единственный logger — nestjs-pino; application events используют существующий
|
||||
[StructuredLogger](../../src/common/logging/structured-logger.service.ts) и
|
||||
request context. Выбирай стабильное имя события и разрешённые scalar fields.
|
||||
Wrapper отбрасывает неизвестные поля, но это не разрешение помещать secret
|
||||
в `message`/`stack`: review sensitive logging обязателен.
|
||||
Не добавляй второй logger или сырой request/body/error payload.
|
||||
Источник rationale — [ADR 008](../../../docs/adr/008-pino-backend-logging.md);
|
||||
при secrets/user data читай также Security.
|
||||
|
||||
## Проверка
|
||||
|
||||
`npm run typecheck:app`, `npm run lint`, targeted Jest по изменённому use case.
|
||||
Смысл boundaries проверяется review: backend не имеет отдельного автоматического
|
||||
FSD/DI architecture checker. Existing tests и build не доказывают правильный owner.
|
||||
Reference in New Issue
Block a user