Hayaat Intake AI
Voice and SMS intake for Medicaid home-help
A Next.js 16 App Router application for a Michigan Medicaid home-help agency. Vapi voice intake, Twilio SMS with OpenAI tool-calling, and Supabase (Postgres, Auth, Storage) power public intake plus a staff admin console gated by middleware and SSR sessions.

The Challenge
Intake was manual and fragmented: phone-heavy triage, inconsistent capture of client versus caregiver context, and slow handoff into applications and staff workflows. Every channel produced its own island of data.
Engineering Architecture
- App Router with server componentsAuth-sensitive reads stay on the server, while interactive widgets — the Vapi call button, chat widget, and Kanban board — are isolated as client components.
- Middleware scoped to /admin/*Public intake and landing pages stay frictionless; only staff surfaces pay the cost of session refresh and redirect.
- Service-role Supabase inside webhooksTwilio and Vapi hit server-only routes where the service role bypasses RLS for trusted writes. The tradeoff is deliberate: correctness lives in application code, not client queries.
- Recursive payload parsing for VapiVapi end-of-call payloads vary in shape. Deep key lookup makes the integration resilient to schema drift without redeploying the assistant.
- Signed-URL document routeA private storage bucket with short-lived redirects avoids exposing raw paths and supports compliance-minded access to PHI documents.
Technical Wins
- Resilient Vapi to CRM and SMS handoffThe webhook ignores non-terminal events, extracts caller metadata from nested JSON, upserts clients or caregivers by phone, fires a non-blocking application-link SMS, and writes intake logs — returning fast while downstream work continues.
- Retroactive message linkingWhen the model invokes create_lead, the server upserts the client and then backfills earlier message rows that matched the session or phone number but had no client attached, repairing anonymous threads once identity is disclosed.
- Middleware session hygieneInvalid refresh tokens are cleared before redirecting to login, which cuts stuck sessions and the support churn they generate for staff.




