Skip to main content

System Architecture Design Document (SADD): OxaWay

Project: OxaWay – Multi-Tenant AI Travel Concierge
Host: oxaway.ai
Version: 1.1 (Pilot Phase + WhatsApp)
Date: 6 February 2026
Status: Implementation / Infrastructure Setup


1. Executive Summary

OxaWay is a white-label B2B SaaS platform providing "AI Concierge" services to the hospitality industry. The system automates guest inquiries via Retrieval-Augmented Generation (RAG) and facilitates a seamless, invisible handover to human agents for complex issues.

Core Architectural Philosophy

  • Multi-Tenancy: Single codebase serving multiple tenants (e.g., Emma Villas, Agencies) with strict logical data isolation.
  • Licensing Safety: Core logic resides in owned code (Trigger.dev/Next.js) or permissive open-source tools (Flowise/Typebot/Evolution API) to avoid restrictive "Fair-code" licensing traps during resale.
  • Cost Efficiency: High-leverage use of Hetzner VPS for compute (fixed cost) and Supabase for managed data (serverless scale).

2. The Technology Stack

ComponentTechnologyHosting StrategyRationale & Trade-offs
Hosting & DevOpsHetzner + CoolifySelf-Hosted (Germany)Pros: GDPR compliance, extremely low fixed cost (~€15/mo), "Vercel-like" DX.
Cons: You own the uptime; requires manual backup config.
DatabaseSupabaseCloud (Managed)Pros: Auth, Vector DB (pgvector), and Realtime WebSocket built-in.
Cons: Vendor lock-in for Auth/Realtime features.
Orchestrator (Chat)TypebotSelf-Hosted (Coolify)Pros: Visual state machine; handles "Human Handoff" logic perfectly.
Cons: Stateless by default; needs external DB for long-term memory.
WhatsApp GatewayEvolution APISelf-Hosted (Coolify)Pros: MIT License (safe for resale); Supports multi-device & massive scale.
Cons: High RAM usage; 24h WhatsApp rule must be managed externally.
AI IntelligenceFlowiseSelf-Hosted (Coolify)Pros: Drag-and-drop RAG; easy to swap LLMs (OpenAI $\to$ Anthropic).
Cons: Not designed for chat routing/logic (that's why we use Typebot).
Job QueueTrigger.devCloud (Managed)Pros: Resilient background jobs (scraping, onboarding) with auto-retries.
Cons: Cloud dependency (latency US $\leftrightarrow$ EU).

3. Architecture Diagrams

3.1 High-Level System Flow (Hexagonal)

This diagram illustrates how Typebot acts as the central router, normalizing inputs from both the Web Widget and WhatsApp (via Evolution API) before consulting the AI Brain (Flowise).

3.2 Multi-Tenancy Data Model

We utilize Row Level Security (RLS) in Supabase. Every query must include the tenant_id.

  • Tenants Table: id (UUID), name, config (JSONB).
  • Chat Sessions: id, tenant_id (FK), platform (Web/WhatsApp), is_human_active (BOOL).
  • WhatsApp Instances: tenant_id, instance_token, status.

4. Implementation Detail: The "Wrapper" Patterns

4.1 The Web Wrapper (Next.js)

A lightweight React component that wraps the Typebot standard library. It handles:

  1. Authentication: verifying the user is allowed to chat (optional).
  2. Context Injection: Passing page_url or user_id to Typebot as hidden variables.
  3. Human Toggle: Listening to Supabase Realtime changes to hide the bot input and show a "Agent is typing..." indicator.

4.2 The WhatsApp Pipeline (Evolution API)

Since WhatsApp users have no "Frontend," Typebot acts as the logic wrapper.

  1. Ingestion: Evolution API receives the message $\to$ Webhook to Typebot.
  2. Normalization: Typebot formats the incoming phone number and extracts the name.
  3. Routing:
    • If is_human_active = true: Typebot posts the message to Supabase (inbox) and stops.
    • If is_human_active = false: Typebot calls Flowise API.
  4. Response: Flowise returns text $\to$ Typebot formats it (e.g., handles bolding *text*) $\to$ Typebot calls Evolution API sendText endpoint.

5. Operational Workflows

5.1 Onboarding New Tenants (Automated)

We use Trigger.dev to execute a resilient onboarding transaction:

  1. Create Tenant row in Supabase.
  2. Provision WhatsApp: Call Evolution API to create a new instance named {tenant_id}.
  3. Link Webhook: Configure the new instance to send events to the Master Typebot URL.
  4. Generate Keys: Store the secure instance_token in Supabase vault.
  5. Return QR: Display the QR code in the Super-Admin Dashboard for the client to scan.

5.2 Multi-Property Context

Flowise does not natively support multi-tenancy in a single Chatflow.

  • Strategy: We pass metadata_filter = { "tenant_id": "xyz" } from Typebot to Flowise.
  • Vector Store: All documents live in one vector collection but are strictly partitioned by this metadata field during retrieval.

6. Repository Structure (Monorepo)

/apps
/web # Next.js Dashboard & Widget Wrapper
/docs # This documentation site
/packages
/database # Supabase schema & migrations
/trigger # Trigger.dev background jobs (WhatsApp provisioning)
/shared # TS Types shared between Web and Trigger

7. The Architect's Tax (Trade-off Analysis)

Every architectural choice comes with a cost. These are the accepted risks for the Pilot.

A. The Wrapper Pattern vs. Headless UI

  • Trade-off: Using the "Standard" Typebot embed is faster to build but limits UI customization.
  • Tax: We might struggle with complex custom UI elements (e.g., a "Date Picker" that looks exactly like the client's brand) inside the chat bubble.

B. Single VPS (Hetzner)

  • Trade-off: Running everything on one box saves ~€200/mo but creates a Single Point of Failure (SPOF).
  • Tax: If the server hardware fails, all tenants go offline. Mitigation: Daily snapshots.

C. Trigger.dev (Cloud)

  • Trade-off: Using Managed Cloud guarantees delivery but introduces latency.
  • Tax: A WhatsApp message might take 1-2s extra round trip due to the US $\leftrightarrow$ EU hop for background processing (if used for message handling). Note: Direct chat flow goes Hetzner internal (fast), only onboarding uses Cloud.

D. Evolution API (WhatsApp)

  • Trade-off: Self-hosting the WhatsApp gateway avoids per-message fees (Meta BSPs) but requires resource management.
  • Tax:
    1. Memory: Headless Chrome (Baileys) is RAM hungry. We must monitor memory leaks.
    2. Stability: WhatsApp Web protocol changes occasionally. We must keep Evolution API updated or the connection might break.
    3. 24h Rule: We are responsible for strictly blocking outgoing marketing messages outside the 24h window to avoid getting the number banned.

8. Future Roadmap (Phase 2)

  1. Audit Logs: Implement an audit_logs table for compliance (tracking who changed bot settings/prompts).
  2. Headless UI: Migrate from the "Wrapper" to a fully custom "Headless" UI using @typebot.io/js for 100% seamless unified streams.
  3. Voice Integration: Enable Flowise "Whisper" nodes for Audio-to-Text processing to support voice notes on WhatsApp.