38
Total
25
High
12
Medium
1
Low

Prerequisites

No test cases yet.

Pre-deploy / migration

IDTest CasePreconditionsStepsExpected ResultPriority
EOC-001 Migration applies cleanly DB backup taken, app stopped or blue/green ready 1. Run `alembic upgrade head` 2. Verify revision `0086_contact_email_id` Migration succeeds. No constraint violations. Existing contacts with `phone=''` now have `phone IS NULL` High
EOC-002 Email-only row allowed in DB Migration applied 1. `INSERT` or API-create contact with `phone=NULL`, `email='verify@example.com'` (unique per org) Row persists. Check constraints satisfied (`phone OR email` required) High
EOC-003 Partial unique indexes Two contacts in same org 1. Create contact A: phone only 2. Create contact B: email only 3. Attempt duplicate phone or duplicate email in same org Second create returns 409 / unique violation. Different orgs may reuse same email (tenant-scoped) High

CRM — create & edit contacts

IDTest CasePreconditionsStepsExpected ResultPriority
EOC-010 Create email-only contact via UI Logged in, `/contacts` 1. Click **New Contact** 2. Leave phone empty 3. Enter email `alice@example.com`, name optional 4. Save Success toast. List shows email; phone column shows **—**. No placeholder phone stored High
EOC-011 Create phone-only contact (regression) Logged in 1. New contact with phone `+919876543210`, email empty 2. Save Contact created as before. `phone` set, `email` null High
EOC-012 Create with both phone and email Logged in 1. Enter phone and email 2. Save Both fields stored. Open Chat enabled High
EOC-013 Validation: neither phone nor email Create modal open 1. Leave phone and email empty 2. Save Inline/form error: at least one of phone or email required. No API call High
EOC-014 Validation: invalid email Create modal open 1. Email only: `not-an-email` 2. Save Client or API validation error. Contact not created Medium
EOC-015 Search by email Email-only contact exists 1. `/contacts` search box: partial email 2. Observe results Contact appears in results (email search works) High
EOC-016 Open Chat disabled for email-only Email-only contact in list 1. Hover Open Chat icon 2. Click (if enabled) Button disabled or tooltip: add phone to start WhatsApp chat. No navigation to conversation High
EOC-017 Backfill phone on email-only contact Email-only contact exists 1. Edit contact 2. Add phone (field enabled when contact has no phone) 3. Save Phone saved. Open Chat becomes enabled. Phone field read-only on subsequent edits High
EOC-018 Cannot change phone once set Contact with phone 1. Edit contact 2. Attempt to change phone Phone field disabled. Only email/name/tags editable High
EOC-019 Duplicate email (API) Contact with `bob@example.com` exists 1. `POST /api/contacts` with same email, different phone (or curl) HTTP **409** with message containing `already exists` High
EOC-020 Identity collision (API) Contact A: phone P1. Contact B: email E2 only 1. `POST /api/contacts` with `phone=P1` and `email=E2` HTTP **409** `identity_collision: phone and email match different contacts` High

Public forms & marketing

IDTest CasePreconditionsStepsExpected ResultPriority
EOC-030 Marketing `/contact_us` email-only Public site or local `frontend` dev 1. Open `/contact_us` 2. Fill name + email only (no phone) 3. Submit Success message mentions email follow-up (not only WhatsApp). Network payload has `"phone": null` High
EOC-031 Marketing form phone + email Public form 1. Submit with both phone and email Success copy mentions WhatsApp confirmation. Payload includes phone string Medium
EOC-032 Marketing validation: neither Form open 1. Fill name only, submit Client validation highlights phone and email fields. No submit High
EOC-033 Public API email-only lead Valid `X-Form-Token`, honeypot empty 1. `POST /api/public/forms/submit` JSON: `{ "name": "Ravi", "email": "ravi@example.com" }` HTTP **200** `{"ok": true}`. Contact + lead created; contact has `phone=NULL` High
EOC-034 Public API missing both identifiers Valid token 1. POST body: `{ "name": "Ravi" }` only HTTP **422** validation error High
EOC-035 Form integration guide endpoint Open `/feature-coverage-matrix` or form guide page source 1. Inspect documented submit URL Endpoint is `https://api.bizbotify.com/api/public/forms/submit` (not `app.bizbotify.com`) Low

