Overview
Orders by status
Low-stock alerts —
| Pin | Finish | Bay | Stock | Reorder at | |
|---|---|---|---|---|---|
| Loading… | |||||
Orders —
| Order | Customer | Pins | Total | Status | Created | Actions |
|---|---|---|---|---|---|---|
| Loading… | ||||||
AI render queue —
| Job | Design | Car | Provider | Status | Progress | Created | Actions |
|---|---|---|---|---|---|---|---|
| Loading… | |||||||
Saved designs —
Pin inventory —
| Pin | Category | Finish | Bay | Stock | Reorder ≤ | |
|---|---|---|---|---|---|---|
| Loading… | ||||||
Settings read-only · config via backend/.env
Runtime —
Providers set the corresponding env key to flip to "live"
| Service | Mode | Env key |
|---|
CORS allow-list FRONTEND_ORIGIN env
Architecture docs reference · fold open to read
Backend architecture specification (v1.0)
This is the engineering handoff that described the target backend shape. It remains the authoritative reference for the data model, integration surface, and end-to-end fulfillment flow.
The shape of things
Three tiers: the storefront, a custom Node service for configurator state + AI jobs, and Shopify for the classic commerce primitives (cart, checkout, payments, tax, fraud). Ops uses this console; customers see accounts via Shopify Customer Account API.
frontend/.backend/. Handles designs, AI jobs, inventory, orders. Talks to Shopify Admin API + AI providers + S3.Schema (SQLite · owned by us)
-- Pin SKUs (a tiny product catalog mirrored from Shopify) CREATE TABLE pins ( id TEXT PRIMARY KEY, category TEXT NOT NULL, label TEXT NOT NULL, glyph TEXT, image_url TEXT, base_price_cents INTEGER NOT NULL DEFAULT 300, created_at TEXT DEFAULT (datetime('now')) ); -- Finishes (silver/gold/black/rose) with per-SKU inventory CREATE TABLE pin_variants ( id INTEGER PRIMARY KEY AUTOINCREMENT, pin_id TEXT REFERENCES pins(id), finish TEXT NOT NULL, bay_location TEXT, stock_qty INTEGER NOT NULL DEFAULT 0, reorder_point INTEGER NOT NULL DEFAULT 20, UNIQUE(pin_id, finish) ); -- User's configurator state, one row per saved design CREATE TABLE designs ( id TEXT PRIMARY KEY, customer_id TEXT, frame_color TEXT NOT NULL, plate_text TEXT, finish TEXT NOT NULL DEFAULT 'silver', placements TEXT NOT NULL, -- JSON { "0": { pin, finish }, ... } thumbnail_url TEXT, version INTEGER DEFAULT 1, created_at TEXT DEFAULT (datetime('now')), updated_at TEXT DEFAULT (datetime('now')) ); -- Orders + event-sourced status audit CREATE TABLE orders ( id PRIMARY KEY, design_id, customer_email, ship_address, subtotal_cents, tax_cents, shipping_cents, total_cents, status, tracking_number, ...); CREATE TABLE order_events ( id, order_id, from_status, to_status, note, actor, created_at ); -- AI renders — one row per generate request CREATE TABLE ai_preview_jobs ( id, design_id, provider, prompt, car_spec, status, progress, output_url, cost_cents, error, created_at, finished_at );
Endpoints exposed today
?category=&q=What we do NOT build ourselves
💳 Payments
Shopify Checkout — we never handle PAN data. Stripe is the card gateway inside Shopify. PayPal / Shop Pay / Apple Pay all inherited.
📮 Shipping
EasyPost (or ShipStation) rate-shops UPS / USPS / DHL, prints labels, webhook flips status to delivered.
📽 AI video
Router picks Sora / Veo / Seedance by load, fallback on failure, per-user cost cap.
✉ Transactional email
Postmark or Resend. Order confirmation, preview ready, shipped + tracking, delivered + review.
From click to doormat
- Configurator autosaves placements to
POST /api/designsevery few seconds (debounced). - AI preview: user submits car spec → job queued → worker renders → MP4 to CDN → SSE progress to the UI.
- Add to cart: API expands placements into Shopify variant_ids (one line per pin+finish), returns Shopify Checkout URL.
- Checkout: Shopify handles payment, tax, fraud. Webhook
orders/paidhits our service. - Order row created; email with AI preview sent; order appears in this console.
- Pick: staff opens picklist → walks bays → scans each pin (decrements stock_qty).
- Assemble: pins placed by hand, photographed for QC.
- Ship: EasyPost buys cheapest label; tracking number written back.
- Delivery webhook flips status; review email scheduled for +3 days.