DATABASE_URL set# Terminal 1: Backend API (required)
cd apps/zooly-app && npm run dev # Port 3004
# Terminal 2: Merch frontend
cd apps/zooly-merch && npm run dev # Port 3008
Visit http://localhost:3008/teststore/lexnour to see the test campaign.
The merch app requires campaign/product data in the database. Run the seed script:
DATABASE_URL="postgresql://postgres:admin@localhost:5432/zoolylocal" \
npx tsx packages/db/src/seed/merch-seed.ts
This creates 3 test campaigns:
| Campaign | URL | Products |
|---|---|---|
| Lexnour | /teststore/lexnour | T-Shirt ($69), Hoodie ($109) |
| LAS VEGAS ACES | /Las%20Vegas%20Aces/las-vegas-aces | Team Tee ($45), Pro Hoodie ($85), Championship Plaque ($59) |
| Plaque | /plaque/plaque | T-Shirt ($69), Hoodie ($109), Plaque ($39) |
Set in apps/zooly-merch/.env or .env.local:
| Variable | Default | Purpose |
|---|---|---|
VITE_APP_URL | http://localhost:3004 | Backend API base URL |
VITE_MEDIA_BASE_URL | ${VITE_APP_URL}/api/media | S3/CloudFront media origin |
Set in apps/zooly-app/.env.local:
| Variable | Purpose |
|---|---|
ALLOWED_DOMAINS_CORS | Comma-separated allowed CORS origins (include http://localhost:3008) |
STRIPE_SECRET_KEY | Stripe server key (sk_test_...) |
STRIPE_PUBLISHABLE_KEY | Stripe publishable key (pk_test_...) |
SENDGRID_API_KEY | SendGrid email delivery |
NEXT_PUBLIC_UI_HOST | Merch experience URL for email links (http://localhost:3008) |
SUPPORT_EMAIL_ADDRESSES | Comma-separated; first used as "from" address |
MERCH_MOCKUP_MODE | composite (default) or ai-tryon |
FAL_KEY | FAL API key for AI generation |
AWS_ACCESS_KEY_ID | S3 access |
AWS_SECRET_ACCESS_KEY | S3 access |
AWS_REGION | S3 region |
AWS_BUCKET_NAME | S3 bucket |
DATABASE_URL | PostgreSQL connection |
cd apps/zooly-merch && npm run build # Outputs dist/
cd apps/zooly-merch
npx playwright test # Run all tests
npx playwright test --ui # Interactive UI mode
npx playwright show-report # View HTML report
apps/zooly-merch/vercel.json configures SPA mode:
{ "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }] }
Production: merch.zooly.ai reverse proxies to app.zooly.ai/merch-app.
http://localhost:3008/ shows 3 campaign cardshttp://localhost:3008/teststore/lexnour shows hero, CTAs, legal footer/create): Logarithmic progress + email capture + carousel during generation; then art selection (if multiple candidates) and cart view on the same URL; reselfie via overlay; BUY from art adds to cart on-page, BUY from cart continues to shipping4242 4242 4242 4242)| Issue | Fix |
|---|---|
| CORS errors | Add http://localhost:3008 to ALLOWED_DOMAINS_CORS in zooly-app .env.local |
| Images not loading | S3 assets from seed don't exist locally; expected behavior |
| Stripe errors | Ensure STRIPE_SECRET_KEY and STRIPE_PUBLISHABLE_KEY are set |
| Emails not sending | Check SENDGRID_API_KEY, SUPPORT_EMAIL_ADDRESSES, NEXT_PUBLIC_UI_HOST |
| Camera not working | HTTPS required for getUserMedia in most browsers; use localhost or ngrok |