8.9 KiB
apps/www Deployment Readiness — Day-0 Plan
Status: DRAFT — what's needed to deploy apps/www to https://waggle-os.ai
Authoring: CC, 2026-05-12 (Phase 2 Wave 3 prep)
Gates: Wave 3 / C2 (Stripe live smoke) is blocked until apps/www is live at a real URL
Why this matters
The Stripe webhook endpoint we_1TVt5qCNCrMQy1f7Zl5ujKSC (created during Wave 2 PG3
prep) is configured to POST to https://waggle-os.ai/api/webhooks/stripe. Without a
live deployment at that URL:
- Stripe webhook deliveries fail (5xx or DNS fail) — won't trigger tier upgrades.
- Marketing CTAs ("Start free trial") have nowhere to land.
- Day-0 LinkedIn post can't link to a real domain.
The Day-0 ETA target (2026-05-15) requires this resolved.
Existing deploy automation: broken
.github/workflows/deploy-www.yml targets GitHub Pages and expects
apps/www/dist (static output). Two problems:
next buildoutputs.next/, NOTdist/— the workflow's artifact upload path is wrong.- GitHub Pages only serves static files — it cannot run:
- The
/api/webhooks/striperoute (needs serverless) - The Clerk middleware (needs Node runtime)
- Server Actions / dynamic rendering
- The
This workflow either needs full rewrite OR a different host. Recommendation: switch to Vercel.
Recommended path: Vercel
Why Vercel
- Native Next.js hosting — zero config; auto-detects
apps/www/next.config.mjs - Server Actions + API routes + middleware all work without translation
- Free tier sufficient for pilot traffic; auto-scaling on Pro
- Native Clerk + Stripe + PostHog integrations documented
- DNS-by-CNAME straightforward to point
waggle-os.aiat Vercel
Step 1 — Vercel project setup
# Install Vercel CLI (one-time)
npm i -g vercel
# Link the apps/www directory to a new Vercel project
cd D:\Projects\waggle-os\apps\www
vercel login # browser OAuth, uses Marko's account
vercel link # creates .vercel/ folder (gitignored)
# When prompted: "Set up apps/www?" → Yes
# Project name: waggle-www (or your choice)
# Framework: Next.js (auto-detected)
# Build command: leave default (npm run build)
# Output directory: leave default (.next)
# Root directory: ./ (already in apps/www)
Step 2 — Set production environment variables
13 env vars from apps/www/.env.local need to land in Vercel. Use the CLI for atomicity:
cd D:\Projects\waggle-os\apps\www
# Bulk-add all 13 prod env vars to Vercel (production environment)
# Reads from .env.local and pushes each to Vercel.
$envFile = ".env.local"
Get-Content $envFile | ForEach-Object {
if ($_ -match "^([A-Z_]+)=(.+)$") {
$key = $matches[1]
$val = $matches[2]
# Skip lines that are template/example values
if ($val -notmatch "REPLACE_ME") {
Write-Host "Setting $key in Vercel production..."
$val | vercel env add $key production
}
}
}
Verification:
vercel env ls production
# Should list all 13 keys (no values displayed; just names).
Step 3 — First deploy (preview)
cd D:\Projects\waggle-os\apps\www
vercel
# Deploys to a preview URL like https://waggle-www-<hash>.vercel.app
# Capture this URL — use for smoke test before production
Step 4 — Preview smoke test
# Open the preview URL in browser:
# 1. Landing page renders (no Clerk crash, no 500)
# 2. /sign-up loads the Clerk widget
# 3. /pricing renders Pro + Teams cards
# 4. /privacy + /terms + /cookies + /eu-ai-act render legal pages
# 5. Hit /api/webhooks/stripe with a curl POST (should reject without signature):
curl -X POST https://waggle-www-<hash>.vercel.app/api/webhooks/stripe -d '{}'
# Expected: 400 "Missing stripe-signature header" or similar
Step 5 — Promote to production at waggle-os.ai
vercel --prod
# Promotes the last preview to production at https://<project>.vercel.app
Now point waggle-os.ai DNS:
- Vercel dashboard → project → Domains → Add
waggle-os.ai - Vercel shows the CNAME/A record values to set at your DNS registrar
- At the registrar (whoever hosts waggle-os.ai DNS), add the records
- Verify with
nslookup waggle-os.ai— should resolve to Vercel's IP - SSL cert auto-provisions via Let's Encrypt within ~5 min of DNS pointing
Step 6 — Production smoke test
# Once https://waggle-os.ai resolves to Vercel:
# 1. Browser: load https://waggle-os.ai — landing renders
# 2. curl Stripe webhook endpoint (should 400, not 404 or 5xx):
curl -X POST https://waggle-os.ai/api/webhooks/stripe -d '{}'
# Expected: 400 — endpoint reachable, just rejected for missing signature
# 3. Test Stripe webhook delivery FROM Stripe side:
# Stripe Dashboard → Developers → Webhooks → endpoint we_1TVt5qCNCrMQy1f7Zl5ujKSC
# → "Send test webhook" → checkout.session.completed event
# Look for 200 response in Stripe's recent deliveries panel.
Step 7 — Update Day-0 ETA marker
After production smoke passes, Wave 3 / C2 (Stripe live smoke) can fire — that's the real Pro Checkout test with a card 4242, watching webhook arrive + Clerk publicMetadata update + tier flip in the UI.
Env var checklist (the 13)
Order matches apps/www/.env.local line-by-line. Each must be in Vercel "Production"
environment before deploy.
| Variable | Notes |
|---|---|
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY |
Clerk dashboard, "live" mode key (pk_live_* or pk_test_*) |
CLERK_SECRET_KEY |
Server-side Clerk auth. Rotated 2026-05-12 ✓ |
NEXT_PUBLIC_CLERK_SIGN_IN_URL |
Default /sign-in |
NEXT_PUBLIC_CLERK_SIGN_UP_URL |
Default /sign-up |
NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL |
Where to send post-signin (e.g. /) |
NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL |
Where to send post-signup (e.g. /) |
CLERK_WEBHOOK_SECRET |
For Clerk → tier publicMetadata sync; set if using Clerk webhooks (else can defer) |
STRIPE_SECRET_KEY |
Live key, on Egzakta account (CNCrMQy1f7). Marko declined rotation per session call — left in chat log; consider rotating post-Day-0. |
STRIPE_WEBHOOK_SECRET |
whsec_smwv4fInMEzJ3NSj3AwcNY2pz21eVrBu (live endpoint created Wave 2 PG3 prep) |
STRIPE_PRICE_PRO_MONTHLY |
price_1TVsaMCNCrMQy1f7KwImpxA4 (Pro $19/mo) |
STRIPE_PRICE_PRO_ANNUAL |
price_1TVsaLCNCrMQy1f7YhQGDH2o (Pro $190/yr) |
STRIPE_PRICE_TEAMS_MONTHLY |
price_1TVsaLCNCrMQy1f7WUhtbZ88 (Teams $49/seat/mo) |
STRIPE_PRICE_TEAMS_ANNUAL |
price_1TVsaLCNCrMQy1f75lmMHMTj (Teams $490/seat/yr) |
Note: .env.example is missing 10 of these 13. Update .env.example to include
all key names (no values; just placeholders) so onboarding contributors know what's needed.
Alternative paths (if Vercel doesn't fit)
Alt-A: Self-host via Docker + Render/Fly/Railway
# apps/www/Dockerfile (would need creating)
FROM node:20-alpine
WORKDIR /app
COPY apps/www/package*.json ./
RUN npm install
COPY apps/www/ ./
RUN npm run build
CMD ["npm", "start"]
EXPOSE 3000
Render/Fly: connect GitHub repo, point at apps/www, set 13 env vars, deploy.
Cost: $0-7/mo for hobby, scales with traffic.
Alt-B: Cloudflare Pages with Functions
CF Pages supports Next.js with Functions for API routes. Slightly more setup than Vercel, similar feature parity. Pro: cheaper at scale. Con: less mature Next.js integration vs Vercel.
Alt-C: Existing GitHub Pages workflow + Next.js static export
Rewrite apps/www/next.config.mjs with output: 'export', drop API routes, move
the Stripe webhook handler elsewhere (Cloudflare Worker, AWS Lambda, your cloud.waggle-os.ai
sidecar). Significant rework. NOT recommended for Day-0.
Day-0 readiness gate
Wave 3 / C2 (Stripe live smoke) cannot fire until:
- apps/www deployed to https://waggle-os.ai (whichever path)
- Production smoke confirms
/api/webhooks/striperesponds (4xx for missing sig, not 5xx or 404) - Stripe dashboard "Send test webhook" delivers 200 from production endpoint
- DNS propagation confirmed (
nslookup waggle-os.airesolves) - SSL cert active (no browser warning)
Once those 5 checks pass, the Wave 3 C2 task in 02-PLAN.md (real Pro Checkout
with test card 4242 → live webhook → Clerk publicMetadata.tier flip → tier
unlock in product) can fire as designed.
Wall-clock estimate for Marko to drive this: 30-60 min if Vercel auth + DNS are already set up; +1-2h if DNS is at a registrar that takes hours to propagate.
Disposition
Once you pick a deploy path:
- Vercel (recommended): follow Steps 1-7 above. Tell CC "deployment live at https://waggle-os.ai" and I fire Wave 3 / C2 from there.
- Other: confirm the path; CC adapts the smoke script accordingly.
Drafted 2026-05-12 by CC. Wave 3 C2 task in 02-PLAN.md resumes once deployment is live.