Leads panel

IDTest CasePreconditionsStepsExpected ResultPriority
EOC-040 Lead from email-only form Lead created from EOC-033 1. Open Leads 2. Find lead 3. Open detail panel Lead opens. **Open Chat** disabled. Hint: no WhatsApp number on file High
EOC-041 Lead Open Chat after phone backfill Email-only lead/contact 1. Add phone on linked contact (EOC-017) 2. Reopen lead panel Open Chat enabled. Chat opens or creates conversation Medium

WhatsApp campaigns

IDTest CasePreconditionsStepsExpected ResultPriority
EOC-050 Broadcast excludes email-only Email-only + phone contact in org; template approved 1. Create broadcast, recipient source **Contacts**, select both 2. Launch campaign `total_recipients` counts only phone contact. Email-only excluded (not FAILED row) High
EOC-051 Campaign completes with mixed audience As above 1. Run campaign to completion Campaign status completed. Only phone contact receives message. Logs contain `campaign_skipped_undeliverable` with `channel=whatsapp` for skipped contact High
EOC-052 Send test template to phone Active WA account 1. Campaign wizard → send test to valid phone Test message delivers Medium

Auto follow-up / nurture

IDTest CasePreconditionsStepsExpected ResultPriority
EOC-060 Manual enroll skipped (email-only) Active nurture sequence; email-only contact 1. Contacts → contact → enroll in follow-up OR Leads enroll HTTP **400** or UI error: no phone for WhatsApp follow-up. No enrollment row High
EOC-061 Auto-enroll after form (email-only) Sequence with tag/form trigger 1. Submit public form email-only with matching tag 2. Check logs `nurture_enroll_skipped_undeliverable` logged; no active enrollment Medium
EOC-062 Nurture on phone contact (regression) Contact with phone 1. Enroll in sequence Enrollment created. Steps send on schedule High

Agent inbox / outbound messages

IDTest CasePreconditionsStepsExpected ResultPriority
EOC-070 Send text without phone (API) Conversation linked to contact; set `contact.phone=NULL` in DB **or** use API-only path 1. `POST /api/conversations/{id}/messages/text` with body HTTP **400** detail contains no phone number. No Meta API call High
EOC-071 Inbound WhatsApp still works (regression) Customer messages business number 1. Send WhatsApp to connected number 2. Verify inbox Message appears. Contact has phone from webhook. Auto-reply/flows still run High

Chatbot / automation (flow engine)

IDTest CasePreconditionsStepsExpected ResultPriority
EOC-080 Flow send_message skip Email-only contact in flow session (edge setup) 1. Trigger flow with send_message node Step skipped; log `messaging_skipped_undeliverable` surface `flow_engine_send_message`. Flow does not crash Medium
EOC-081 Flow send_template skip Same 1. Flow with send_template node No template sent; flow advances or skips gracefully Medium

API & integrations contract

IDTest CasePreconditionsStepsExpected ResultPriority
EOC-090 ContactResponse phone nullable Email-only contact 1. `GET /api/contacts/{id}` JSON `"phone": null`. Email present High
EOC-091 Integrations contact detail API key with contact read 1. `GET /api/integrations/v1/contacts/{id}` for email-only `phone` omitted or null per schema Medium
EOC-092 CSV export email-only row Email-only contact exists 1. Export contacts CSV Row has empty phone cell, email populated Medium

Observability (logs)

IDTest CasePreconditionsStepsExpected ResultPriority
EOC-100 Email-only create log Create via API/form 1. Create email-only contact 2. Search logs `contact_created_email_only` Log line with `org_id`, `contact_id` (no PII) Medium
EOC-101 Campaign skip log EOC-050 1. Build campaign recipients 2. Search `campaign_skipped_undeliverable` `channel=whatsapp`, `contact_id`, `campaign_id` Medium
EOC-102 Form collision log Two contacts; submit form with conflicting phone+email 1. Submit public form matching collision scenario 2. Search `identity_collision` Warning logged with both contact IDs; form still returns 200 Medium

Explicitly out of scope (do not file bugs)

No test cases yet.

Sign-off checklist

No test cases yet.