# API Documentation Workflow (NestJS → OpenAPI → Next.js)

Treat the OpenAPI spec generated by NestJS as the single source of truth, and have the Next.js side consume types and clients generated from it. Hand-transcribing or duplicating the spec is forbidden — this structurally prevents both "docs drift from implementation" and "frontend/backend type drift."

## Principles

1. **NestJS decorators are the single source of truth for API documentation.** Never hand-transcribe the API spec into a separate document.
2. **Hand-writing request/response types on the Next.js side is forbidden.** Always import the generated types.
3. Never hand-edit generated artifacts (`openapi.json`, generated clients). If something needs to change, change the decorators instead.

## Required annotations on the NestJS side

Every public endpoint must include the following (via `@nestjs/swagger`):

| Decorator | Requirement |
|---|---|
| `@ApiTags` | Tag each controller with a resource name, used for grouping in the reference. |
| `@ApiOperation` | `summary` is required (written in the project's designated language). Add `description` where useful. |
| `@ApiResponse` | Document success responses plus business errors (404, 409, 422, etc.) along with the conditions that trigger them. |
| `@ApiProperty` | Required on every DTO property. Include `description` (in the designated language) and, where possible, `enum`/`example`. |

- To reduce missed annotations, use the `@nestjs/swagger` CLI plugin (which infers metadata from type information) where practical. Even then, write `description` explicitly.
- Keep validation constraints (class-validator) in sync with the `@ApiProperty` constraints (required / nullable / enum).

## Generating OpenAPI output

- Provide a dedicated script (e.g., `npm run openapi:generate`) that produces `openapi.json`, and **commit the generated output to the repository**.
- Why commit it: API changes become visible as a diff in the PR, and it gives CI and client generation a fixed baseline to compare against.
- Standardize on a generation method that doesn't depend on the server actually running (bootstrap the app and write `SwaggerModule.createDocument` output to a file) — see the docs-site skill for the procedure.

## Generation on the Next.js side

- Use either `openapi-typescript` (types only) or `orval` (types plus client functions) as the generator, and standardize on one per project.
- Output generated code to `src/generated/`, and make the **no hand-editing** rule explicit via a README in that directory or ESLint configuration.
- All API calls must go through generated types and clients. Casting a raw `fetch` response with `as` to a hand-written type will be flagged in review as HIGH severity (it breaks the generated contract).

## Freshness checks in CI

CI should verify the following two conditions and fail the build on any diff (see the docs-site skill for a reference implementation):

1. Regenerate `openapi.json` and confirm there's no diff against the committed version (catches decorator changes that weren't regenerated).
2. Regenerate the client/types and confirm there's no diff against the committed version (catches generated artifacts that fell out of sync).

## Breaking changes

- Breaking changes — removing fields, changing types, making optional fields required — must follow your API's compatibility procedures (versioning, staged deprecation). See the api-design skill for the decision criteria.
