Campaign Validator
File: client_backend/src/scripts/validate-campaign.ts
Why
After any test run (manual UI testing, load test, or a real production campaign), you need a quick way to check: did everything work? Are there stuck contacts? Missing recordings? Billing mismatches?
This script scans every contact in a campaign and reports issues grouped by severity.
How To Run
bash
cd client_backend
# Validate a specific campaign
npx tsx src/scripts/validate-campaign.ts <campaignUID>
# Verbose mode (show all issues, not just first 20)
npx tsx src/scripts/validate-campaign.ts <campaignUID> --verbose
# Validate all currently running campaigns
npx tsx src/scripts/validate-campaign.ts --all-running
# Validate the 10 most recent campaigns
npx tsx src/scripts/validate-campaign.ts --recent 10What It Checks
Errors (things that are broken)
- Stuck in_progress: Contact hasn't been updated in 5+ minutes likely a dropped webhook or stale call
- Missing recording URL: Call completed (
done) with duration > 3s but norecordingUrlegress pipeline failed - Missing credit transaction: Call has billing duration but no matching
CreditTransactiondocument billing was skipped
Warnings (things that might be wrong)
- Missing transcription: Completed call with duration > 5s but no transcription agent didn't sync
- Missing analysis: Completed call with duration > 5s but no analysis analysis service didn't sync
- Billing without callAnsweredAt: Duration was computed from
participantJoinedAtinstead ofcallAnsweredAtincludes ringing time in billing - Missing participantLeftAt: Contact has join timestamp but no leave timestamp and isn't in_progress
- Unusually long call: Duration > 30 minutes possible stuck egress or missed hangup
- Done without SIP call ID: Contact completed but never got a SIP call ID unusual
Reading The Output
--- Contact Status Breakdown ---
done 850 (85.0%) ###########################################
failed 150 (15.0%) ########
--- Data Completeness (for 'done' contacts) ---
Recordings: 845/850 (99.4%) 5 MISSING
Transcriptions: 850/850 (100.0%)
Analysis: 848/850 (99.8%) 2 MISSING
--- VERDICT ---
FAILED 5 error(s), 2 warning(s)When To Use
- After a load test with
--skip-cleanupto inspect the synthetic data - After a real production campaign to verify data completeness
- When a customer reports missing recordings or wrong billing
- As a daily health check:
--all-runningor--recent 10