AI4ALL MVP — System Architecture Per-tenant SQLite · Docker VPS · WhatsApp-first Layer 1 — WhatsApp Business WhatsApp BotEvolution API Message HandlerWebhook / Router Session Managerconversation_sessions Message QueueInbound / Outbound Layer 2 — Integration WhatsApp GWEvolution API LLM ProviderOpenRouter Adapter Memory ServiceRedis + Vector Calendar AdaptersGoogle / Outlook Layer 3 — Engine Workflow EngineState Machine / Routes Agent RouterIntent → Handler Business ExecutorsScheduling · Cancel · Remind NLU ClassifierIntent Detection Layer 4 — Storage & Infrastructure SQLitePer-tenant DB files RedisCache · Sessions · Queue Docker VPSCompose + Monorepo TraefikTLS · Reverse Proxy Legend WhatsApp Layer External Service Engine / Logic Storage / Data Infrastructure Data Flow

End-to-End: “Quero agendar para amanhãs às 10h”

A patient sends a scheduling request via WhatsApp. Here is what happens at each layer, step by step.

📱 Layer 1 — WhatsApp Business

1
Patient sends WhatsApp message WhatsApp Bot The patient types the message in WhatsApp. Evolution API receives it and fires an HTTPS webhook to our server through Traefik (TLS termination).
2
Webhook receives and routes Message Handler The webhook endpoint parses the payload: extracts phone number, message text, and tenant ID. Normalizes and pushes to the Message Queue for async processing.
3
Session lookup or creation Session Manager Checks SQLite for an active conversation_sessions record for this phone. If found, loads context (state, previous intents). If not, creates a new session with expires_at = now + 30min.
4
Message queued Message Queue The inbound message is enqueued with session context. Decouples webhook reception from processing, ensuring no messages are lost under load.

🔗 Layer 2 — Integration

5
NLU classifies intent LLM Provider + NLU Classifier Message sent to LLM via OpenRouter Adapter with tenant-specific system prompt. Returns structured intent: {intent: “schedule_appointment”, entities: {date: “tomorrow”, time: “10:00”}}.
6
Context retrieved from memory Memory Service Redis checks for recent conversation context (patient name, previous attempts). Vector search retrieves relevant KB entries (clinic hours, doctor specialties). This enriches the next LLM call if clarification is needed.
7
Calendar availability check Calendar Adapters Google Calendar Adapter queries the clinic calendar for available slots on the requested date/time. Returns: slot available at 10:00, or nearest alternatives.

⚙️ Layer 3 — Engine

8
Workflow Engine routes intent Workflow Engine The state machine evaluates current session state and intent. A “schedule_appointment” intent transitions to SCHEDULING state. Determines steps: check availability → confirm with patient → create appointment.
9
Agent Router dispatches Agent Router Intent mapped to SchedulingHandler. Router resolves which executor handles this based on tenant config and intent type.
10
Business logic executes Business Executors SchedulingExecutor: (1) validates slot still available, (2) creates appointment in SQLite with status “confirmed”, (3) writes event to Google Calendar via adapter, (4) generates PT-BR confirmation message.

💾 Layer 4 — Storage & Infrastructure

11
Appointment persisted SQLite Written to tenant DB: appointments table with patient_phone, date, time, status, created_at. Single connection-per-request used for all DB ops in this flow.
12
Session and cache updated Redis Session state updated (moves to COMPLETED). Appointment confirmation cached to avoid redundant DB queries on follow-up.
13
Response delivered via WhatsApp WhatsApp GW Confirmation message sent back through Evolution API. Traefik handles outbound HTTPS. Patient receives reply in WhatsApp within seconds.