Repository navigation
feat(api): add OpenAPI contract validation - #1253
Conversation
The OpenAPI document is built at runtime from @nestjs/swagger decorators and served at /api/docs, and nothing checks it. Across 37 controllers a contract defect — a duplicated operationId, an undeclared path parameter, a missing 2xx response — ships silently and surfaces as a broken generated SDK or documentation that does not match the API. Adds validateOpenApiContract(), a pure function over a document object, so the rules are testable without booting the application: - errors (break consumers): openapi-version, info-title, info-version, paths-present, operation-id-present, operation-id-unique, responses-documented, success-response, path-parameter-declared, path-parameter-used, path-parameter-required, request-body-content - warnings (documentation quality): servers-declared, operation-tagged, tag-declared, tag-used, operation-summary, no-body-on-get, required-response - opt-in: operation-description The severity split is what makes this adoptable — it can gate CI today without first fixing every missing summary across 37 controllers. Also adds a CLI (validate-openapi.ts, exit 0/1/2), 40 tests, and docs. Closes MDTechLabs#1248
|
@Cybermaxi7 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
|
Heads-up on the red The
None of the 18 lint errors are in Happy to fix those conflict markers in a separate PR if that would help — it looked like it wanted to be its own change rather than something buried in a feature branch. |
Closes #1248
The problem
The OpenAPI document is built at runtime from
@nestjs/swaggerdecorators inapps/api/src/main.tsand served at/api/docs. Nothing checks it.Across 37 controllers that means a contract defect ships silently and surfaces somewhere expensive:
operationIdproduces colliding method names in a generated SDKWhat this adds
validateOpenApiContract(document, options)— a pure function over a document object, so every rule is testable without booting the application.Errors — these break consumers
openapi-versionopenapipresent and 3.xinfo-title,info-versioninfofieldspaths-presentoperation-id-presentoperationIdoperation-id-uniqueresponses-documentedsuccess-responsedefaultdoes not count)path-parameter-declared{param}has a matching parameterpath-parameter-usedpath-parameter-requiredrequest-body-contentWarnings — documentation quality
servers-declared,operation-tagged,tag-declared,tag-used,operation-summary,no-body-on-get,required-responseOpt-in
operation-description, behind--require-descriptions.Why the severity split matters
Anything that breaks a consumer is an error. Anything that merely degrades documentation is a warning.
That split is what makes this adoptable: it can be wired into CI today without first fixing every missing summary across 37 controllers. Tighten it over time by promoting warnings.
CLI
Exit codes:
0valid,1contract errors,2usage or parse failure — so it can gate CI directly.Not wired into CI by default, because it needs a serialised spec and where that gets produced is a repo-level decision.
docs/OPENAPI_CONTRACT_VALIDATION.mdcovers how to serialise the document and the workflow step to add once it is.Testing
40 tests covering every rule, both severities, the
default-is-not-success case, multi-parameter paths, non-HTTP-method path keys, report formatting, and CLI argument parsing.All passing.
eslint apps/api/src/openapi/clean.Scope
Four new files, additive only. No existing file is modified, so there is nothing here that can regress current behaviour.