openova/docs
hatiyildiz 0887073735 feat(wizard): #175 — product-family dependency model + transitive-mandatory promotion
Two interlocking fixes for StepComponents per operator feedback (#175):

1. **Transitive-mandatory promotion** (Fix A) — at module-load time walk
   the dependency graph from every mandatory-tier component and promote
   every reached component to mandatory. cnpg + valkey are lifted from
   recommended → mandatory because Harbor / Gitea / PowerDNS / Keycloak
   (mandatory or transitively mandatory) cannot run without them. They
   no longer surface in Tab 1 ("Choose Your Stack"); they appear in Tab 2
   ("Always Included") under the FABRIC product section.

2. **Product-family model** (Fix B) — new `Product` type in
   `componentGroups.ts` with `tier`, `components`, `familyDependencies`,
   and `cascadeOnMemberSelection`. CORTEX is flagged as
   cascade-on-member-selection (operator: "BGE alone doesn't have much
   meaning unless we have Cortex... when chosen the entire family needs
   to be selected"). Selecting any CORTEX member or Specter (whose deps
   reach into CORTEX) cascades the rest of CORTEX plus FABRIC (CORTEX's
   familyDependency). À-la-carte products (FABRIC, RELAY) keep
   independent member selection.

UX additions:
- Product header per family in Tab 1 with "Select entire X family" CTA
  (selectable via product-cta-<id> testid)
- Cascade-add toast surfaces both component-deps and family additions
- Cascade-remove confirmation modal lists every dependent that will go
- All operator-visible strings sourced from new
  `stepComponentsCopy.ts` i18n module — no inline literals in JSX

Store actions: `addProduct(id)` / `removeProduct(id)` plus a
member-selection cascade in `addComponent` that respects the product
flag. Mandatory components are protected from any cascade-remove path.

Documentation: `docs/PRODUCT-FAMILIES.md` describes the dependency
model, every product entry, and worked examples (Specter, BGE, Harbor,
ClickHouse).

Vitest: 43 new test cases including transitive-promotion verification,
cross-product cascade, product CTA flow, and i18n wiring. All 146
tests pass; typecheck + build green.

Closes #175.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 09:43:00 +02:00
..
ARCHITECTURE.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
AUDIT-PROCEDURE.md docs(component-count): update 53 → 56 anchors after Pass 105 (spire + nats-jetstream + sealed-secrets) 2026-04-28 13:48:24 +02:00
BLUEPRINT-AUTHORING.md docs(seaweedfs+guacamole): replace MinIO with SeaweedFS as unified S3 encapsulation; add Guacamole to bp-relay 2026-04-28 10:23:46 +02:00
BUSINESS-STRATEGY.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
COMPONENT-LOGOS.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
DEMO-RUNBOOK.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
FRANCHISE-MODEL.md docs(franchise),test(billing): voucher CRD propagation invariant 2026-04-28 13:59:31 +02:00
GLOSSARY.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
IMPLEMENTATION-STATUS.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
INVIOLABLE-PRINCIPLES.md docs(principles): canonical INVIOLABLE-PRINCIPLES.md — 10 non-negotiable rules 2026-04-28 13:28:11 +02:00
MULTI-REGION-DNS.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
NAMING-CONVENTION.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
ORCHESTRATOR-STATE.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
PERSONAS-AND-JOURNEYS.md docs(unified-repo-model): collapse SME and corporate to one shape — Application = Gitea Repo 2026-04-28 10:13:02 +02:00
PLATFORM-POWERDNS.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
PLATFORM-TECH-STACK.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
PRODUCT-FAMILIES.md feat(wizard): #175 — product-family dependency model + transitive-mandatory promotion 2026-04-29 09:43:00 +02:00
PROVISIONING-PLAN.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
RUNBOOK-PROVISIONING.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
SECURITY.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
SOVEREIGN-PROVISIONING.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
SRE.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
TECHNOLOGY-FORECAST-2027-2030.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
VALIDATION-LOG.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00