C4 Architecture Diagrams — design spec (2026-06-21)
Brainstormed + approved 2026-06-21. A full C4 model (Context → Container → Component → Code, plus Dynamic/sequence flows) of the Rewhaven app, authored as Mermaid under the developer portal, as an evolving source of truth grounded in the POC learnings and the decisions already made.
Goal
A hand-curated set of C4 diagrams (Mermaid) under
docs/developer/architecture/, organized by C4 level, that documents the
current decided architecture so we don't re-derive it each time — a reference
that evolves as load-bearing decisions change.
Why
The architecture is settled (CLAUDE.md's load-bearing rules + the decision log), but it lives as prose + tribal memory. A C4 diagram set makes the boundaries explicit, gives reviews and onboarding a shared map, and records why each boundary exists (the POC taught it). It is authored, not generated — the value is the curation.
Scope (approved)
- Full C4: L1 Context, L2 Container, L3 Component, L4 Code, plus a Dynamic (sequence) page.
- L4 is scoped to the load-bearing aggregates only — the economy (append-only ledger + zero-floor wallet) and chore → submission → approval → completion — NOT all ~30 models (those would only rot).
- Organized by C4 level as a new
architecture/subtree.
Structure
A new authored subtree at app/test-gallery/authored/developer/architecture/
(the build copies authored/developer/** into docs/developer/** recursively,
so nested dirs just work). Today's prose architecture.md is folded into the
subtree's index.md (the overview); the standalone architecture.md is
removed and its inbound links updated.
| File | Level | sidebar_position |
|---|---|---|
architecture/index.md | Overview + legend + "Evolution from the POC" + the inside/outside & one-data-path narrative (from today's architecture.md) | 1 |
architecture/context.md | L1 System Context | 2 |
architecture/containers.md | L2 Container | 3 |
architecture/components.md | L3 Component (app + client_sdk) | 4 |
architecture/code.md | L4 Code (economy + chore-flow aggregates) | 5 |
architecture/dynamics.md | Dynamic (sequence flows) | 6 |
The folder gets _category_.json {label:"Architecture", position:2} (right
after Getting Started). architecture/index.md carries slug so the category
links to the overview.
Mermaid / C4 conventions (the legend)
- Use
flowchart/graph TBwith subgraphs as C4 boundaries + a sharedclassDeflegend — NOT Mermaid's nativeC4Context/C4Container(still experimental, renders unreliably in the Docusaurus mermaid theme @3.10.1). - The legend (defined once on
index.md, applied consistently):classDef person fill:#…— actors (Parent / Co-parent / Kid)classDef external fill:#…— external systems (Supabase, on-device store, AI)classDef container fill:#…— deployable/runnable unitsclassDef component fill:#…— code units inside a container
- Dynamic flows use
sequenceDiagram(well-supported). - Every diagram is preceded by a one-line caption and followed by a short "Why / changed-from-POC" callout.
Per-page content (the diagrams to author)
L1 — context.md
Actors: Parent, Co-parent (delegated scopes), Kid (incl. watch-only).
System: Rewhaven. External: Supabase (cloud data/auth), on-device store
(offline-first), AI recommender (planned). Relationships labelled (uses,
authenticates against, syncs to, reads suggestions from).
Why-note: offline-first + cloud-optional tiers (cite homebase-offline-first-mvp
- the product-tiers decision); RLS/household-scoping from the rebuild spec.
L2 — containers.md
Containers: Flutter app (app/, inside/outside), client_sdk (pure Dart
data layer), design_system (model-agnostic UI), Supabase (Postgres + Auth
- RLS + Edge Functions), local Drift DB. Show the config-driven local↔cloud
switch (
createClient({config}),ClientConfig(api: ApiConfig)), and that presentation depends ONLY on the client_sdk facade (not on Drift/Supabase). Why-note: config-driven construction + pure-Dart SDK + DS-has-no-SDK-dep (CLAUDE.md invariants;design-system-decisions).
L3 — components.md (two diagrams)
(a) App container: routes/pages → blocs (inside/blocs) → repositories
(outside/repositories: approvals, auth, chores, household, places) → the
client_sdk facade; plus effect_providers (auth_change, feature_flags,
mixpanel, shared_prefs) and client_providers (sentry). Show repositories as
the thin presentation seam; effect/client providers off to the side.
(b) client_sdk container: facade (client/ — Client, ClientImpl,
createClient, ClientConfig) → services (approval_service,
chore_service, economy_service, entitlement_service, household_service,
ledger_service, + chore_period/id_generator helpers) → adapters
(local = Drift [3], cached = write-through [1], memory = in-memory [1];
cloud + ai = planned/stubbed, shown dashed) → models.
Why-note: domain rules live in services, repos are thin (CLAUDE.md); adapter
swap is config not injection.
Honesty: cloud and ai adapters are currently stubs — render them dashed
/ "planned", do not imply they're built.
L4 — code.md (two aggregate diagrams, classes + relationships)
(a) Economy aggregate: LedgerEntry (append-only) ← LedgerService;
Wallet/buckets (bucket.dart, give/save/spend/bank) with the zero-floor
invariant (debit throws + SQL trigger); EconomyService orchestrating; the
expectation-pays-zero rule.
(b) Chore-flow aggregate: Chore (ChoreKind expectation|bounty) →
ChoreSubmission → Approval (ApprovalKind completion|redemption;
ApprovalStatus) → ChoreCompletion; ChoreService + ApprovalService.
Why-note: append-only + invariants-in-service-AND-schema (CLAUDE.md); the POC's
mutable-balance bug → the ledger-projected model (poc-domain-gap-analysis).
Dynamic — dynamics.md (sequence diagrams)
- Chore completion: Kid taps done → Bloc → ChoresRepository → ChoreService
submitCompletion→ Approval(pending) → Parent approves → ApprovalService → EconomyService credits Wallet via LedgerEntry → cache/stream updates the UI. - Spend → redemption: Kid requests spend → SpendRequest/Approval(redemption) → affordability check → Parent approves → debit (zero-floor) → Redemption.
- Cache-first read (write-through): Bloc reads → Repository → facade → cached adapter → (hit → return; miss → local/cloud → populate) — the offline-first path.
- Auth/onboarding → setup: sign-in → AuthenticatedGuard → no household →
SetupRoute → SetupBloc creates household + members.
Why-notes cite
today-jtbd-funnels(the completion funnel) + the offline-first
- auth-guard decisions.
Living source of truth
- Fully authored / hand-curated — no codegen (L4 especially would only rot if
generated).
index.mdstates: "these are the source of truth; update them when a load-bearing decision changes." - Each page cross-links the decision docs it derives from (relative links into Developer → Decisions) so a diagram and its rationale stay tied.
Build / wiring
- New authored pages under
app/test-gallery/authored/developer/architecture/; the existinggenerateDeveloperDocs()copy step already handles the nested dir. - Remove
authored/developer/architecture.md; update its inbound links (getting-started + the guides reference./architecture→ point to./architecture/i.e. the overview). _category_.jsonfor the subtree.- Mermaid already wired (
markdown.mermaid: true+@docusaurus/theme-mermaid).
Testing / verify
node scripts/build_test_gallery.mjs→docs/developer/architecture/has the 6 pages.npm run build→ BUILD=0,[SUCCESS]; every Mermaid diagram parses/renders (a broken diagram fails the build or renders an error box — check the build log- spot-check the deployed pages).
- After
deploy-developer-gallery.sh: Developer → Architecture shows the subtree; the L1–L4 + Dynamic diagrams render; no broken links from the foldedarchitecture.md.
Out of scope
- Diagramming all ~30 models at L4 (aggregates only).
- Auto-generating any diagram from source.
- Re-architecting anything — this documents the current decided design (and
marks
cloud/aiadapters as planned, honestly). - C4-PlantUML / Structurizr tooling — Mermaid only.
Sequencing (for the plan)
- Overview + legend (
index.md): foldarchitecture.mdprose in, define theclassDeflegend + "Evolution from the POC",_category_.json, fix inbound links, remove the oldarchitecture.md. Build green. - L1 + L2 (
context.md,containers.md). - L3 (
components.md— app + SDK). - L4 (
code.md— economy + chore-flow aggregates). - Dynamic (
dynamics.md— the 4 sequences). - Build + deploy + verify (every diagram renders under Developer → Architecture).