Refactors /sovereign/provision/$id/infrastructure to match the founder's
wizard mental model:
Org/Sovereign
└─ Topology pattern (SOLO | HA-PAIR | MULTI-REGION | AIR-GAP)
└─ Region(s)
└─ Physical Cluster(s)
├─ vClusters [DMZ · RTZ · MGMT]
├─ LBs / peerings / firewalls
└─ Worker nodes / pools
The 4 tabs (Topology / Compute / Storage / Network) are filtered lenses
over ONE backend response. Topology view is the default landing,
hierarchical 4-depth (Cloud → Region → Cluster → vCluster), and the
detail panel slides in on click. Click a cluster to zoom — vClusters of
that cluster un-dim.
Per founder spec, every CRUD action is delivered through a delta-wizard
modal that creates a Job entry. Modals shipped:
• AddRegionModal (3-step, re-uses StepProvider in mode='add-region')
• AddClusterModal (re-uses StepTopology in mode='add-cluster')
• AddVClusterModal · AddNodePoolModal · ScalePoolModal · ChangeSKUModal
• AddLBModal · AddPeeringModal
• EditFirewallRulesModal · EditDNSRecordsModal
• NodeActionConfirm (cordon / drain / replace)
• DeleteCascadeConfirm (with cascade preview)
NEW pure layout function `lib/topologyLayout.ts` produces the layered
graph (no force-directed, no reactflow). Typed CRUD client wrappers in
`lib/infrastructure-crud.ts`. Synthetic fixture under
`test/fixtures/infrastructure-topology.fixture.ts` so the page is
navigable when the live `/infrastructure/topology` backend isn't
deployed yet.
Header gains a per-Sovereign switcher fed by GET /v1/deployments.
Wizard step components (StepProvider, StepTopology) get a `mode` prop
for in-place reuse — they are NOT forked.
Tests: 51 infra tests pass (10 InfrastructurePage + 6 Topology +
5 Compute + 4 Storage + 6 Network + 11 topologyLayout + 9 fixture
shape). Wizard test coverage (135 tests) unchanged. Cosmetic guards
extended for layered canvas, side panel, and Sovereign switcher.
Co-authored-by: hatiyildiz <hatice.yildiz@openova.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>