C4 Architecture Diagrams Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax.
Goal: Author a full C4 model (L1 Context → L2 Container → L3 Component → L4 Code, + Dynamic sequence flows) as Mermaid diagrams in a new architecture/ subtree of the Docusaurus developer portal, as a living source of truth.
Architecture: Hand-authored Markdown pages under app/test-gallery/authored/developer/architecture/ (the existing build copies authored/developer/** → docs/developer/** recursively). C4 boundaries rendered with flowchart/graph TB + subgraphs + a shared classDef legend; dynamic flows with sequenceDiagram. Today's prose architecture.md is folded into the subtree index.md.
Tech Stack: Markdown, Mermaid (via @docusaurus/[email protected], already wired). NO Dart/Flutter.
Global Constraints
- Markdown/Mermaid only — no
fvm/Dart. Run build steps fromapp/test-gallery/. - Honest exit codes:
<cmd> > /tmp/t.txt 2>&1; echo "EXIT=$?"; inspect the file. Build passes only onEXIT=0+[SUCCESS] Generated static files in "build". - Mermaid renders client-side, so
npm run buildgreen does NOT prove a diagram parses. Everymermaidblock MUST be validated with the Mermaid Chart MCP toolmcp__claude_ai_Mermaid_Chart__validate_and_render_mermaid_diagram(load viaToolSearch "select:mcp__claude_ai_Mermaid_Chart__validate_and_render_mermaid_diagram"). A page is done only when each of its diagrams validates clean. - C4 style:
flowchart/graph TBwith subgraphs as boundaries +classDef— NOT nativeC4Context/C4Container(experimental, unreliable in this theme). - The shared legend (use these EXACT classDefs on every C4 diagram):
(design_system calm-dusk palette: lilac=person, honey=external, sky=container, sage=component.) Planned/stubbed nodes getclassDef person fill:#AE97D8,stroke:#3A3357,color:#15131F;classDef external fill:#CBB677,stroke:#5A4F2E,color:#1A160B;classDef container fill:#6AA4DA,stroke:#274867,color:#0C1620;classDef component fill:#66B891,stroke:#244B3A,color:#0B1A13;
stroke-dasharray: 4 3via a:::plannedclass:classDef planned fill:#2C2A33,stroke:#888,color:#DDD,stroke-dasharray:4 3;. - Honesty: the
cloudandaiadapters are CURRENTLY stubs (0 files) — render them with:::plannedand label "(planned)". Never imply they're built. - Ground content in the real structure (verified): SDK services =
approval_service, chore_service, economy_service, entitlement_service, household_service, ledger_service(+chore_period,id_generatorhelpers); adapterslocal(Drift, 3 files)/cached(1)/memory(1) real,cloud/aistubbed; app repositories =approvals, auth, chores, household, places; effect_providers =auth_change, feature_flags, mixpanel, shared_prefs; client_providers =sentry. - EBUSY guard: if
npm run buildfails withEBUSY … rmdir build, the:8002server holdsbuild/. Stop it first:powershell.exe -NoProfile -Command "(Get-NetTCPConnection -LocalPort 8002 -State Listen -ErrorAction SilentlyContinue).OwningProcess | Sort-Object -Unique | ForEach-Object { try { Stop-Process -Id \$_ -Force } catch {} }"then rebuild. - Each
mermaiddiagram is preceded by a one-line caption and followed by a short "Why / changed-from-POC" callout citing the relevant decision doc (relative link into../decisions/<file>or../specs-and-plans/<file>). - Commit per task on branch
docs/c4-architecture; do NOT push.
File structure
app/test-gallery/authored/developer/
architecture.md ← REMOVED (folded into architecture/index.md)
architecture/
_category_.json {label:"Architecture", position:2}
index.md (pos 1) overview + legend + Evolution-from-POC + inside/outside narrative
context.md (pos 2) L1 System Context
containers.md (pos 3) L2 Container
components.md (pos 4) L3 Component (app + client_sdk)
code.md (pos 5) L4 Code (economy + chore-flow aggregates)
dynamics.md (pos 6) Dynamic sequence flows
getting-started.md and the guides currently link ./architecture → must become ./architecture/ (or ./architecture/index).
Task 1: Overview + legend + fold architecture.md; remove old page; fix links
Files:
- Create:
app/test-gallery/authored/developer/architecture/index.md,architecture/_category_.json - Delete:
app/test-gallery/authored/developer/architecture.md - Modify:
app/test-gallery/authored/developer/getting-started.md,guides/*.md(any./architecturelink →./architecture/)
Interfaces:
-
Produces: the
architecture/category +index.md(slug so the category lands on it) carrying the sharedclassDeflegend block that every later diagram copies verbatim. -
Step 1: Create
architecture/_category_.json:{"label": "Architecture", "position": 2, "link": {"type": "doc", "id": "developer/architecture/index"}} -
Step 2: Create
architecture/index.md(front-mattersidebar_position: 1,title: Architecture): (a) one-paragraph intro — "a C4 model of Rewhaven, the living source of truth; update when a load-bearing decision changes"; (b) the legend — a smallmermaidflowchart showing one node of each class with the EXACTclassDefs from Global Constraints, so readers learn the colors; (c) the inside/outside + one-data-path narrative folded from the oldarchitecture.md(keep its substance — the path, the load-bearing rules, the packages); (d) an "Evolution from the POC" section: 4-5 bullets (mutable balances → append-only ledger; monolithic client → facade+services+adapters; brand-in-names → i18n-only; hand-maintained .g.dart → CI codegen) each linking the relevant../decisions/*or../specs-and-plans/rebuild-spec. -
Step 3: Validate the legend mermaid block via the Mermaid MCP validate tool → must be clean.
-
Step 4:
git rmthe oldarchitecture.md; grep for./architecturereferences ingetting-started.md+guides/*.mdand repoint to./architecture/. -
Step 5: Build green:
cd app/test-gallery && node scripts/build_test_gallery.mjs > /tmp/g.txt 2>&1; echo "GEN=$?"npm run build > /tmp/b.txt 2>&1; echo "BUILD=$?"; grep -iE "SUCCESS|\[ERROR\]|broken" /tmp/b.txt | tail -5Expected GEN=0, BUILD=0,
[SUCCESS], no broken-link ERROR for the removed page. -
Step 6: Commit:
git add -A app/test-gallery/authored/developer && git commit -m "docs(arch): C4 overview + legend; fold architecture.md into architecture/index"
Task 2: L1 Context + L2 Container
Files: Create architecture/context.md, architecture/containers.md
- Step 1 —
context.md(sidebar_position: 2,title: L1 — System Context): aflowchart TB:- Persons:
Parent,CoParent["Co-parent\n(delegated scopes)"],Kid["Kid\n(incl. watch-only)"]→:::person - System:
Rewhaven["Rewhaven\n(household chore + token economy)"]→:::container - External:
Supabase["Supabase\n(cloud data · auth · RLS)"],Device["On-device store\n(offline-first)"],AI["AI recommender\n(planned)"]:::planned→:::external - Edges: persons → Rewhaven ("use"); Rewhaven → Supabase ("syncs to / authenticates"); Rewhaven → Device ("reads/writes offline"); Rewhaven -.-> AI ("suggestions (planned)").
- Apply all
classDefs (legend + planned). Caption + Why-note: offline-first + cloud-optional tiers → link../../decisions/2026-06-16-poc-domain-gap-analysisand the rebuild-spec.
- Persons:
- Step 2 —
containers.md(sidebar_position: 3,title: L2 — Containers): aflowchart TBwith subgraphs:subgraph Device→App["Flutter app\n(inside/outside)"]:::container,Drift["Local Drift DB"]:::containerApp→SDK["client_sdk\n(pure Dart facade)"]:::container,App→DS["design_system\n(model-agnostic UI)"]:::containerSDK→Drift("local store");SDK-.->Supa["Supabase\n(Postgres · Auth · RLS · Edge Fns)"]:::external("cloud (config-driven)")- Note node:
Cfg["createClient({config})\nApiConfig → local↔cloud switch"]near the SDK→store edges. - Edge
App -->|"facade only — never drift/supabase"| SDK. - Caption + Why-note: config-driven construction + pure-Dart SDK + DS-no-SDK-dep → link
../../decisions/2026-06-17-design-system-decisions.
- Step 3: Validate BOTH mermaid blocks via the Mermaid MCP tool → clean.
- Step 4: Build green (as Task 1 Step 5).
- Step 5: Commit:
git commit -m "docs(arch): L1 context + L2 containers"
Task 3: L3 Component (app + client_sdk)
Files: Create architecture/components.md (sidebar_position: 4, title: L3 — Components)
- Step 1 — App component diagram (
flowchart TB):subgraph inside→Pages["routes / pages"]:::component→Blocs["blocs\n(inside/blocs)"]:::componentsubgraph outside→Repos["repositories\napprovals · auth · chores · household · places"]:::component,Effects["effect_providers\nauth_change · feature_flags · mixpanel · shared_prefs"]:::component,Clients["client_providers\nsentry"]:::component- Edges:
Blocs --> Repos,Blocs --> Effects,Repos -->|facade| SDKfacade["client_sdk facade"]:::container,Effects --> Clients.
- Step 2 — client_sdk component diagram (
flowchart TB):Facade["client/\nClient · ClientImpl · createClient · ClientConfig"]:::componentsubgraph services→Approval["approval_service"],Chore["chore_service"],Economy["economy_service"],Entitlement["entitlement_service"],Household["household_service"],Ledger["ledger_service"](+ note:chore_period · id_generatorhelpers) →:::componentsubgraph adapters→Local["local (Drift)"]:::component,Cached["cached (write-through)"]:::component,Memory["memory (in-memory)"]:::component,Cloud["cloud (planned)"]:::planned,Ai["ai (planned)"]:::plannedModels["models"]:::component- Edges:
Facade --> services --> adapters --> Models; note "domain rules live in services; repos are thin".
- Step 3: Caption each; Why-notes: services hold domain rules / repos thin / adapter-swap-is-config (CLAUDE.md) and the cloud+ai planned honesty note.
- Step 4: Validate BOTH mermaid blocks via the Mermaid MCP tool → clean.
- Step 5: Build green. Commit:
git commit -m "docs(arch): L3 components — app + client_sdk"
Task 4: L4 Code (economy + chore-flow aggregates)
Files: Create architecture/code.md (sidebar_position: 5, title: L4 — Code (key aggregates))
- Step 1 — Economy aggregate (
flowchart LRorclassDiagram; preferflowchartfor style consistency, boxes = types):LedgerEntry["LedgerEntry\n(append-only)"],LedgerService,Wallet["Wallet / buckets\ngive · save · spend · bank"],EconomyService.- Edges:
EconomyService -->|credits/debits| LedgerService -->|appends| LedgerEntry;LedgerService -->|projects balance| Wallet; annotate zero-floor (debit throws + SQL trigger) and expectation-pays-zero as edge labels / notes.
- Step 2 — Chore-flow aggregate (
flowchart LR):Chore["Chore\n(ChoreKind: expectation | bounty)"]-->ChoreSubmission-->Approval["Approval\n(kind: completion | redemption;\nstatus: pending→approved/rejected)"]-->ChoreCompletion.- Side:
ChoreService(creates submission),ApprovalService(resolves) → on approve, calls into EconomyService (link to diagram 1).
- Step 3: Why-notes: append-only + invariants-in-service-AND-schema (CLAUDE.md); the POC mutable-balance bug → ledger-projected model (link
../../decisions/2026-06-16-poc-domain-gap-analysis). - Step 4: Validate BOTH mermaid blocks via the Mermaid MCP tool → clean.
- Step 5: Build green. Commit:
git commit -m "docs(arch): L4 code — economy + chore-flow aggregates"
Task 5: Dynamic sequence flows
Files: Create architecture/dynamics.md (sidebar_position: 6, title: Dynamic — key flows)
- Step 1: Author 4
sequenceDiagramblocks (participants drawn from real types):- Chore completion:
Kid→Bloc→ChoresRepository→ChoreService: submitCompletion→ApprovalService: Approval(pending)→Parent→Bloc: approve→ApprovalService→EconomyService: credit→LedgerService: append LedgerEntry→Wallet updated→stream→UI. - Spend → redemption:
Kid→Bloc: requestSpend→Approval(redemption, pending)→ affordability check (zero-floor) →Parent: approve→EconomyService: debit→Redemption. - Cache-first read (write-through):
Bloc→Repository→Facade→CachedAdapter→ alt hit: return; else:LocalAdapter/Cloud→ populate cache → return. - Auth/onboarding → setup:
User→AuthBloc: sign-in→AuthenticatedGuard→no household→SetupRoute→SetupBloc: createHousehold + members.
- Chore completion:
- Step 2: Captions + Why-notes: completion funnel → link
../../decisions/2026-06-19-today-jtbd-funnels; cache-first → offline-first decision; guard flow → (the auth-onboarding spec under specs-and-plans). - Step 3: Validate ALL 4
sequenceDiagramblocks via the Mermaid MCP tool → clean. - Step 4: Build green. Commit:
git commit -m "docs(arch): dynamic sequence flows"
Task 6: Build + deploy + verify live
Files: none (uses scripts/deploy-developer-gallery.sh)
- Step 1: Final regen + build (stop :8002 first if EBUSY):
Expected:cd app/test-gallery && node scripts/build_test_gallery.mjs > /tmp/g.txt 2>&1; echo "GEN=$?"ls docs/developer/architecturenpm run build > /tmp/b.txt 2>&1; echo "BUILD=$?"; tail -3 /tmp/b.txt
docs/developer/architecture/has index/context/containers/components/code/dynamics; BUILD=0[SUCCESS]. - Step 2: Redeploy:
cd C:/Users/ryted/Development/repo/rytedesigns/rewhaven && bash scripts/deploy-developer-gallery.sh > /tmp/d.txt 2>&1; echo "DEPLOY=$?"; tail -4 /tmp/d.txt - Step 3: Verify live (follow redirects for trailing slash):
Expected: all 200. (Diagrams render client-side; the per-diagram Mermaid MCP validation in Tasks 1-5 is the parse guarantee.)for u in index context containers components code dynamics; dop="https://developer.eldr-labs.duckdns.org/developer/architecture/$([ $u = index ] && echo '' || echo $u)"echo "$(curl -sL -o /dev/null -w '%{http_code}' --max-time 15 "$p") <- $u"donecurl -sL -o /dev/null -w "overview→ %{http_code}\n" --max-time 15 "https://developer.eldr-labs.duckdns.org/developer/architecture/"
- Step 4: Commit any deploy-side changes if present (usually none).
Self-review
- Spec coverage: L1 (T2) · L2 (T2) · L3 app+SDK (T3) · L4 economy+chore-flow (T4) · Dynamic 4 flows (T5) · overview+legend+fold+links (T1) · build+deploy+verify (T6). cloud/ai-as-planned (T2/T3 honesty). Legend colors concrete (Global Constraints). POC-learnings + decision links on every page. ✓
- Placeholder scan: legend hexes are concrete; each diagram's nodes/edges/classDefs enumerated; no "TBD". The Mermaid MCP validation is the explicit test cycle (build-green alone can't validate client-side mermaid). ✓
- Consistency: the
classDeflegend block is identical across all C4 diagrams (copied from Global Constraints);:::plannedused consistently for cloud/ai; service/adapter/repo names match the verified structure. ✓