Merch App Overview

Fan-facing AI-powered custom merchandise experience

What is the Merch App?

The Merch App is a standalone Vite SPA that powers the fan-facing custom merchandise experience. Fans take a selfie, generate AI art from it, pick merchandise (t-shirt, hoodie, plaque), and purchase via Stripe.

The app runs at apps/zooly-merch/ (thin Vite wrapper) with client code in packages/merch/client/, server logic in packages/merch/srv/, payment integration via @zooly/srv-stripe-payment, and a Drizzle-backed API on apps/zooly-app/.

Key Features

  • AI Art Generation: Multi-attempt parallel generation via FAL.AI with character consistency scoring
  • Multi-Candidate Art Selection: All generated candidates are returned to the fan for manual selection, sorted by likeness score
  • Multi-Item Cart: Fans can add multiple products to a single order with full cart management (add, remove, clear)
  • Create Page (unified): Single /create route combines AI generation, art selection, cart review, and reselfie — internal states (loading, art selection, cart) without extra navigations; reselfie is an inline overlay
  • Camera & Upload: Native camera capture with face detection, or file upload with Gemini vision verification
  • Mockup Compositing: Sharp-based apparel print blending or FAL AI virtual try-on
  • Plaque Rendering: Multi-layer Sharp composition with OpenType.js text overlay
  • Stripe Payments: PaymentElement with Apple Pay/Google Pay support
  • Campaign Lifecycle: SOFT_CLOSE countdown, EMERGENCY_CLOSE, ENDED states
  • Journey Analytics: 117 distinct event types tracked across all pages
  • Session Persistence: sessionStorage-based with optimistic updates and debounced sync

System Components

1. Vite SPA (Frontend)

apps/zooly-merch/ is a thin Vite wrapper. All React code lives in packages/merch/client/ (@zooly/merch-client) — 15 page routes, 22 components, 6 hooks, MerchContext for state management. Styled with DM Sans font and --merch-* CSS custom properties.

2. Backend API (zooly-app)

20 Next.js API routes (thin wrappers) handling campaign config, session management, image upload/verification, AI generation, art candidate selection, mockup rendering, pricing, payment, and order completion.

3. Server Logic (packages/merch/srv)

@zooly/merch-srv — 25 service files covering AI art generation, image processing pipeline, order creation, email delivery, lifecycle FSM, and analytics tracking.

4. Payment Integration (packages/srv-stripe-payment)

@zooly/srv-stripe-payment handles merch payment processing: createMerchPaymentIntent for PI creation with audit trail and idempotency, and completePaymentFromClient for server-side payment verification and revenue distribution.

5. Database Layer

14 Drizzle tables with 17 enums, 11 access files, covering campaigns (with sellerAccountId), products, sessions (with stripePaymentDbId), orders, analytics, tracking, and AI models.

Domain Topology

DomainAppPurpose
merch.zooly.aireverse proxy to app.zooly.ai/merch-appProduction merch
localhost:3008Vite dev serverLocal development
localhost:3004zooly-appBackend API

Data Flow

Fan browser (Vite SPA, port 3008)
  | fetch() with CORS
zooly-app API routes (port 3004)
  | delegates to @zooly/merch-srv + @zooly/srv-stripe-payment
PostgreSQL (merch_* + stripe_payments tables)
  | S3 (media), FAL.AI (generation), Stripe (payments), SendGrid (email)

Next Steps