PSA/docs/openapi/registry-integration.md
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

4.4 KiB

OpenAPI Registry Integration Plan

This document captures the scaffolding introduced for the new OpenAPI workflow and how it lines up with the comprehensive plan dated 2025-09-18.

Architecture Overview

  • ApiOpenApiRegistry wraps @asteasolutions/zod-to-openapi and centralises route/component registration. It enforces edition-aware filtering so we can emit CE or EE specifications from the same metadata.
  • Shared components live in server/src/lib/api/openapi/components.ts. The base module currently registers API key security plus the canonical error envelope; additional shared schemas should be added here.
  • Existing route generators (for now registerServiceCategoryRoutes) sit under server/src/lib/api/openapi/routes/**. Each registrar receives the shared component handles (e.g. ErrorResponse) and registers one or more routes.
  • buildBaseRegistry in server/src/lib/api/openapi/index.ts wires everything together. Controllers will eventually expose registerOpenApi(registry) helpers that are imported here.
  • registerInventoryBackfillRoutes hydrates placeholder operations for every path discovered in docs/openapi/route-inventory.json, so the generated spec now lists the full surface area (with x-placeholder: true until real metadata replaces it).
  • sdk/scripts/generate-openapi.ts now consumes the registry, accepts CLI overrides (--edition, --output, --version, --formats, --title, --description), and writes edition-specific JSON + YAML artifacts (alga-openapi.<edition>.{json,yaml}). CE remains mirrored to the legacy alga-openapi.{json,yaml} files for backward compatibility.

Controller Integration Pattern

  1. Add registerOpenApi export to each controller module:
    import { registerTicketSchemas } from '@/lib/api/schemas/ticket';
    import { ApiOpenApiRegistry } from '@/lib/api/openapi';
    
    export function registerOpenApi(registry: ApiOpenApiRegistry) {
      const { ErrorResponse } = registerTicketSchemas(registry);
    
      registry.registerRoute({
        method: 'get',
        path: '/api/v1/tickets',
        summary: 'List tickets',
        tags: ['Tickets'],
        edition: 'both',
        security: [{ ApiKeyAuth: [] }],
        request: { query: ticketListQuerySchema },
        responses: {
          200: { description: 'Tickets', schema: ticketListResponseSchema },
          401: { description: 'Authentication failed.', schema: ErrorResponse },
        },
        extensions: {
          'x-rbac-resource': 'ticket',
          'x-tenant-header-required': true,
        },
      });
    }
    
  2. Update the registry builder to import each controller registrar (registerTicketRoutes(registry, deps) or the inline registerOpenApi export).
  3. Ensure canonical schemas: controllers should rely on the Zod definitions inside server/src/lib/api/schemas/**. The schema coverage report (docs/openapi/schema-coverage.md) lists 56 routes currently missing canonical coverage; those handlers should be refactored first.
  4. Edition annotations: mark EE-only routes with edition: 'ee' so the generator automatically omits them from the CE artifact (and vice versa).

Supporting Automation

  • scripts/generate_route_inventory.py emits docs/openapi/route-inventory.{json,csv} (416 routes discovered). This underpins testability for "registry covers all routes" checks in CI.
  • scripts/analyze_schema_coverage.py emits docs/openapi/schema-coverage.{json,md}. Use this to drive Phase 1 backlog: every route without canonical schemas must be addressed before registry adoption.
  • Future work: add a Vitest suite that loads the registry and asserts parity against the CSV inventory (Phase 2 exit criteria).

Next Steps (per comprehensive plan)

  1. Finish Phase 1: implement/centralise Zod schemas for the 56 direct handlers highlighted in schema-coverage.md.
  2. Phase 2 kick-off: progressively add registerOpenApi exports to controllers, feeding them into buildBaseRegistry. Gate progress with an inventory parity test.
  3. Phase 3: extend sdk/scripts/generate-openapi.ts with CI guardrails (git diff check) and wire npm scripts (openapi:generate:ce, openapi:generate:ee).
  4. Phase 4+: once registry coverage hits 100%, publish the CE/EE specs and add Redoc/Swagger UI exposure as outlined in the original plan.

Maintain the supporting docs (route-inventory.csv, schema-coverage.md) as living artifacts—regenerate them whenever routes or schemas change, and surface regressions via CI.