Handoff: Provision Voice Agent for Zewdei (First Paying Customer)
Created: 2026-03-27 Priority: P0 — paying customer ($49.95/mo Voice+Chat) with no working voice line Context: Zewdei paid March 25. Webhook failure meant his church was never activated. We fixed the DB manually today (status=active, plan=starter/both, Stripe linked). Chatbot is working. Voice agent config exists but has NO phone number.
Read These First
C:\dev\churchwiseai-web\voice-agent-livekit\main.py— LiveKit agent entrypoint, phone routingC:\dev\churchwiseai-web\voice-agent-livekit\session.py—resolve_route(), phone registry, church config loadingC:\dev\churchwiseai-web\voice-agent-livekit\scripts\setup_sip.py— LiveKit SIP trunk setup scriptC:\dev\CLAUDE.md— cross-project rules, voice agent section
Customer Details
| Field | Value |
|---|---|
| Church | Medhanialem Ethiopian Evangelical Church |
| Church ID | 96f5b89e-b238-4811-8d76-777f84f4241c |
| Premium ID | 92eef012-3ded-4285-b3ca-066f48492762 |
| Admin | Zewdei Gebremedhin (zewdei.gebremedhin@gmail.com) |
| Phone | 414-336-2009 |
| Location | Greenfield, WI (Milwaukee area) |
| Plan | Starter Voice+Chat ($49.95/mo) |
| Stripe Sub | sub_1TF06CFaoK5IPzNoFKVOGlf1 (active) |
Current State
| Component | Status |
|---|---|
premium_churches | Active, Stripe linked, plan=starter/both |
churches.is_premium | true |
organization_settings | Exists (chatbot provisioned) |
church_voice_agents | Exists, status=active, BUT twilio_phone_number=NULL |
| Chatbot | Working |
| Voice agent | NOT WORKING — no phone number |
What Needs to Happen
Part 1: Set Up Telnyx (founder wants to use Telnyx instead of Twilio for customer numbers — cheaper)
- Create Telnyx account (if not already done) or use existing
- Buy a phone number — Milwaukee area code (414 or 262)
- Configure Telnyx SIP trunk to point at LiveKit Cloud SIP gateway
- Get the SIP URI from LiveKit Cloud → Project Settings (something like
cwa-voice-9x077mph.sip.livekit.cloud) - Create a Telnyx SIP connection/trunk pointing to that URI
- Get the SIP URI from LiveKit Cloud → Project Settings (something like
- Test — call the number, verify it reaches LiveKit
Part 2: Wire Into LiveKit
- Add number to LiveKit SIP trunk — either:
- Re-run
voice-agent-livekit/scripts/setup_sip.pywith the new number inPHONE_NUMBERSarray - Or use LiveKit API to add the number to the existing trunk
- Re-run
- Add phone→church_id mapping in
voice-agent-livekit/session.py:# In PHONE_REGISTRY or equivalent lookup"+1XXXXXXXXXX": "96f5b89e-b238-4811-8d76-777f84f4241c", - Deploy the agent — push to Railway (or wherever the LiveKit agent is hosted)
Part 3: Update Database
- Update
church_voice_agents:UPDATE church_voice_agentsSET twilio_phone_number = '+1XXXXXXXXXX',twilio_phone_sid = 'telnyx_sid_here'WHERE church_id = '96f5b89e-b238-4811-8d76-777f84f4241c'; - The column is still named
twilio_phone_numbereven for Telnyx numbers — legacy naming
Part 4: Test End-to-End
- Call the new number
- Verify the greeting plays (currently set to: "We would like to know about how to repair the church that we have." — this looks wrong, may need fixing)
- Verify
voice_call_logsgets a new entry - Verify
resolve_route()correctly maps to this church's config
Voice Agent Config Issues to Fix
The church_voice_agents row has some issues from the preview period:
| Field | Current Value | Issue |
|---|---|---|
welcome_greeting | "We would like to know about how to repair the church that we have." | This is a question, not a greeting. Should be something like "Thank you for calling Medhanialem Ethiopian Evangelical Church. How can I help you today?" |
notification_email | med@eecmke.org | Verify this is correct |
notification_phone | 2622936676 | Verify this is correct |
Architecture Notes
- Voice agent is on LiveKit (NOT Cartesia LINE, NOT Railway for hosting — check where the LiveKit agent is actually deployed)
voice-agent-line/is the OLD Cartesia code — do NOT usevoice-agent-livekit/is the CURRENT code- The agent is multi-tenant: ONE deployed agent serves ALL churches. Phone number routing happens in
session.py→resolve_route() - Phone registry is currently a hardcoded dict — long-term should move to DB lookup from
church_voice_agents.twilio_phone_number
Founder Decision Needed
- Telnyx account setup — does the founder already have a Telnyx account? If not, needs to be created.
- Welcome greeting — the current greeting text is wrong. Ask the founder what Zewdei's church greeting should say.
- 3-months-free promise — Zewdei was promised 3 months free but was charged $49.95. This needs to be resolved in Stripe (credit or coupon). Handle in same session or separate.
What Was Done Today (March 27)
- Discovered Zewdei's Visa DID go through on March 25 ($49.95) — previous agent incorrectly said it failed
- Root cause: all 3 live Stripe webhook signing secrets were wrong since March 9
- Fixed: recreated all 3 webhook endpoints with fresh secrets, updated Vercel env vars, redeployed all 3 sites
- Manually activated Zewdei: status→active, plan→starter/both, Stripe IDs linked, is_premium→true, voice status→active, lifecycle emails logged
- Built Stripe WatchTower (3 layers): webhook failure instrumentation (P0 alert on first failure), 15-min canary (endpoint health + audit heartbeat), daily Stripe↔DB reconciliation
- Fixed pre-existing ops-reporter bugs (column name mismatches that broke P0 cooldown)
- Cleaned up 9 stale test records from premium_churches + 7 junk churches entries
- Updated voice setup alert email template for LiveKit provisioning steps