HAProxy UI ships a script that cross-references the official Dataplane v3 OpenAPI specification against the Zod schemas in src/lib/api/types.ts. It answers one question continuously: does the app model the whole schema, or has it drifted?
Running it
node scripts/coverage.mjs # offline, uses the cached specnode scripts/coverage.mjs --refresh # refetch the spec firstpnpm coverage # same as the first form
Current status: 287/287 spec fields modeled, 0 gaps.
What it checks
Six models are compared against the spec, because those are the six the app owns:
const MODELS = ['global', 'defaults', 'frontend', 'backend', 'bind', 'server'];
For each, it walks the spec’s definitions → <model> → properties block and compares each field against the Zod schema. Nested properties: blocks (inside array-of-objects such as cpu_maps) are skipped so JSON-Schema keywords like items, type and pattern are not miscounted as model fields.
The gate
The script exits 1 when any model has unmodeled spec fields, or when the modelled set drifts from the spec. It runs in CI on every build:
# .github/workflows/build.yml- run: pnpm run coverage
This turns “did we forget a field?” from a question someone has to remember to ask into a build failure. When the Dataplane API adds a field, the build breaks and names it.
Spec source and caching
The spec is fetched from the haproxytech/dataplaneapi-specification repository and cached at .coverage/haproxy_spec.yaml. The offline mode is what makes the gate deterministic in CI; --refresh updates the cache when the upstream spec changes.
Why this matters more than a test count
Passing unit tests prove the code does what it was written to do. They say nothing about whether the code matches the API it targets. This gate is the only thing in the build that notices when the API changes underneath the app — and for a config editor, silently not modelling a field is a correctness bug, not a missing feature. An unmodelled field on a resource can be deleted by a PUT (see API Reference), so gaps here are data-loss risks, not gaps in convenience.
Full verification command set
All four must be green before a change ships:
pnpm lint # prettier --check . && eslint . (0 errors)pnpm check # svelte-check (0 errors, 0 warnings)pnpm test # vitest single-run (230 passed, 1 skipped)pnpm coverage # spec cross-reference (287/287, exit 0)