Skip to content

Target Architecture

The monolithic Express server is replaced by three Cloudflare Workers and a static frontend:

ServiceRuntimeResponsibilityOntological role
dashboard-apiCF Worker (Hono)All CRUD endpoints, dashboard queries, health checksPrimary EngineeredSystem — serves ICEs, Measurement Data, Process Records
ingestCF Worker (Queue consumer)Shopify sync, asset ingest, CSV generation, mart refreshProcedureExecution engine — executes all background Procedures
frontendCF PagesReact SPA served from edgeHuman-agent interface for Persons bearing Roles
SharedHono middleware + DrizzleAuth validation, Shopify client, DB accessCross-cutting EngineeredSystem capabilities

The dashboard-api and ingest workers communicate via Cloudflare Queues. For direct internal calls (e.g., health aggregation), Service Bindings provide zero-overhead in-Worker communication.

ConcernChoiceRationale
Web frameworkHonoWorker-native, middleware ecosystem, TypeScript-first
ORMDrizzle (PostgreSQL dialect)Already in codebase (Postgres dialect); type-safe, lightweight
DatabasePlanetScale via HyperdriveManaged PostgreSQL, connection pooling at edge
Object storageCloudflare R2 (binding API)Replaces @aws-sdk; native Worker access, no credentials
AuthCloudflare AccessGoogle SSO, zero-trust, JWT assertion on every request
Background jobsCF Queues + Cron TriggersReplace Edge Functions; integrated retry, DLQ, scheduling
MigrationsdbmateFramework-agnostic, SQL-native, pairs with PlanetScale branching
Frontend hostingCloudflare PagesEdge-served SPA, preview deployments, wrangler integration

These dependencies and patterns are removed entirely:

RemovedReplacement
express, express-session, connect-pg-simpleHono
passport, passport-localCF Access JWT validation
@supabase/supabase-jsDrizzle + Hyperdrive
@aws-sdk/client-s3R2 binding API (env.R2_BUCKET.put())
@neondatabase/serverlessHyperdrive connection
memorystoreN/A (no server-side sessions)
All 6 Supabase Edge FunctionsWorker queue consumers + cron handlers
Supabase RLS policiesCF Access + app-level checks
PostgreSQL materialized viewsExplicit performance_measurement_dataset table writes
Supabase StorageR2

The React frontend changes are minimal:

  • Stays: React 18, Vite, shadcn/ui, React Query, Wouter, Recharts, Tailwind
  • Changes:
    • Remove @supabase/supabase-js and AuthContext/AuthProvider
    • Remove Passport login page — Access handles auth before the app loads
    • Replace API client base URL from Express to Worker
    • Add Cf-Access-Jwt-Assertion header forwarding (automatic when Pages + Workers share a zone)
  • Deploy: Cloudflare Pages instead of Vercel