# `@/lib/api`

Shared response envelope contracts for HTTP route handlers.

## Owner

Platform Engineering.

## Purpose

Every public (`/api/v1/*`) handler returns the same envelope. This module is the
single source of truth for those shapes — the OpenAPI v1 spec
(`openapi/v1/openapi.json`) mirrors them under
`components.schemas.{Envelope,ListEnvelope,ErrorEnvelope}`.

## Public API

```ts
import {
  ok, list, err,
  unauthorized, forbidden, notFound, badRequest, serverError,
  readPagination,
  type ApiErrorCode,
} from '@/lib/api'
```

| Helper | Returns |
|---|---|
| `ok(data, init?)` | `2xx { data }` |
| `list(data, meta, init?)` | `2xx { data, meta: { page, limit, total } }` |
| `err(msg, status, code?, details?)` | error envelope at given status |
| `unauthorized()` / `forbidden()` / `notFound()` / `badRequest()` / `serverError()` | shorthands |
| `readPagination(searchParams)` | `{ page, limit, offset }` clamped to `[1, MAX]` |

## Compatibility contract

`/api/v1/*` shapes are versioned. Any breaking change to `data`, `meta`, or
`error` envelope structure requires a new version prefix (`/api/v2/...`).
Internal routes (`/api/admin/*`, `/api/owner/*`, `/api/demo/*`) are NOT bound
by the v1 compatibility contract — see `docs/foundation/api-contract.md`.

## Dependencies

- Circle 2 (Platform). No domain dependencies. Imports `next/server` only.

## Tests

Covered indirectly via route handler tests. Add unit tests when extending
`readPagination` or the error helpers.
