Skip to content

High-Level Design (HLD) ​

The big-picture view: context, containers, deployment topology, and the primary request flows. Low-level contracts (RPC signatures, EF request/response shapes) live on the per-area pages and in the Backend reference.

How a change to any of this reaches production is a separate architecture with its own HLD and LLD: the Release Management System. This page describes what the platform is; that one describes how it changes. No production change ships outside it.

Updated 2026-08-08 — the C4 diagrams below described a single React SPA

The container view used to show one React 18 SPA code-split into four tiers, public routes at /b /s /w, and a public_page_ops_* cron warming the cache. That is the retired architecture (legacy/). It is now two stacks (ADR-0011), one public route /:slug, and the transactional outbox in place of the cron family (whose tables were dropped 2026-08-08).

C4 — Level 1: System Context ​

C4 — Level 2: Container view ​

⚠ The cache-invalidation edge is the one to look at twice. It is drawn because it is required, not because it is built: no write path currently calls cache invalidation (verified — zero cache/cloudflare/invalidate references in manage-profile, manage-settings, manage-reminder). Until the outbox worker is wired, a vendor who edits their card sees no change on the public side, which is indistinguishable from a broken product. That is QRS-350/351, not a deferrable nicety.

Deployment topology ​

Promotion is deliberate. Migrations, EFs, secrets, storage, and cron changes are applied to both Supabase projects by hand (Dev first, then Prod) — Dev/UAT does not self-sync to Prod. See Deployment & Promotion.

Primary flow — authenticated write (dashboard) ​

Primary flow — public Setu Card read (SSR, edge-cached) ​

Two invariants this flow encodes. The SSR route — not the RPC — is the cache boundary, so it is the thing that sets Cache-Tag; there is nothing to fix in the RPC. And Tier 0 is 0 KB of JS: the card renders, looks finished and is fully readable with JavaScript disabled. That is what makes it fast, edge-cacheable and SEO-viable, and it is the actual source of the "premium" feel.

Design invariants (never violated) ​

  • Data access: supabase.from() is banned in app code; the seam is packages/data. See Data Access Strategy.
  • Tier isolation: mobile user ⇎ admin; packages/* and tooling/* never import app @/ code. See Tier System.
  • Security: validate at boundaries (Zod), RLS on every table, EF is the primary write-enforcement layer, and no policy grants access by role alone.
  • Never branch on archetype, industry or plan in app code — lint-gated. Ask for a feature.
  • Design system: Apple-style soft corners, zero hard-coded colours, mandatory light+dark, one shared token package feeding both UI idioms.
  • Parity: every applicable feature ships on Android native · iOS native · Web PWA together. The exception path is retired.
  • One renderer for the public card, always DOM. There is never an RN card-template renderer — in R1 or ever (ADR-0019).

See also: Frontend · Backend · Database & RLS · Security.