Skip to content

fix(voice): harden destination parsing and phone matching#46

Merged
ByteStreams-AI merged 2 commits intomainfrom
fix/vapi-call-start-hardening
May 6, 2026
Merged

fix(voice): harden destination parsing and phone matching#46
ByteStreams-AI merged 2 commits intomainfrom
fix/vapi-call-start-hardening

Conversation

@ByteStreams-AI
Copy link
Copy Markdown
Owner

@ByteStreams-AI ByteStreams-AI commented May 6, 2026

Refs #44

Hardens vapi call-start by:

  • accepting destination phone in both nested and direct payload shapes
  • normalizing destination and stored restaurant phone formats before lookup

Prevents brittle call-start failures caused by format/schema drift.

Greptile Summary

This PR hardens the Vapi call-start handler against phone number format and payload schema drift. The restaurant phone lookup is switched from an exact DB match to a normalized candidate query, and the destination phone extraction now handles both phoneNumber.number (nested) and phoneNumber (direct string) payload shapes.

  • context.ts: lookupRestaurantByDestination now generates 2–3 normalized candidate strings via phoneLookupCandidates, queries with .in('phone_number', candidates) (preserving the DB index), then applies normalizeUsE164ish in-memory to confirm the match. A warning is emitted when multiple restaurants normalize to the same destination number.
  • index.ts: Three new fallback paths are added to firstString(...) for destinationPhone, covering Vapi payloads where phoneNumber is a raw string instead of an object. The validation error message is updated to describe all accepted shapes.

Confidence Score: 5/5

Safe to merge — the lookup change preserves DB-side filtering and the new fallback paths in the webhook handler are correctly guarded by type-checking within deepReadString.

Both changes are narrowly scoped defensive fixes. The DB query now uses .in() over a small, bounded candidate list, restoring index usage. The new phoneNumber-as-string fallbacks only activate when typeof value === 'string', so they cannot accidentally capture object payloads. The normalization logic is correct for all US E164 variants (10-digit, 11-digit with leading 1, +-prefixed). No regressions are introduced to the existing happy path.

No files require special attention.

Important Files Changed

Filename Overview
supabase/functions/_shared/context.ts Replaces exact-match DB query with .in() over normalized candidate variants; adds in-memory normalization filter and multi-match warning. The full-table-scan concern from the previous review is addressed.
supabase/functions/vapi_call_start/index.ts Adds three new fallback paths that read phoneNumber as a direct string (not phoneNumber.number object). Error message updated to reflect the broader accepted shapes. Logic is correct — deepReadString returns null for object values, so the new paths only fire for string payloads.

Comments Outside Diff (1)

  1. supabase/functions/vapi_call_start/index.ts, line 159 (link)

    P2 The error message still references only phoneNumber.number, but this PR adds three new fallback paths that accept phoneNumber as a direct string. Callers who hit the validation guard will get a misleading message that doesn't mention the new accepted shapes.

Reviews (2): Last reviewed commit: "fix(voice): address PR #46 review on loo..." | Re-trigger Greptile

Comment thread supabase/functions/_shared/context.ts
@ByteStreams-AI
Copy link
Copy Markdown
Owner Author

Addressed review feedback in 1b22cac:

  • Replaced full-table active restaurant fetch with DB-side phone_number IN (...) lookup candidates to avoid O(n) hot-path behavior.
  • Updated assistant-request validation error message to mention both accepted destination shapes (phoneNumber.number and phoneNumber string).

pnpm ci:fast passes locally (299/299).

@ByteStreams-AI ByteStreams-AI merged commit 5e9f45a into main May 6, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant