Files
backend/.ai/conventions/backend-architecture.md
T

4.0 KiB
Raw Blame History

Backend architecture

Выбор владельца

Найди существующий use case, его collaborators и tests до создания module/service. Сохрани ответственность в текущем module, если новая возможность относится к нему. Module — граница связного набора providers, а не папка для каждого endpoint.

Решение Owner
Route, request/response mapping, status/cookie Controller, HTTP rules
Business use case, orchestration, domain validation Feature service
Input shape/format DTO + configured ValidationPipe
Атомарность/DB query Сервис use case через PrismaService, Data
Внешний protocol, deadline/retry/limiting Existing client, Integrations
Чистое вычисление/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 передаёт user/account/query в service, без финансовых вычислений в controller.
  • TbankAccessService владеет connection/account access и generation; новые account use cases используют его вместо копирования guard/decrypt logic.
  • decimal.ts — пример pure domain helper; Injectable и adapter для арифметики не нужны.

Наличие guard подтверждает session, но не владение account. При пересечении access boundary добавь Security. Ошибка upstream не должна обходить общий HTTP filter или превращать чужой account в доступный.

Logging

Единственный logger — nestjs-pino; application events используют существующий StructuredLogger и request context. Выбирай стабильное имя события и разрешённые scalar fields. Wrapper отбрасывает неизвестные поля, но это не разрешение помещать secret в message/stack: review sensitive logging обязателен. Не добавляй второй logger или сырой request/body/error payload. Источник rationale — ADR 008; при 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.