# hiberius/whatsapp-receptionist architecture

> Architecture diagram of the GitHub repository hiberius/whatsapp-receptionist, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/hiberius/whatsapp-receptionist
- Repository: https://github.com/hiberius/whatsapp-receptionist

## Overview

#### Purpose and Runtime
WhatsApp Receptionist is a self-hostable, multi-tenant AI receptionist for Italian businesses. It receives WhatsApp text/voice messages, uses AI and tenant knowledge to respond or book Google Calendar appointments, and escalates conversations to human operators. It is a Next.js 15 App Router application running React 19, TypeScript, and Node 22.

Primary HTTP/UI entry points are the public site and route tree in `src/app/page.tsx`, tenant APIs in `src/app/api/`, inbound WhatsApp webhook handling in `src/app/api/webhook/whatsapp/route.ts`, and scheduled internal job routes in `src/app/api/internal/jobs/`.

#### Presentation, Identity, and Tenant Boundary
Route groups separate public marketing, authentication, tenant dashboard, and super-admin surfaces. Dashboard layouts enforce authenticated tenant access; admin is distinct and explicitly incomplete for cross-tenant data access.

- `src/app/(auth)/layout.tsx`
- `src/app/(dashboard)/layout.tsx`
- `src/app/(admin)/layout.tsx`
- `src/middleware.ts`

Supabase Auth supplies SSR-aware sessions. Server business services use a service-role client, so application-level `tenant_id` filtering is currently material; database RLS exists but is not exercised by normal server calls.

#### API-to-Domain Layer
Next Route Handlers are the transport boundary: they validate/authenticate requests and delegate business behavior to `src/server/`, which must not be imported by client components. Dashboard client forms use the internal API rather than directly accessing server services.

- `src/app/api/conversations/[conversationId]/messages/route.ts`
- `src/app/api/settings/services/route.ts`
- `src/server/conversations/operator-messages.ts`
- `src/server/settings/tenant-settings.ts`

Shared API parsing, JSON responses, session guards, rate limits, logging, and request security sit beneath this boundary.

#### WhatsApp Conversation Pipeline
The WhatsApp webhook verifies incoming provider events, resolves the claimed tenant number, persists/processes conversation state, and routes message handling. Auto-replies may be suppressed by opt-out, usage limits, escalation state, or guardrails. Outbound messages are staged in a durable outbox and sent by a cron job with retry/dead-letter behavior, decoupling provider delivery from most request paths.

- `src/app/api/webhook/whatsapp/route.ts`
- `src/server/whatsapp/service.ts`
- `src/server/whatsapp/auto-reply.ts`
- `src/server/whatsapp/outbox.ts`
- `src/app/api/internal/jobs/whatsapp-outbox/route.ts`

360dialog is the WhatsApp Business provider; per-tenant credentials are encrypted at rest. Voice messages flow through media handling and ElevenLabs transcription.

#### AI, Knowledge, and Booking
Reply orchestration builds tenant-specific context and prompts, classifies intent, retrieves semantic knowledge, generates an Anthropic Claude response, and invokes structured booking extraction/bridge when appropriate. Tenant-editable persona text is composed inside non-overridable safety rules. The booking service checks business hours/services and creates protected appointments; calendar integration synchronizes with Google Calendar.

- `src/server/ai/reply-orchestrator.ts`
- `src/server/ai/intent-router.ts`
- `src/server/ai/booking-bridge.ts`
- `src/server/knowledge-base/documents.ts`
- `src/server/appointments/booking.ts`
- `src/server/calendar/google.ts`

#### Persistence, Integrations, and Compliance
Supabase Postgres is the system of record for tenants, conversations, appointments, credentials, usage, audit data, and vector-backed knowledge; SQL migrations define schemas, constraints, and RLS. Google OAuth state is tenant-bound and signed; stored credentials are encrypted. Stripe controls subscription checkout, portal, and webhook lifecycle, with Italian SDI invoicing integration.

