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/.
/create route combines AI generation, art selection, cart review, and reselfie — internal states (loading, art selection, cart) without extra navigations; reselfie is an inline overlayapps/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.
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.
@zooly/merch-srv — 25 service files covering AI art generation, image processing pipeline, order creation, email delivery, lifecycle FSM, and analytics tracking.
@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.
14 Drizzle tables with 17 enums, 11 access files, covering campaigns (with sellerAccountId), products, sessions (with stripePaymentDbId), orders, analytics, tracking, and AI models.
| Domain | App | Purpose |
|---|---|---|
merch.zooly.ai | reverse proxy to app.zooly.ai/merch-app | Production merch |
localhost:3008 | Vite dev server | Local development |
localhost:3004 | zooly-app | Backend API |
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)