# OpenSpec Change: enterprise-api-shared - **Change ID**: enterprise-api-shared - **Package**: `@suaveplan/api-shared` - **Category**: api/framework - **Target path**: `api/framework/api-shared` - **Status**: PROPOSED - **Date**: 2026-04-24 - **Reference spec**: `/mnt/s/web/suaveplan/enterprise/api-shared.md` --- ## Summary Deliver `@suaveplan/api-shared` on the genesis branch from scratch at enterprise quality. The package provides shared utilities, middleware factories, and types consumed by every `@suaveplan/api-plugin-*` package: response helpers (success/error envelopes, pagination), middleware factories (request-id, correlation-id, tenant-context, request-logging), Zod schema utilities (paginated query parsing, sort/filter normalisation), and typed Hono context extensions. Genesis adds structured errors, OTel instrumentation, `@suaveplan/logger` integration, and a full benchmark suite. --- ## Current-state audit (genesis) The package does not exist on genesis yet — fresh build. No prior source, no test results, no coverage data. --- ## Available workspace deps on genesis | Package | Role | |---|---| | `@suaveplan/error` (`workspace:^`) | `ApiSharedError` base + error codes | | `@suaveplan/types` (`workspace:^`) | `LoggerLike`, `EventBusLike` | | `@suaveplan/logger` (`workspace:^`) | Request-logging middleware | | `@suaveplan/api` (`workspace:^`) | `PluginContext` type, `HonoApp` | | `@suaveplan/api-schemas` (`workspace:^`) | Pagination / sort / filter Zod schemas | | `hono` (`catalog:server`) | Middleware type + context | | `@hono/zod-openapi` (`catalog:server`) | Typed route helpers | | `zod` (`catalog:forms`) | Schema validation | | `@opentelemetry/api` (`catalog:observability`) | Spans + metrics | | `tslib` (`catalog:build`) | Runtime helpers | --- ## Public API surface ### Response helpers ```ts function successResponse(data: T, meta?: ResponseMeta): ApiSuccessResponse function errorResponse(error: SuaveplanError): ApiErrorResponse function paginatedResponse(items: T[], pagination: PaginationMeta): ApiPaginatedResponse function noContentResponse(): Response // 204 ``` ### Middleware factories ```ts function requestIdMiddleware(): MiddlewareHandler // X-Request-ID header inject + propagate function correlationIdMiddleware(): MiddlewareHandler // X-Correlation-ID propagate function tenantContextMiddleware(): MiddlewareHandler // extract tenantId into Hono context function requestLoggingMiddleware(logger: LoggerLike): MiddlewareHandler function errorHandlerMiddleware(): MiddlewareHandler // converts SuaveplanError → RFC 7807 ``` ### Schema utilities ```ts function parsePaginationQuery(query: unknown): PaginationQuery function parseSortQuery(query: unknown, allowedFields: string[]): SortQuery function parseFilterQuery(query: unknown, allowedFields: string[]): FilterQuery ``` ### Types ```ts interface ApiSuccessResponse { success: true; data: T; meta?: ResponseMeta } interface ApiErrorResponse { success: false; error: ApiErrorEnvelope } interface ApiPaginatedResponse extends ApiSuccessResponse { pagination: PaginationMeta } interface PaginationMeta { page: number; pageSize: number; total: number; totalPages: number } interface ResponseMeta { requestId?: string; timestamp?: string; [key: string]: unknown } ``` ### Error codes ```ts type ApiSharedErrorCode = | "API_SHARED_INVALID_PAGINATION" | "API_SHARED_INVALID_SORT" | "API_SHARED_INVALID_FILTER" | "API_SHARED_MISSING_TENANT" ``` --- ## Genesis additions 1. **RFC 7807 Problem+JSON** error handler middleware — converts `SuaveplanError` to structured problem detail body. 2. **OTel** — `requestLoggingMiddleware` records `http.request_duration_ms` histogram; correlation-id propagated as span attribute. 3. **Zod schemas** for all public options (pagination, sort, filter) exported for downstream reuse. 4. **`@suaveplan/api-schemas` delegation** — `parsePaginationQuery` wraps `@suaveplan/api-schemas`' `PaginationQuerySchema`. 5. **Benchmark suite** measuring middleware chain overhead. --- ## File layout ```text api/framework/api-shared/ package.json tsconfig.json vitest.config.ts src/ index.ts constants/index.ts types/ common.ts common.md errors/ api-shared-errors.ts api-shared-errors.md api-shared-errors.test.ts index.ts responses/ response-helpers/ response-helpers.ts response-helpers.md response-helpers.test.ts index.ts middleware/ request-id/ request-id.ts request-id.md request-id.test.ts index.ts correlation-id/ correlation-id.ts correlation-id.md correlation-id.test.ts index.ts tenant-context/ tenant-context.ts tenant-context.md tenant-context.test.ts index.ts request-logging/ request-logging.ts request-logging.md request-logging.test.ts index.ts error-handler/ error-handler.ts error-handler.md error-handler.test.ts index.ts schemas/ pagination/ pagination.ts pagination.md pagination.test.ts index.ts sort-filter/ sort-filter.ts sort-filter.md sort-filter.test.ts index.ts __benchmarks__/ middleware.bench.ts tests/ integration.test.ts ``` --- ## Impact Every `api-plugin-*` package imports from `@suaveplan/api-shared`. This package must be published before any plugin can be built. Prerequisites: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/logger`, `@suaveplan/api`, `@suaveplan/api-schemas`.