Context
ResponseFormatInterceptor standardizes success payloads; ValidationExceptionFilter/PrismaExceptionFilter/AllExceptionsFilter emit { statusCode, message, ... } shapes with overlapping fields; DTOs throw BadRequestException at various shapes too.
Problem
Clients observe inconsistent error envelopes per module (array vs string message, presence of path/timestamp), making API SDKs fragile; docs API_VERSIONING doesn't specify the error contract.
Proposed approach
Define a single ErrorResponse contract (code, message, details, traceId - trace interceptor already sets x-trace-id), align the three filters + ValidationPipe exceptionFactory, and add an e2e that snapshots error shapes across representative routes.
Acceptance criteria
- All error responses share the documented envelope; snapshot test enforces it.
Context
ResponseFormatInterceptorstandardizes success payloads;ValidationExceptionFilter/PrismaExceptionFilter/AllExceptionsFilteremit{ statusCode, message, ... }shapes with overlapping fields; DTOs throwBadRequestExceptionat various shapes too.Problem
Clients observe inconsistent error envelopes per module (array vs string message, presence of
path/timestamp), making API SDKs fragile; docsAPI_VERSIONINGdoesn't specify the error contract.Proposed approach
Define a single
ErrorResponsecontract (code, message, details, traceId - trace interceptor already setsx-trace-id), align the three filters + ValidationPipe exceptionFactory, and add an e2e that snapshots error shapes across representative routes.Acceptance criteria