- `supabase/migrations/202604240001_initial_backend_mvp.sql`
- `src/server/integrations/google-calendar-oauth.ts`
- `src/server/integrations/credential-encryption.ts`
- `src/server/billing/stripe-billing.ts`
- `src/app/api/webhook/stripe/route.ts`

GDPR export, deletion, and retention are domain services invoked by tenant APIs and authenticated jobs.

#### Operations and Background Work
Vercel-hosted cron routes execute reminders, data retention/deletion, WhatsApp delivery/template/voice work, and health monitoring. Health checks probe critical external dependencies. Resend delivers operational and escalation mail; Upstash Redis supplies endpoint-specific rate limiting; Pino emits PII-redacted structured logs.

- `vercel.json`
- `src/app/api/internal/jobs/appointment-reminders/route.ts`
- `src/app/api/internal/jobs/data-retention/route.ts`
- `src/server/monitoring/health-watchdog.ts`
- `src/lib/health/checks.ts`

Main entry points: [`supabase/migrations/202604240001_initial_backend_mvp.sql`](https://github.com/hiberius/whatsapp-receptionist/blob/main/supabase/migrations/202604240001_initial_backend_mvp.sql) (Supabase Postgres), [`src/app/api/settings/services/route.ts`](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/api/settings/services/route.ts) (Tenant APIs), [`src/server/whatsapp/service.ts`](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/whatsapp/service.ts) (Conversation service), [`src/server/whatsapp/auto-reply.ts`](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/whatsapp/auto-reply.ts) (Auto-reply policy)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_presentation["Presentation &amp; access"]
  node_public["Public site<br/>Next.js page<br/>[page.tsx]"]
  node_access["Tenant access surfaces<br/>route layouts<br/>[layout.tsx]"]
  node_middleware["Session middleware<br/>Next middleware<br/>[middleware.ts]"]
end

subgraph group_api["API &amp; jobs"]
  node_tenant_api["Tenant APIs<br/>route handlers<br/>[route.ts]"]
  node_operator_messages["Operator messaging<br/>domain service"]
  node_outbox_job["Outbox delivery job<br/>internal cron route<br/>[route.ts]"]
  node_stripe_webhook["Stripe webhook<br/>route handler<br/>[route.ts]"]
end

subgraph group_conversation["WhatsApp pipeline"]
  node_webhook["WhatsApp webhook<br/>route handler<br/>[route.ts]"]
  node_whatsapp_service["Conversation service<br/>domain service<br/>[service.ts]"]
  node_auto_reply["Auto-reply policy<br/>domain service<br/>[auto-reply.ts]"]
  node_outbox["Durable message outbox<br/>delivery service<br/>[outbox.ts]"]
end

subgraph group_ai["AI &amp; booking"]
  node_reply_orchestrator["Reply orchestrator<br/>AI service"]
  node_intent_router["Intent router<br/>AI service<br/>[intent-router.ts]"]
  node_knowledge["Tenant knowledge<br/>knowledge service<br/>[documents.ts]"]
  node_booking_bridge["Booking bridge<br/>AI booking service<br/>[booking-bridge.ts]"]
  node_booking["Appointment booking<br/>domain service<br/>[booking.ts]"]
end

subgraph group_data["Data &amp; integrations"]
  node_google_calendar{{"Google Calendar<br/>calendar integration<br/>[google.ts]"}}
  node_postgres[("Supabase Postgres<br/>system of record")]
  node_provider{{"360dialog WhatsApp<br/>external provider"}}
  node_billing["Stripe billing<br/>billing service<br/>[stripe-billing.ts]"]
end

subgraph group_operations["Operations"]
  node_scheduled_jobs["Scheduled operations<br/>internal cron routes<br/>[route.ts]"]
  node_health["Health watchdog<br/>monitoring service<br/>[health-watchdog.ts]"]
end

node_public -->|"uses APIs"| node_tenant_api
node_middleware -->|"protects"| node_access
node_access -->|"dashboard requests"| node_tenant_api
node_tenant_api -->|"delegates"| node_operator_messages
node_tenant_api -->|"tenant-scoped data"| node_postgres
node_webhook -->|"inbound events"| node_whatsapp_service
node_provider -->|"WhatsApp events"| node_webhook
node_whatsapp_service -->|"conversation state"| node_postgres
node_whatsapp_service -->|"routes handling"| node_auto_reply
node_auto_reply -->|"eligible replies"| node_reply_orchestrator
node_auto_reply -->|"stage response"| node_outbox
node_reply_orchestrator -->|"classifies intent"| node_intent_router
node_reply_orchestrator -->|"retrieves context"| node_knowledge
node_intent_router -->|"booking intent"| node_booking_bridge
node_booking_bridge -->|"structured request"| node_booking
node_booking -->|"syncs appointment"| node_google_calendar
node_booking -->|"stores appointment"| node_postgres
node_outbox_job -->|"drains retries"| node_outbox
node_outbox -->|"send message"| node_provider
node_stripe_webhook -->|"subscription events"| node_billing
node_billing -->|"subscription state"| node_postgres
node_scheduled_jobs -->|"retention and reminders"| node_postgres
node_scheduled_jobs -->|"health work"| node_health
node_health -.->|"dependency probe"| node_provider

click node_public "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/page.tsx"
click node_access "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/(dashboard)/layout.tsx"
click node_middleware "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/middleware.ts"
click node_tenant_api "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/api/settings/services/route.ts"
click node_operator_messages "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/conversations/operator-messages.ts"
click node_webhook "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/api/webhook/whatsapp/route.ts"
click node_whatsapp_service "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/whatsapp/service.ts"
click node_auto_reply "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/whatsapp/auto-reply.ts"
click node_outbox "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/whatsapp/outbox.ts"
click node_outbox_job "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/api/internal/jobs/whatsapp-outbox/route.ts"
click node_reply_orchestrator "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/ai/reply-orchestrator.ts"
click node_intent_router "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/ai/intent-router.ts"
click node_knowledge "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/knowledge-base/documents.ts"
click node_booking_bridge "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/ai/booking-bridge.ts"
click node_booking "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/appointments/booking.ts"
click node_google_calendar "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/calendar/google.ts"
click node_postgres "https://github.com/hiberius/whatsapp-receptionist/blob/main/supabase/migrations/202604240001_initial_backend_mvp.sql"
click node_billing "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/billing/stripe-billing.ts"
click node_stripe_webhook "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/api/webhook/stripe/route.ts"
click node_scheduled_jobs "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/api/internal/jobs/appointment-reminders/route.ts"
click node_health "https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/monitoring/health-watchdog.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_public,node_access,node_middleware toneBlue
class node_tenant_api,node_operator_messages,node_outbox_job,node_stripe_webhook toneAmber
class node_webhook,node_whatsapp_service,node_auto_reply,node_outbox toneMint
class node_reply_orchestrator,node_intent_router,node_knowledge,node_booking_bridge,node_booking toneRose
class node_google_calendar,node_postgres,node_provider,node_billing toneIndigo
class node_scheduled_jobs,node_health toneTeal
```

## Components

### Presentation & access

- [Public site](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/page.tsx): Next.js page · `src/app/page.tsx`
- [Tenant access surfaces](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/(dashboard)/layout.tsx): route layouts · Auth, dashboard, and admin are separated route groups. · `src/app/(dashboard)/layout.tsx`
- [Session middleware](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/middleware.ts): Next middleware · `src/middleware.ts`

### API & jobs

- [Tenant APIs](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/api/settings/services/route.ts): route handlers · Authenticated transport boundary for dashboard clients. · `src/app/api/settings/services/route.ts`
- [Operator messaging](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/conversations/operator-messages.ts): domain service · `src/server/conversations/operator-messages.ts`
- [Outbox delivery job](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/api/internal/jobs/whatsapp-outbox/route.ts): internal cron route · `src/app/api/internal/jobs/whatsapp-outbox/route.ts`
- [Stripe webhook](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/api/webhook/stripe/route.ts): route handler · `src/app/api/webhook/stripe/route.ts`

### WhatsApp pipeline

- [WhatsApp webhook](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/api/webhook/whatsapp/route.ts): route handler · Verifies provider events and resolves the tenant number. · `src/app/api/webhook/whatsapp/route.ts`
- [Conversation service](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/whatsapp/service.ts): domain service · Persists and processes WhatsApp conversation state. · `src/server/whatsapp/service.ts`
- [Auto-reply policy](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/whatsapp/auto-reply.ts): domain service · Applies opt-out, usage, escalation, and safety suppression. · `src/server/whatsapp/auto-reply.ts`
- [Durable message outbox](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/whatsapp/outbox.ts): delivery service · Stages outbound delivery with retry and dead-letter behavior. · `src/server/whatsapp/outbox.ts`

### AI & booking

- [Reply orchestrator](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/ai/reply-orchestrator.ts): AI service · Builds tenant context and coordinates reply generation. · `src/server/ai/reply-orchestrator.ts`
- [Intent router](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/ai/intent-router.ts): AI service · `src/server/ai/intent-router.ts`
- [Tenant knowledge](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/knowledge-base/documents.ts): knowledge service · Semantic retrieval over tenant documents. · `src/server/knowledge-base/documents.ts`
- [Booking bridge](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/ai/booking-bridge.ts): AI booking service · Extracts structured booking requests. · `src/server/ai/booking-bridge.ts`
- [Appointment booking](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/appointments/booking.ts): domain service · Checks services and business hours before protected booking. · `src/server/appointments/booking.ts`

### Data & integrations

- [Google Calendar](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/calendar/google.ts): calendar integration · `src/server/calendar/google.ts`
- [Supabase Postgres](https://github.com/hiberius/whatsapp-receptionist/blob/main/supabase/migrations/202604240001_initial_backend_mvp.sql): system of record · Tenant-scoped application queries use service-role access. · `supabase/migrations/202604240001_initial_backend_mvp.sql`
- **360dialog WhatsApp**: external provider · Tenant credentials are encrypted at rest.
- [Stripe billing](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/billing/stripe-billing.ts): billing service · Checkout, portal, and subscription lifecycle. · `src/server/billing/stripe-billing.ts`

### Operations

- [Scheduled operations](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/app/api/internal/jobs/appointment-reminders/route.ts): internal cron routes · Runs reminders, retention, health, template, and voice work. · `src/app/api/internal/jobs/appointment-reminders/route.ts`
- [Health watchdog](https://github.com/hiberius/whatsapp-receptionist/blob/main/src/server/monitoring/health-watchdog.ts): monitoring service · Probes critical external dependencies. · `src/server/monitoring/health-watchdog.ts`

## Connections

- Public site → Tenant APIs: uses APIs
- Session middleware → Tenant access surfaces: protects
- Tenant access surfaces → Tenant APIs: dashboard requests
- Tenant APIs → Operator messaging: delegates
- Tenant APIs → Supabase Postgres: tenant-scoped data
- WhatsApp webhook → Conversation service: inbound events
- 360dialog WhatsApp → WhatsApp webhook: WhatsApp events
- Conversation service → Supabase Postgres: conversation state
- Conversation service → Auto-reply policy: routes handling
- Auto-reply policy → Reply orchestrator: eligible replies
- Auto-reply policy → Durable message outbox: stage response
- Reply orchestrator → Intent router: classifies intent
- Reply orchestrator → Tenant knowledge: retrieves context
- Intent router → Booking bridge: booking intent
- Booking bridge → Appointment booking: structured request
- Appointment booking → Google Calendar: syncs appointment
- Appointment booking → Supabase Postgres: stores appointment
- Outbox delivery job → Durable message outbox: drains retries
- Durable message outbox → 360dialog WhatsApp: send message
- Stripe webhook → Stripe billing: subscription events
- Stripe billing → Supabase Postgres: subscription state
- Scheduled operations → Supabase Postgres: retention and reminders
- Scheduled operations → Health watchdog: health work
- Health watchdog → 360dialog WhatsApp: dependency probe
