Introduction
BluntDashboard is an internal operations platform for Blunt Cases — a phone-case brand that manages product performance tracking, creative ad testing (combos), asset redundancy pipelines, supplier CSV automation, and Shopify data analytics.
Why rewrite?
Section titled “Why rewrite?”The current system has accumulated enough technical debt that incremental fixes are no longer cost-effective. The three critical issues are:
-
Dual storage with volatile auth — Real business data (performance metrics, combos, tags, assets) is persisted in Supabase, but the Express server uses an in-memory
Map<number, T>for auth users, sample orders, integrations, and notifications. Auth state is lost on restart. The Drizzle schema inshared/schema.tsdefines tables that are never connected to a database — it’s used only for TypeScript types. -
Security gaps — A hardcoded password bypass (
admin123) exists inserver/auth.ts. Over 40 API endpoints (performance metrics, combo logs, tag classifications, designers, tag analytics, asset ingest) have zero authentication middleware. Two incompatible auth systems (Passport.js sessions + Supabase JWT) create a split-brain identity model where neither can verify the other’s tokens. -
Operational fragility — Shopify data sync runs only when manually triggered via a UI button — there is no cron scheduling. Six Supabase Edge Functions duplicate Shopify client logic across isolated Deno runtimes with no shared configuration (three near-identical
shopifyRest()helpers plus three inlinefetch()calls). Note: the system does have run tracking (raw.ingest_runstable) and idempotency viaON CONFLICTupserts and SHA-256 checksum deduplication — but these are implemented inconsistently and only in some code paths.
What stays
Section titled “What stays”The rewrite preserves what works:
- The React + shadcn/ui frontend — component library, React Query patterns, and page structure remain largely intact
- The raw → core → mart data warehouse pattern — the layered approach to Shopify data is sound
- The asset deduplication strategy — SHA-256 checksums with R2 storage
- The combo ID convention —
TYPE-PRODUCT-COUNT-AUDIENCE-SEQformat (now formalized as Plan Specification Identifiers)
What changes
Section titled “What changes”| Current | Target |
|---|---|
| Express.js on Vercel/Replit | Cloudflare Workers (Hono) |
| Supabase PostgreSQL | PlanetScale PostgreSQL via Hyperdrive |
| Supabase Auth + Passport.js | Cloudflare Access (Google SSO) |
| Supabase Edge Functions | CF Workers + Queues + Cron |
| Supabase Storage | Cloudflare R2 (native bindings) |
| @aws-sdk/client-s3 | R2 Worker binding API |
| Manual sync triggers | Scheduled Cron Triggers |
| Drizzle + Postgres dialect (Supabase) | Drizzle + Postgres dialect (PlanetScale) |
| Ad-hoc naming conventions | Ontology-first naming grounded in BFO/IAO/CCO/IOF/PKO |
Document structure
Section titled “Document structure”This specification is organized using viewpoints adapted from the Arcadia method, with an Ontological Foundation that grounds every entity, relation, and process in formal categories:
- Ontological Foundation — why ontology-first, the ontology stack, domain mapping, quick reference, and ontological decisions
- Overview — problem statement, current state, debt assessment
- Architecture — logical and physical decomposition
- Data Model — schema (ontologically-named tables), pipeline, and PlanetScale constraints
- Scenarios — 14 operational scenarios in ConnectSpec style with ontologically-typed contracts
- Integrations — per-service integration details
- Operations — auth, observability, migration, and delivery plan