# Tasks — add-api-openapi ## 1. Scaffold - [ ] 1.1 Create `packages/api/api-openapi/` with `src/{registry,route-factory,schema-registry,merger,plugin-integration,error-codes,types}/` + `tests/setup/` - [ ] 1.2 `package.json` v0.1.0. Deps: `@suaveplan/error` `@suaveplan/api-plugin` `@suaveplan/api-schemas` `@suaveplan/types` `tslib`, `hono` `@hono/zod-openapi` (`catalog:server`), `zod` (`catalog:forms`), `@opentelemetry/api`. Dev: standard testing. ~8 subpath exports. - [ ] 1.3 tsconfigs + vite + vitest (100/100/100/100) + polyfills ## 2. Implementation - [ ] 2.1 `src/error-codes.ts` + `.md` + test — 3 OPENAPI.* codes + `OpenAPIError` - [ ] 2.2 `src/types/openapi.{ts,md,index.ts}` — `OpenAPIDocument`, `PathItem`, `Operation`, `OpenAPIInfo`, `OpenAPIServer`, `SecurityScheme`, `RegisteredRoute` - [ ] 2.3 `src/registry/registry.{ts,test.ts,md,index.ts}` — `OpenAPIRegistry` + `buildDocument()` + `applyTo(app)` - [ ] 2.4 `src/route-factory/route-factory.{ts,test.ts,md,index.ts}` — `RouteBuilder` + `route/GET/POST/PUT/PATCH/DELETE` + `StandardResponses` (widened) + `ErrorResponseSchema` (+ `successResponse/paginatedResponse/errorResponse`) - [ ] 2.5 `src/route-factory/route-factory.spec-conformance.test.ts` — `expectTypeOf` end-to-end inference - [ ] 2.6 `src/schema-registry/schema-registry.{ts,test.ts,md,index.ts}` — instance-based, no global; extend/partial/pick/omit on ZodObject - [ ] 2.7 `src/schema-registry/common-schemas.{ts,md}` — `CommonSchemas` (uuid/email/url/datetime/positiveInt/nonNegativeInt/page/limit/sortOrder) - [ ] 2.8 `src/merger/merger.{ts,test.ts,md,index.ts}` — `mergeOpenAPIDocuments`, `prefixPaths`, `filterPathsByTag`, `removeInternalRoutes` - [ ] 2.9 `src/plugin-integration/plugin-integration.{ts,test.ts,md,index.ts}` — `definePluginRoutes(routes, {app, registry, pluginName})` - [ ] 2.10 `src/index.ts` — named re-exports (incl. `BearerAuthScheme`, `ApiKeyScheme`) ## 3. Tests - [ ] 3.1 Co-located `*.test.ts` per spec scenario - [ ] 3.2 `src/api-openapi.spec-conformance.test.ts` — every OPENAPI.* thrown; no global singleton; `expectTypeOf` on RouteBuilder end-to-end - [ ] 3.3 `tests/integration/full-doc-roundtrip.test.ts` — real OpenAPIHono + real registry + 3 plugins registering routes → assert merged doc shape - [ ] 3.4 `tests/property.test.ts` — fast-check `mergeOpenAPIDocuments` associativity (`merge(a, b, c) === merge(merge(a, b), c)`) for arbitrary path sets - [ ] 3.5 `tests/dep-graph.test.ts` - [ ] 3.6 Runner imports + timeouts conventions ## 4. Documentation - [ ] 4.1 Sibling `.md` per impl - [ ] 4.2 `README.md` — RouteBuilder examples (basic + with auth + paginated), SchemaRegistry derivation patterns, mergeOpenAPIDocuments use cases, `definePluginRoutes` plugin pattern ## 5. Gates - [ ] 5.1 `bunx turbo lint typecheck test --filter=@suaveplan/api-openapi --force` - [ ] 5.2 Coverage 100/100/100/100 - [ ] 5.3 `bun scripts/openspec-conformance.ts @suaveplan/api-openapi` exit 0 - [ ] 5.4 Build green - [ ] 5.5 Banned-pattern + no `export *` + no direct runner imports ## 6. Archive - [ ] 6.1 Fold spec → `openspec/specs/api-openapi/spec.md` - [ ] 6.2 mv change → archive - [ ] 6.3 MANIFEST + STATUS refresh