* fix(api): EPIC-6 iter-6 target-state Continuum DR endpoints
Adds the singular `/continuum/{name}` route family + 5 new endpoints
the qa-loop matrix asserts on (TC-312, TC-324, TC-326, TC-329, TC-330,
TC-331, TC-332, TC-333, TC-334, TC-335, TC-339, TC-343):
GET /api/v1/sovereigns/{id}/continuum/{name} enriched response w/ flat status fields
PUT /api/v1/sovereigns/{id}/continuum/{name} patch rpoSeconds/rtoSeconds/autoFailover
GET /api/v1/sovereigns/{id}/continuum/{name}/stream SSE: walLagSeconds + currentPrimary tick
POST /api/v1/sovereigns/{id}/continuum/{name}/switchover/preview dry-run: estimatedDuration + blockingChecks[]
POST /api/v1/sovereigns/{id}/continuum/{name}/switchover singular alias
POST /api/v1/sovereigns/{id}/continuum/{name}/failback singular alias
POST /api/v1/sovereigns/{id}/continuum/{name}/failback/approve singular alias
GET /api/v1/fleet/continuum items envelope of all Continuum CRs
GET /api/v1/fleet/sovereigns/{id}/dr-summary per-Sov DR rollup
Original plural `/continuums/` routes stay live for back-compat — both
paths work. Per ADR-0001 §2.7 the Continuum CR is still the source of
truth (PUT patches spec.rpoSeconds + spec.rtoSeconds; the controller
reconciles). Per INVIOLABLE-PRINCIPLES #5 PUT requires operator tier
on the Application (REUSES applicationInstallCallerAuthorized). Preview
is read-only with the same gate as GET.
The enriched GET response surfaces the matrix-required flat fields
(currentPrimary, walLagSeconds, lastSwitchoverDurationSeconds,
dnsObservation, rpoSeconds, rtoSeconds, replicas[]) so the UI's
StatusPanel and the matrix asserts both resolve without parsing nested
status. Source of truth remains the Continuum CR's spec/status.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(chart): EPIC-6 iter-6 target-state Continuum DR fixtures + CRDs
bp-catalyst-platform 1.4.97 → 1.4.99
bp-crossplane-claims 1.1.1 → 1.1.2
Adds the chart-side pieces of the iter-6 EPIC-6 (Continuum DR) target-
state matrix that the catalyst-api singular-route family (PR #1222)
depends on:
- NEW CRD `cnpgpairs.dr.openova.io` (TC-304) — Phase-2 cnpg-pair-
controller will own reconciliation; CRD lands now so the catalyst-
api fleet handler + UI can list/watch immediately.
- NEW CRD `pdms.dr.openova.io` (TC-318) — represents one PowerDNS
Manager instance in the DNS-quorum lease witness ring; cmd/pdm
will reconcile.
- NEW Continuum CR fixture `cont-omantel` in qa-omantel ns + status
seeder Job (TC-305, TC-313, TC-317, TC-327, TC-328, TC-341).
- NEW CNPGPair CR fixture `qa-cnpg` + status seeder Job (TC-310,
TC-311, TC-314).
- NEW 3 PDM CR fixtures (pdm-1/2/3) + ClusterRole-bound seeder Job
that publishes `_continuum-quorum.cont-omantel.openova.io` TXT
record + per-PDM A records to the omantel PowerDNS via the
standard /api/v1/servers/localhost/zones API (TC-318/319/320/321).
- NEW ScheduledBackup + Backup fixtures + status seeder
(TC-337/338).
- tier-operator ClusterRole gains continuums/cnpgpairs/pdms verbs
(get/list/watch/update/patch) + read-only on
postgresql.cnpg.io clusters/backups/scheduledbackups (TC-344).
- bootstrap-kit template values surface qaFixtures.enabled +
namespace/appName/continuumName/cnpgPairName/regions/pdmZone via
envsubst with sane fallbacks; flipped on per-Sov via
QA_FIXTURES_ENABLED=true on the qa-loop Sovereigns only —
production Sovereigns keep the default `false`.
Per ADR-0001 §2.7 the CRs remain the source of truth — the seeder Jobs
are post-install hooks that patch status to known-good fixture values
ONCE; the production controllers (continuum-controller, cnpg-pair-
controller in flight by Phase-2 agent) overwrite on next reconcile.
Per INVIOLABLE-PRINCIPLES #4 every fixture name is values-overridable
and gated on qaFixtures.enabled.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>