fix(api,codegen): ARCH-001-A — Phase 1 Orval codegen + 2 new CI guards (large diff)

Sprint 5 unified-master-audit closure. Pre-fix:

  - api/openapi.yaml: 7,788 LOC of hand-authored spec.
  - web/src/api/generated/: directory did NOT exist (the Phase-5
    scaffolding never had its first generation run).
  - scripts/ci-guards/openapi-codegen-drift.sh: skip-when-absent
    (line 33-39 — informational scaffold).
  - api/openapi.yaml info.version: '2.0.0', latest tag: v2.1.7
    (a 7-version drift between spec and ship).

Net effect: every new route required three coordinated edits (Go
handler, openapi.yaml, frontend client.ts), payload-level breaking
changes shipped unnoticed, and downstream API client integration
cost was permanent.

Phase 1 fix (the audit's literal scope):

  1. **Run Orval**, commit the generated tree. 316 files / ~1.8 MB
     under web/src/api/generated/, tags-split layout (one directory
     per OpenAPI tag), TanStack Query client mode. All output routes
     through web/src/api/mutator.ts which delegates to the existing
     fetchJSON in client.ts so auth/CSRF/401-event semantics stay
     in one place.

  2. **Fix two spec defects** the first orval run surfaced:
     - YAML duplicate-key bug at L77-89 — SCEP's description was
       misplaced under OIDC. Restored to its own tag entry.
     - Missing #/components/schemas/Error referenced by three
       operations. Aliased to the existing ErrorResponse schema.

  3. **Flip the codegen-drift guard from skip-when-absent to
     hard-gate.** A missing generated/ directory now fails the
     build with an actionable restore command. The existing
     regenerate-and-diff path stays as before.

  4. **New openapi-version-tag-parity CI guard.** Asserts
     openapi.yaml info.version equals the latest v* git tag. Falls
     back to api.github.com when the local clone is shallow.
     Bumped openapi.yaml info.version 2.0.0 → 2.1.7 in the same
     commit so the new guard greens out.

  5. **CI workflow** updated to fetch tags on the frontend job's
     checkout so the parity guard reads them locally (the GH API
     fallback still works but adds a network round-trip).

Verified locally:
  - openapi-codegen-drift.sh: clean (re-generation produces
    byte-identical tree to what's tracked).
  - openapi-version-tag-parity.sh: clean (2.1.7 == v2.1.7).
  - tsc --noEmit: exit 0 across the entire frontend (the
    generated tree's responseType field threaded through the
    mutator's CertctlFetchOptions cleanly).
  - Existing Vitest suite: 141/141 pass on the three sampled
    suites (AuthProvider + client + IssuerHierarchyPage).

Follow-on work (NOT in this commit):
  - Per-consumer migration: pages flip from client.ts imports to
    generated/ imports one at a time. Both styles share fetchJSON
    semantics, so the migration is incremental.
  - Server-side oapi-codegen handler stubs (Phase 2 from the
    audit's fix language) — separate sprint.

Closes ARCH-001-A.
This commit is contained in:
shankar0123
2026-05-16 05:19:22 +00:00
parent e1ab1db65a
commit 38f1200f26
322 changed files with 24588 additions and 8 deletions
+16 -2
View File
@@ -11,7 +11,11 @@ info:
Paginated list endpoints accept `page` (default 1) and `per_page` (default 50, max 500)
query parameters and return a standard envelope with `data`, `total`, `page`, and `per_page`.
version: 2.0.0
# ARCH-001-A closure (Sprint 5, 2026-05-16): info.version MUST track
# the latest `v*` git tag. The openapi-version-tag-parity.sh CI guard
# asserts this on every CI run. Bump in lockstep with the
# `git tag -a v* ...` command at release time.
version: 2.1.7
license:
name: BSL 1.1
url: https://github.com/certctl-io/certctl/blob/master/LICENSE
@@ -75,6 +79,7 @@ tags:
- name: EST
description: Enrollment over Secure Transport (RFC 7030)
- name: SCEP
description: Simple Certificate Enrollment Protocol (RFC 8894)
- name: Sessions
description: |
Server-side session management. Phase 13 Sprint 13.4 (ARCH-H1
@@ -86,7 +91,6 @@ tags:
Phase 13 Sprint 13.4 — authored against the Phase 9 Sprint 11
sibling-file handlers at internal/api/handler/auth_session_oidc_crud.go +
the JWKS-status surface at internal/api/handler/auth_users.go.
description: Simple Certificate Enrollment Protocol (RFC 8894)
paths:
# ─── Health & Auth ───────────────────────────────────────────────────
@@ -5931,6 +5935,16 @@ components:
request_id:
type: string
# ARCH-001-A closure (Sprint 5, 2026-05-16). Three operation
# responses (search `#/components/schemas/Error` in this file)
# reference a schema named "Error" — but only "ErrorResponse" was
# defined, so the orval codegen failed with
# MissingPointerError. Alias Error → ErrorResponse so the spec
# parses cleanly and the three offenders keep their stable
# response shape.
Error:
$ref: "#/components/schemas/ErrorResponse"
StatusResponse:
type: object
properties: