Skip to main content

Operations Guide

Last updated: March 2026 Audience: Claude Code agents operating the system day-to-day


System Architecture

ChurchWiseAI operates three web properties on Vercel sharing a single production Supabase database, plus a voice agent on LiveKit Cloud.

Web Properties (Vercel) Voice Agent (LiveKit Cloud)
----------------------------- -------------------------
churchwiseai.com (port 3002) LiveKit Agents v1.5 (Python)
pewsearch.com (port 3001) Multi-tenant, routes by phone
illustratetheword.com (port 3000) Deploy: lk agent deploy
Code: voice-agent-livekit/

Shared Database: Supabase (wrwkszmobuhvcfjipasi)
ONE instance for dev AND prod. No staging DB.
PropertyWhat It SellsCode LocationDeploy Branch
churchwiseai.comVoice Agent + Chatbot (all AI products)churchwiseai-web/main
pewsearch.comPremium Pages ($4.95/mo directory listing)pewsearch/web/master
illustratetheword.comITW Premium ($9.95/mo illustration library)sermon-illustrations/master

Legacy services (do not modify):

  • churchwiseai-web/voice-agent/ -- old Node.js/Railway voice agent (replaced by voice-agent-livekit/)
  • churchwiseai-web/voice-agent-line/ -- old Cartesia LINE SDK agent (replaced by voice-agent-livekit/)
  • ai-sermon-assistant/ -- old Nx monorepo (reference only, never build here)

Signup Flow (End to End)

Pricing Page (/pricing) -> "Get Started"
-> Onboard (/onboard): church name, email, denomination, plan
-> Stripe Checkout (hosted)
-> Webhook: checkout.session.completed
1. Upsert premium_churches (status='active')
2. Store stripe_customer_id + stripe_subscription_id
3. Normalize plan key via normalizePlanKey()
4. provisionChatbot() -> creates organization_settings
5. Send welcome email with magic link
6. If voice plan -> send voice setup alert to admin
-> Admin Dashboard (/admin/[token]) -- church is live

Key detail: checkout.session.completed is the single activation event. customer.subscription.created is intentionally NOT handled (prevents duplicate welcome emails).

Voice Provisioning

Voice plans require a phone number. New customers use Telnyx (direct SIP to LiveKit, cheaper than Twilio). Twilio is legacy only for existing numbers.

  1. Webhook detects a voice plan purchase
  2. Alert email sent to support with church name, city, plan tier
  3. Admin provisions a Telnyx number with local area code + creates LiveKit SIP trunk/dispatch rule
  4. Database update: church_voice_agents row with phone number and status = 'active'
  5. Phone ready email sent to the church

Current state: Semi-automated. See knowledge/runbooks/voice-provisioning.md for full runbook.

Auth & Security

  • HMAC sessions: Admin tokens hashed with HMAC-SHA256 using APP_SECRET. Database stores hashes only.
  • Magic links: Welcome email contains /auth/magic?t=TOKEN. Sets HttpOnly cookie (cw_session) on first visit.
  • RBAC (9 roles): admin, office_admin, prayer_team, care_team, treasurer, volunteer_coordinator, worship_leader, spiritual_leader, care_leader. Enforced at both API and UI levels.
  • Sensitive data gating: Callback reasons visible only to PASTORAL_ROLES. Confidential prayer text redacted for non-pastoral. Financial data restricted to FINANCIAL_ROLES (admin, treasurer).

Key Database Tables

TablePurpose
churches (218K+ visible)Church directory listings
premium_churches (13 total: 3 Stripe, 10 demo/test)Paid subscriptions + admin access
church_voice_agentsVoice agent config per church
organization_settingsChatbot config per church
voice_call_logsCall transcripts + recordings
voice_prayer_requestsPrayer requests (voice + chat)
voice_visitor_contactsVisitor contact captures
voice_callback_requestsCallback/appointment requests
church_team_membersRBAC team roles
unified_rag_content (327K)All content (illustrations, sermons) -- NEVER bulk delete
product_knowledgeRuntime knowledge for chatbot + voice agent

Deployment

ServiceHow to DeployTiming
churchwiseai.comPush to main -> Vercel auto-deploys2-5 min
pewsearch.comPush to master -> Vercel auto-deploys2-5 min
illustratetheword.comPush to master -> Vercel auto-deploys2-5 min
Voice agentC:\dev\lk.exe agent deploy --project cwa-voice --silent~1 min

Rollback (Vercel): Dashboard -> Deployments -> find last good deploy -> Promote to Production. Takes seconds.

Rollback (Voice): Re-deploy the previous commit from voice-agent-livekit/.

Email System

All transactional email via Resend (from hello@churchwiseai.com):

EmailTrigger
Welcomecheckout.session.completed
Payment Failedinvoice.payment_failed
Voice Setup AlertVoice plan purchased
Phone ReadyTwilio number assigned
Upgrade NotificationPlan change

Lifecycle Emails — 11 sequences, 25+ templates, daily cron at 8am ET (13:00 UTC) via Vercel. Handles onboarding drips (Starter/Pro/Suite), win-back, cross-property promotions (PS→CWA, ITW→SermonWise, CWA→ShareWise), newsletter welcome, and 7-day AI ministry course. Engine: churchwiseai-web/src/lib/lifecycle-emails.ts. Sent via Resend. Deduplication via lifecycle_emails_sent table (unique constraint on church_id + email_key is the state machine — cron is fully idempotent). MailerLite is retained for newsletter subscriber management and Care broadcasts only.

Stripe Integration

Webhook endpoint: /api/stripe/webhook. Three events handled:

EventAction
checkout.session.completedActivate subscription, provision chatbot, send welcome email
customer.subscription.updatedUpdate plan tier, adjust feature access
customer.subscription.deletedSet status='cancelled', remove premium flag

Plan normalization: normalizePlanKey() in tier-config.ts maps Stripe price IDs to canonical plan keys.

Stripe account: churchwiseai@gmail.com. Test mode is default (sk_test_). Use --live flag for live operations. Restricted live key cannot create products via CLI.

Chatbot System

  • Auto-provisioned during checkout via provisionChatbot() -- creates organization_settings with default agent config, maps denomination to theological lens, loads denomination content packs.
  • 39 agentic tools across 3 tiers: Starter (12 tools, 2 agents), Pro (35 tools, 4 agents), Suite (39 tools, 4 agents).
  • Moderation escalation: 1st violation = warning, 2nd = 2-min cooldown, 3rd = 1-hr block, repeated = permanent block.
  • 4 agents in chat: Coordinator, Care, Stewardship, Discipleship.

Voice Agent System

  • 2 agents in voice: Coordinator Agent (Gemini 2.5 Flash, handles info + logistics + giving) + Care Agent (Claude Haiku 4.5, handles prayer/grief/crisis with different voice and pacing).
  • Technology: LiveKit Agents v1.5 (Python), deployed on LiveKit Cloud.
  • Multi-tenant: ONE deployed agent serves ALL churches. session.py:resolve_route() routes by phone number (PHONE_REGISTRY dict + DB fallback).
  • STT/TTS: Deepgram Nova-3 (speech-to-text), Cartesia Sonic (text-to-speech).
  • LLMs: Gemini 2.5 Flash (primary), Claude Haiku 4.5 (fallback; Care Agent uses Haiku as primary for better empathy).
  • Threat detection: Explicit threats -> immediate hangup + emergency notifications. Abuse -> graduated response (warning -> hangup after 3 offenses).

Demo Church

PropertyValue
Church ID00000000-0000-4000-a000-000000000001
Admin tokendemo-admin-token-2026
Dashboard/admin/demo-admin-token-2026
Chatbot/care/churchwiseai-demo
Planbundle (Voice + Chat)

Setup script: scripts/setup-demo-church.sql (idempotent).

Operational Guardrails

  1. ONE production database. Every query hits prod. Be paranoid about writes.
  2. 327K irreplaceable records in unified_rag_content. NEVER bulk delete.
  3. ai-sermon-assistant is LEGACY. Read for reference, never build there.
  4. Deploy branches differ. main for churchwiseai-web, master for pewsearch and ITW.
  5. Multiple agents work concurrently. Always create your own branch. Never reuse another agent's. Never force push.
  6. Voice agent deploys via lk agent deploy, NOT git push.
  7. Use claude -p for batch content generation, not API calls.

Blocking Issues (April 2026)

  • FA-004 (P1): Add trial_will_end webhook event -- trial reminder emails won't send
  • ShareWiseAI: Code complete but OAuth + Stripe products not configured
  • 10DLC SMS: Campaign pending vetting, outbound SMS blocked