docs(api): document the response envelope (JSDoc + Swagger @ApiOkResponse examples)#490
Open
dorisadams wants to merge 1 commit into
Open
Conversation
…onse examples) Follow-up to MERIDIAN-CITY#488. Adds developer-facing documentation so consumers learn the {apiversion, result, data} envelope shape from the source and the OpenAPI spec at /api instead of discovering it at runtime. ### Files added - meridian-api/src/common/dto/envelope.dto.ts -- Swagger EnvelopeDto class with @ApiProperty decorators matching the runtime DataResponseEnvelope interface. `data` is described via oneOf covering object / array / string / number / integer / boolean / null. - meridian-api/src/common/decorators/api-envelope-response.decorator.ts -- @ApiEnvelopeResponse({ dataExample, status, description }) drops in for @ApiOkResponse on every controller method that returns success. Always emits @ApiExtraModels(EnvelopeDto) so the $ref resolves on first use, and derives `result` from the example's shape using the same rule the interceptor applies at runtime. ### Files modified - meridian-api/src/common/interceptors/data-response.interceptor.ts -- Adds JSDoc to API_VERSION, DataResponseEnvelope<T>, the class itself, intercept(), and transform(). transform() carries @returns + four @example blocks (array, single-object, primitive, null). intercept() and transform() carry @throws {never} to make the no-throw contract machine-discoverable. - meridian-api/src/main.ts -- DocumentBuilder().setDescription() now opens with a "## Response envelope" Markdown section explaining apiversion, result and data so consumers see the contract at the top of /api. - meridian-api/src/users/users.controller.ts - meridian-api/src/post/post.controller.ts - meridian-api/src/tweets/tweet.controller.ts - meridian-api/src/auth/auth.controller.ts -- Each success @apiresponse gets replaced with @ApiEnvelopeResponse and a representative dataExample. Error @apiresponse decorators are kept. Pre-existing unused imports (Put, ValidationPipe, UseGuards, SetMetadata, AccessTokenGuard, DefaultValuePipe, GetPostsParamDto) are removed to keep the diff ESLint-clean. - meridian-api/jest.setup.ts -- Adds a virtual jest.mock for the new envelope decorator module (and only the alias path that specs actually use) so existing specs can keep loading controller modules without pulling in the real Swagger metadata machinery. ### Out of scope - src/tag/tag.controller.ts has no Swagger decorators yet. - src/app.controller.ts is the trivial `/` hello-world route. - src/health/health.controller.ts returns a Terminus HealthCheckResult that is NOT wrapped in the envelope, so documenting it as envelope- wrapped would be a contract lie. ### Verification - `tsc -p tsconfig.build.json --noEmit` -> clean. - `eslint` on the touched files -> clean. - `jest src/auth/auth.controller.spec.ts` -> 6 / 6 pass. Follow-up to MERIDIAN-CITY#488 and MERIDIAN-CITY#489.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #488 and #489. Adds developer-facing documentation so consumers learn the
{ apiversion, result, data }envelope shape from the source and from the OpenAPI spec at/apiinstead of discovering it at runtime.What this PR adds
1. JSDoc on the interceptor (
src/common/interceptors/data-response.interceptor.ts)@returns+ four@exampleblocks ontransform()covering array, single-object, primitive, and null payloads.@throws {never}on bothintercept()andtransform()to make the no-throw contract machine-discoverable.2. Swagger
@ApiOkResponseexamples (src/common/decorators/api-envelope-response.decorator.ts+src/common/dto/envelope.dto.ts)EnvelopeDtoSwagger model with@ApiPropertydecorators matching the runtimeDataResponseEnvelope<T>interface (datais described viaoneOfover object / array / string / number / integer / boolean / null).@ApiEnvelopeResponse({ dataExample, status, description })decorator that drops in for@ApiOkResponseon every controller method that returns success. It:@ApiExtraModels(EnvelopeDto)so the$refresolves on first use.getSchemaPath(EnvelopeDto)(idiomatic NestJS, honors custom OpenAPI prefixes).examplepayload whoseresultis derived fromdataExampleusing the same rule the interceptor applies at runtime — so docs and code cannot drift.3. Application per controller (
users,post,tweets,auth)@ApiResponsedecorator was replaced with@ApiEnvelopeResponse(...)carrying a representativedataExamplefor that route.@ApiResponsedecorators (4xx) are kept as-is.4. Site-wide mention in Swagger description (
src/main.ts)DocumentBuilder().setDescription()now opens with a "## Response envelope" Markdown section explainingapiversion,result, anddataso consumers see the contract at the top of/apieven before drilling into a tag.5. Test-suite plumbing (
jest.setup.ts)jest.mockfor the new envelope decorator module (alias path only — the relative-path variant that no spec ever uses was dropped per code-review feedback) so existing specs can keep loading controller modules without pulling in the real Swagger metadata machinery.Out of scope
src/tag/tag.controller.tshas no Swagger decorators — added as a follow-up.src/app.controller.tsis the trivial/hello-world route.src/health/health.controller.tsreturns a TerminusHealthCheckResultshape that is not wrapped in the envelope, so documenting it as envelope-wrapped would be a contract lie.Verification
tsc -p tsconfig.build.json --noEmit-> clean.eslinton every touched file -> clean.jest src/auth/auth.controller.spec.ts-> 6/6 pass (the spec exercises the new envelope decorator import chain via the controller).Follow-up chain
{apiversion, result, data}envelope).Fixes the user request from the dorisadams follow-up flow.