Resolve A01-A10 and C01-C07 from the backend audit. Preserve auth failures, forced candle reconciliation and forecast freshness. Validate MOEX responses and nested HTTP errors; remove unused legacy paths. Verified: 209 unit tests, 262 SQLite e2e tests on Linux, OpenAPI and durability. Record the remaining macOS native SQLite abort in the audit.
6.8 KiB
Backend HTTP API
Выбор boundary
Сначала определи, меняется wire contract или только реализация существующего use case. Для route/request/response/status/error shape используй локальный публичный контракт и configured HTTP tests.
| Проверка | Где выполнять |
|---|---|
| Тип/формат/диапазон входа | Runtime DTO class с class-validator/class-transformer |
| Согласованность полей, бизнес-ограничение | Feature service/domain helper |
| Session и identity | Existing guard/strategy |
| Доступ user к конкретному account | Existing access service |
| HTTP envelope/безопасная ошибка | Общий HttpExceptionFilter |
Controller объявляет contract и делегирует; не обращается напрямую к Prisma/gRPC
и не выполняет финансовые расчёты или сложную оркестрацию.
Controller вызывает application use case/service. Identity берётся из verified
request.user, не из body/userId, предоставленного клиентом. Access rules активируют Security.
DTO и errors
DTO — runtime class: TS interface не предоставляет validation metadata.
*.controller.ts и *.dto.ts остаются около HTTP boundary, в root компактного
module или presentation. DTO можно передать application boundary при совпадении
формы; отдельный Input с теми же полями не нужен. Domain не импортирует DTO:
например, чистые денежные расчёты используют Money, а Swagger — MoneyDto.
Нормализованная форма input нужна только при смысловом отличии от wire contract;
выбор suffix принадлежит Architecture.
ValidationPipe уже настроен в configureApp (transform, whitelist).
Не обещай rejection неизвестных fields: forbidNonWhitelisted не включён.
Для query numbers/arrays выбирай явное преобразование и валидаторы, как в
operations DTO. Swagger metadata
описывает те же required/optional/nullable/enum/range значения.
Используй типизированные response DTO, ApiOkResponse/другой фактический status
и существующий ApiProblemResponses. Prisma model не является public contract:
response выбирает поля явно. Stable codes, RFC 9457 профиль и mapping принадлежат
Errors.
Безопасный путь: используй exception и общий filter, а не локальный
res.status(...).json(...). Исключение — транспортная операция вроде cookie;
следуй существующему auth controller с passthrough и явно заданным status.
Пример и проверка
Prefix /api/v1 задаёт configureApp. Route/status/request/response/OpenAPI
change — изменение публичного backend contract; несовместимое изменение требует
согласованного перехода consumers, а не незаметной правки DTO. Новый API version
не вводи для внутреннего refactor.
Pagination сохраняет contract endpoint: operations использует opaque cursor, limit и DTO bounds. Не заменяй cursor offset/page и не добавляй global pagination helper ради первого endpoint. Новая pagination явно определяет порядок, границу страницы и end-of-list; reused cursor не должен менять filters/owner.
Operations controller показывает guard, user.sub, DTO query и service delegation. Для нового field обновляй Nest DTO/metadata и публикуемый OpenAPI artifact. Потребители получают публичный контракт независимо от внутреннего устройства API.
Проверь happy path и применимые invalid input/access/not-found/domain/upstream
errors на boundary, где они возникают. Unit вызов controller не запускает pipes,
guards или serialization. npm run test:openapi-contract проверяет schema parity,
но не поведение invalid request; выбирай соответствующий test по
Testing. Финальный gate не заменяет semantic review ошибок.
Источник контракта
Nest DTO/controllers/Swagger metadata определяют публичный HTTP API.
npm run openapi:generate собирает backend и записывает корневой openapi.json.
Nest preview читает metadata без запуска HTTP-порта, провайдеров, БД и T-Bank;
команда не требует deployment environment. Artifact исключён из Git.
При изменении API обнови DTO/metadata и выполни генерацию. Потребители получают
artifact отдельно; backend не читает их репозитории. test:openapi-contract
сравнивает вывод генератора с runtime schema configured app во временном каталоге.
Проверка подтверждает правильность генерации, но без versioned baseline не
выявляет breaking change относительно предыдущего выпуска. Для такого изменения
согласуй переход consumers и проверь relevant HTTP behavior.
HTTP prefix — /api/v1; Swagger доступен согласно src/config/swagger.config.ts.
Общий error response — application/problem+json со status и публичным code.
Validation требует 400 / VALIDATION_ERROR и errors: [{ pointer, detail }].
ValidationPipe сохраняет структурированные field errors без target/value,
а filter формирует JSON pointers, включая вложенные поля. Schema parity не
доказывает правильность errors; изменения проверяются через реальный HTTP pipeline.