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. It supports three distinct conceptual journeys:

  1. Experience: A linear, minimal flow built around the Photobomb pattern (selfie → AI generation → result preview), designed to deliver highly engaging personalized content.
  2. Personalized Merch: A catalog-backed merchandise journey where AI-generated art is applied to physical products (t-shirt, hoodie, plaque, etc.).
  3. Branded Merch / E-commerce: Standard merchandise storefront where template artwork is applied directly to products as-is, skipping selfies and AI generation entirely.

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

Key Features

  • Personalized & Branded Product Modes: Configured at the design level (isPersonalized). Personalized designs utilize selfies and AI generation; Branded designs skip selfie-capture and generation entirely to apply template artwork directly.
  • Campaign-Agnostic Journey Session: Sessions are decoupled from a fixed campaign. A campaign-null session is created on a superstore landing page and "adopted" by sub-stores. User identity (selfie, email, shipping) is preserved across sub-stores to allow seamless shopping, while per-campaign scratch fields are cleared.
  • Deep-Link Auto-Advance: Multi-shop entries from a superstore auto-adopt the session and skip the store landing page (A1), dropping the user directly into design/product selection.
  • 3-Level Design Hierarchy: Design → Product Variation → Demographic Variation with config inheritance.
  • Catalog-Backed Products: Global catalog products attach to shops, and designs associate to those catalog products via catalogProductIds.
  • 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 (both personalized and branded) to a single order with full cart management (add, remove, clear) and check out in a single payment step.
  • 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.
  • Catalog Renderer: Product-specific Sharp composition from catalog_renderer_config, including media-managed preview/clean outputs and background-mask reuse.
  • Stripe Payments: PaymentElement with Apple Pay/Google Pay support; multi-currency including zero-decimal (e.g. JPY).
  • Campaign Lifecycle: SOFT_CLOSE countdown, EMERGENCY_CLOSE, ENDED states.
  • Journey Analytics: 117 distinct event types tracked across all pages, with analytics funnels tracked per-campaign even within shared multi-shop sessions.
  • Abandoned Cart Recovery: Hourly cron emails stale unpaid carts with a /cart deep link; admins triage remaining carts in zooly-stats. See Abandoned Cart Recovery.
  • AI Generation Retry: 5-minute cron retries failed or stale AI generations for delayed-email shoppers; admins triage in the Generation dashboard. See AI Generation Retry & Recovery.
  • 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. Admin Builder (packages/merch-admin)

V2 campaign builder with URL-routed tabs (Setup, Design, Simulation, Translation, Benchmark). Uses Zustand for state management. The Design tab supports a 3-level hierarchy: Design (base settings) → Product Variation → Demographic Variation, with config merging at each level.

The Benchmark tab (/benchmark) mounts @zooly/merch-benchmark-client for AI model/prompt comparison runs through the production generation pipeline. See Image Generation Benchmark.

6. Database Layer

25 Drizzle tables across two schema files, 19 enums, 14 access files. Campaign data is normalized into satellite tables (branding, studio, legal, config, copy). Designs support a 3-level hierarchy with config inheritance. Covers campaigns, products, sessions, selfies, cart items, designs, generation cache, orders, analytics, tracking, AI models, and audit logs.

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