Skip to main content

Pro Website — Pre-flight Verification — 2026-04-18T14:20Z

Call: GO for manual test. Live checkout → webhook → provisioning → dashboard → subdomain render is code-complete and infrastructure-healthy. One operational note + one blast-radius tip below.

What was verified (evidence-or-nothing)

1. Landing pages & public URLs — all 200

  • https://churchwiseai.com/pro-website → 200
  • https://churchwiseai.com/onboard?plan=cwa_pro_website → 200
  • https://churchwiseai.com/pricing → 200
  • https://churchwiseai.com/help/pro-website → 200
  • https://churchwiseai.com/onboard/return → 200
  • https://churchwiseai.com/thank-you?token=test-invalid → 200
  • https://the-bridge-church.john316.church (demo) → 200
  • https://john-new-pr6o-site-j-1fa8.john316.church (founder's 2026-04-17 test) → 200

2. Stripe configuration

  • STRIPE_PRO_WEBSITE_MONTHLY_PRICE_ID set in Vercel production (refreshed 2d ago)
  • Live price price_1TEJh4FaoK5IPzNojyaDlegM → $19.95/mo recurring, livemode: true, active: true, product prod_UCj9DWAsREnJFK, no trial
  • STRIPE_WEBHOOK_SECRET, STRIPE_SECRET_KEY, NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY, CRON_SECRET all present

3. Code paths — checkout → webhook → provisioning

  • OnboardForm.tsx — Pro Website branch: pinned $19.95/mo, no billing toggle, no voice, directory opt-in pre-checked
  • OnboardForm/api/onboard → stores to sessionStorage → redirects to /onboard/checkout
  • CheckoutForm.tsx/api/stripe/checkout-embeddedui_mode: 'embedded', passes ALL onboard data in metadata + subscription_data.metadata
  • checkout.session.completed webhook → provisionNewChurch():
    • Creates churches row (slug retry up to 3x)
    • Generates unique vanity_slug (5 collision retries)
    • Upserts premium_churches with plan: 'cwa_pro_website' (canonical, NOT normalized) — rule #22 intact (src/app/api/stripe/webhook/route.ts:1402)
    • Sets website_template: 'protestant_modern', website_activated_at, directory_opt_in
    • Generates admin_token
    • Creates primary identity + session
    • Auto-provisions chatbot (organization_settings row + agent_config)
    • Creates admin team member row
    • Sends welcome email with 3 retries (magic link = /admin/{admin_token})
    • Syncs to MailerLite if opt-in
  • Legacy activateChurch() path also preserves canonical tier in plan (lines 357, 385, 882) — regression-defense for existing customers

4. Webhook inbox health

  • 12 rows total, ALL status = succeeded
  • Zero pending / processing / failed / abandoned
  • Last processed: 2026-04-17T13:31Z (no Stripe activity today — cron idle, healthy)
  • Cron process-stripe-webhooks runs every 1 minute (vercel.json)
  • Return page polls /api/onboard/check-setup every 2s for up to 120s → comfortably covers worst-case webhook + cron delay

5. Admin dashboard routing

  • AdminDashboard.tsx:209 — Website tab IS shown for cwa_pro_website customers despite normalizePlanTier → 'starter'
  • AdminDashboard.tsx:893isProWebsitePlan(premium.plan) routes to full WebsiteTabEditor (design / content / settings sub-tabs, 884 lines)
  • Public link header uses {vanity_slug}.john316.church for cwa_pro_website customers

6. Subdomain rendering

  • middleware.ts:85-101*.john316.church rewrites to /s/[slug] (excludes static assets, APIs, root files)
  • /s/[slug]/page.tsx — queries premium_churches by vanity_slug, plans ∈ {cwa_pro_website, ps_pro_website, pro_website}, status ∈ {active, preview}, ISR revalidate = 3600
  • Chatbot mounted with per-church UUID → church-scoped knowledge + HEAR protocol

7. DB constraints

  • premium_churches.plan CHECK constraint accepts cwa_pro_website
  • premium_churches.website_template CHECK: {protestant_modern, catholic_liturgical, nondenominational_community} — provisioning hardcodes protestant_modern
  • vanity_slug format regex: ^[a-z0-9][a-z0-9-]{1,28}[a-z0-9]$ — generator complies

8. CI state on main

  • Critical Path Protection: GREEN (run 24606483266 @ 14:12:50Z) — this is the gate that matters for customer flow
  • Tests workflow: red (behavioral test_demo_data_completeness.py — demo churches missing hero videos, tracked as FA-044 P2, unrelated to live flow)
  • Voice Behavioral — Church (STUB): red (voice-agent testing backlog, unrelated)
  • FA-043 (vitest import) RESOLVED via PR #52 — now uses node:test

9. No open P0/P1 blockers

  • founder_action_items open P0/P1: 0
  • ops_errors open P0/P1 last 7d: 0

One operational note

Existing Pro Website row uses founder email john+pws2@churchwiseai.com. If you sign up with that same email, the /api/onboard endpoint returns 409 email_exists and re-sends the dashboard link (defensive, by design). To test a fresh signup, use a different +alias like john+protest@churchwiseai.com.

One blast-radius tip (optional)

To avoid real cost + real customer-facing side effects while testing the live flow, you can append ?promo=<100pct-coupon> to the checkout link — but the validation harness at /api/stripe/checkout-embedded with validation_mode: true is the cleaner way (skips MailerLite, skips voice provisioning, marks the church directory-hidden). If this is the first real payment you want through the pipe for verification, just proceed normally — $19.95 on a founder card is a fair price for end-to-end proof.

What to watch during your test

  1. Checkout page: Stripe EmbeddedCheckout should mount. If it spins forever → check browser console for Stripe publishable key / session client_secret errors.
  2. After clicking "Pay": you land on /onboard/return?session_id=.... The spinner says "Setting Up Your Account..." for ≤120s. If it flips to "We're finishing setup — check your email" (timeout branch), the webhook cron hit ran late — refresh or check email. Provisioning still completes server-side.
  3. Redirect: on success → /thank-you?email=X&token=Y → click through to /admin/{token}.
  4. Admin dashboard: you should see the Website tab. Clicking it should render the full editor (NOT the upsell stub from WebsiteTab.tsx). If you see the "Upgrade to Pro or Suite" stub, isProWebsitePlan(premium.plan) failed — check that plan in DB is literally cwa_pro_website, not starter.
  5. Public render: after the wizard writes vanity_slug, visit https://{vanity_slug}.john316.church — should 200 and show the unified template + chatbot.

Path to unlock Axis A (60% cap)

This manual test, if completed with a real card (non-founder email or not attributable to the founder account), unlocks the 60% Axis A cap on the readiness score: overall would flip from NEEDS WORK → READY assuming Axis B stays where it is. Using john+...@churchwiseai.com will NOT unlock Axis A — the cap query is admin_email NOT LIKE '%@churchwiseai.com'.