Files
backend/.ai/conventions/http-api.md
ksv741 4796d9d3f0
Backend security / security (push) Successful in 8s
Backend verify / verify (push) Successful in 11m9s
Conventional commits / commits (pull_request) Successful in 28s
Backend security / security (pull_request) Successful in 7s
Backend verify / verify (pull_request) Successful in 10m38s
fix: harden auth and investment synchronization
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.
2026-09-27 14:09:05 +03:00

6.8 KiB
Raw Permalink Blame History

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.