Docs

Deploying

1. Supabase: create a project; run every file in supabase/migrations/ in order (00010007) in the SQL editor. Enable Google OAuth (Authentication → Providers) and set Site URL to your app URL. Set the DB setting alter database postgres set app.super_admin_emails = 'you@company.com'; (used by the signup trigger) — or flip profiles.is_super_admin manually. For signup captcha, enable Turnstile under Authentication → Captcha. 2. Lemon Squeezy: create a store, products *Starter/Growth/Scale* with monthly + yearly variants, and a *Lifetime* single-payment product. Copy variant IDs into env. Add a webhook → https://<app>/api/webhooks/lemonsqueezy, events subscription_*, order_created, order_refunded, with the signing secret in LEMONSQUEEZY_WEBHOOK_SECRET. 3. Vercel: import repo, add env vars from .env.example, add domains: app domain and the short redirect domain (NEXT_PUBLIC_REDIRECT_BASE_URL). Crons are in vercel.json (health every 6h, workflows daily) — set CRON_SECRET. 4. Custom customer domains: customers CNAME to your app; add the hostname to the Vercel project (API or dashboard) and click Verify in their Domains page. 5. Email: Resend key for health, workflow and dunning emails (optional). Verify the app domain as a sender. 6. Rate limiting: create an Upstash Redis database and set UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN. Without it the app falls back to per-instance in-memory limiting (fine for a single instance, weak at scale). 7. Bot protection (optional): Cloudflare Turnstile — set NEXT_PUBLIC_TURNSTILE_SITE_KEY + TURNSTILE_SECRET_KEY (signup + public forms), and TURNSTILE_REQUIRE=true to hard-require tokens on /api/capture. 8. AI QR art (optional): set REPLICATE_API_TOKEN and optionally REPLICATE_QR_MODEL (defaults to a ControlNet QR model). Quotas come from the per-plan ai_art limit.