How danushrajaram/ai-medical-voice-agent works
Purpose and Runtime
This is a Next.js 14 App Router application for voice-based, AI-assisted medical consultations. Authenticated users select a doctor specialization, create a consultation session from symptoms, and conduct a VAPI voice conversation backed by Gemini 2.0 Flash through OpenRouter. The main runtime starts through Next.js pages and route handlers under app/; deployment targets Vercel.
Application Entry and Route Topology
The public landing entry is app/page.tsx, wrapped by global shell and styling in app/layout.tsx and app/globals.css. Authentication routes are isolated in app/(auth)/sign-in/[[...sign-in]]/page.tsx and app/(auth)/sign-up/[[...sign-up]]/page.tsx. The authenticated product surface begins at app/(routes)/dashboard/page.tsx, with a dashboard layout at app/(routes)/dashboard/layout.tsx.
Identity Boundary
Clerk provides Google/phone authentication and establishes the user boundary before dashboard use. Auth provider integration is located in app/(auth)/provider.tsx; request-level route protection is likely centralized in middleware.ts. The application exposes a user API endpoint at app/api/users/route.tsx, which is the server boundary for persisting or retrieving application-specific user data separate from Clerk identity.
Dashboard, Doctor Selection, and Session Creation
The dashboard composes doctor discovery, suggested doctors, prior consultation history, and session initiation. Its central UI components are app/(routes)/dashboard/_components/DoctorsAgentList.tsx, app/(routes)/dashboard/_components/AddNewSessionDialog.tsx, and app/(routes)/dashboard/_components/HistoryList.tsx. User context is shared client-side through context/UserDetailContext.tsx. The resulting session is navigated to the dynamic consultation route app/(routes)/dashboard/medical-agent/[sessionId]/page.tsx.
AI Consultation Boundary
Server-side API routes separate UI interaction from external AI services. app/api/session-chat/route.tsx handles session chat/consultation requests, while app/api/suggest-doctors/route.tsx generates or retrieves doctor recommendations. Model client/configuration resides in config/OpenAiModel.tsx; despite its name, the README identifies Gemini 2.0 Flash accessed through OpenRouter as the reasoning backend. VAPI is the external real-time voice layer invoked by the consultation experience.
Persistence and Session History
Neon PostgreSQL is accessed through Drizzle ORM. Database connection and schema definitions are concentrated in config/db.tsx and config/schema.tsx; versioned schema evolution is represented by drizzle/0000_cute_queen_noir.sql and drizzle/0001_optimal_firestar.sql. This persistence layer stores patient/application context and supports session history displayed in the dashboard.
Primary Flow
A visitor enters app/page.tsx, signs in via Clerk, and reaches the dashboard. They select a doctor and submit symptoms through the session dialog; the client calls server APIs to create or enrich the consultation context, persists it through Drizzle/PostgreSQL, then routes to the session-specific medical-agent page. That page connects the selected persona and session context to VAPI voice interaction and the OpenRouter/Gemini reasoning path. Completed or existing sessions feed back into dashboard history.
Main entry points: dashboard/page.tsx Dashboard · db.tsx Drizzle database layer · route.tsx Session chat API · [sessionId]/page.tsx Voice consultation
Components 23
Next.js UI
App Router pages and client components.
- Landing page
app/page.tsx - Global app shell
app/layout.tsx - Sign-in / sign-up
app/(auth)/sign-in/[[...sign-in]]/page.tsx - Clerk provider
app/(auth)/provider.tsx - Route protection
middleware.ts - Dashboard · Composes discovery, history, and session initiation.
app/(routes)/dashboard/page.tsx - Dashboard layout
app/(routes)/dashboard/layout.tsx - Doctor discovery
app/(routes)/dashboard/_components/DoctorsAgentList.tsx - New session dialog · Collects doctor selection and symptoms.
app/(routes)/dashboard/_components/AddNewSessionDialog.tsx - Consultation history
app/(routes)/dashboard/_components/HistoryList.tsx - Voice consultation
app/(routes)/dashboard/medical-agent/[sessionId]/page.tsx - User detail context
context/UserDetailContext.tsx
Server APIs
Route handlers and AI integration.
- User API · Persists or retrieves application-specific user data.
app/api/users/route.tsx - Doctor suggestions API
app/api/suggest-doctors/route.tsx - Session chat API · Builds consultation context for AI interactions.
app/api/session-chat/route.tsx - OpenRouter model client · Uses Gemini 2.0 Flash as the reasoning backend.
config/OpenAiModel.tsx
Data Layer
Application persistence and migrations.
- Drizzle database layer · Accesses Neon PostgreSQL and defines persisted records.
config/db.tsx - Schema migrations
drizzle/0000_cute_queen_noir.sql
External Services
Identity, voice, model, and hosting providers.
- Clerk · Google and phone authentication.
- VAPI · Real-time voice conversation layer.
- Gemini 2.0 Flash · Accessed through OpenRouter.
- Neon PostgreSQL
- Vercel
Connections 24
- Landing page → Sign-in / sign-up: sign in
- Global app shell → Landing page: wraps
- Clerk provider → Clerk: authenticates with
- Route protection → Dashboard: protects
- Sign-in / sign-up → Dashboard: authenticated access
- Dashboard layout → Dashboard: wraps
- Dashboard → Doctor discovery: shows
- Dashboard → New session dialog: opens
- Dashboard → Consultation history: shows
- Dashboard → User detail context: uses
- Doctor discovery → Doctor suggestions API: requests suggestions
- New session dialog → Session chat API: submits symptoms
- Session chat API → Voice consultation: creates session
- Dashboard → Voice consultation: navigates by session ID
- Voice consultation → VAPI: starts voice session
- Session chat API → OpenRouter model client: requests reasoning
- Doctor suggestions API → OpenRouter model client: generates recommendations
- OpenRouter model client → Gemini 2.0 Flash: via OpenRouter
- User API → Drizzle database layer: reads and writes
- Session chat API → Drizzle database layer: persists session context
- Consultation history → Drizzle database layer: loads sessions
- Drizzle database layer → Neon PostgreSQL: connects to
- Schema migrations → Drizzle database layer: evolves schema
- Vercel → Global app shell: deploys application