Skip to main content

System Architecture Design Document (SADD): OxaWay

Project: OxaWay – Multi-Tenant AI Travel Concierge
Host: oxaway.ai
Version: 1.0 (Phase 1 MVP)
Date: 5 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) 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: Handles Postgres, Vector Search (pgvector), and Realtime WebSockets out of the box.
Cons: Vendor tie-in for Auth/Realtime features.
OrchestratorTrigger.dev (v3)Cloud (Managed)Pros: Durable, code-first TypeScript workflows; reliable for long-running processes (bookings).
Cons: External dependency for core logic execution.
AI LogicFlowiseSelf-HostedPros: Visual RAG builder; enables "No-Code" adjustments to prompts without redeploying code.
Cons: Node-based runtime can be memory hungry.
Chat BuilderTypebotSelf-HostedPros: Visual flow builder; allows full white-labeling via bot.oxaway.ai.
Cons: Iframe embed limits deep CSS customization.
FrontendReact WrapperVercel / NetlifyPros: Custom widget toggling between AI (Typebot) and Human (Custom UI).

3. Architecture Diagrams

3.1 High-Level System Flow (Hexagonal)

The user interacts with a single widget. The backend routes the conversation based on the active "Mode" (Bot vs. Human).

3.2 Multi-Tenancy Data Model

The system supports a 3-tier hierarchy: Tenant (The Payer) -> Property (The Asset) -> Session (The Chat).


4. Implementation Detail: The "Wrapper" Pattern

Instead of building a fully headless UI immediately (which is expensive and slow), we use a Wrapper Component to speed up development.

  1. Default State: Renders the standard Typebot embed (Iframe).
  2. Monitoring: Subscribes to Supabase Realtime for the specific session_id.
  3. Handover Event: When session.status changes to human_active:
    • The Wrapper unmounts the Typebot component.
    • The Wrapper mounts the custom React Chat Interface.
  4. Reverse Handover: When the agent clicks "Resolve," the Wrapper swaps back to Typebot to trigger a "Anything else?" flow.

5. Operational Workflows

5.1 Onboarding New Tenants

  • Tool: Trigger.dev Task (onboard-tenant).
  • Process:
    1. Create Stripe Customer via API.
    2. Create Tenant Record in Supabase with stripe_id.
    3. Set Usage Limits (e.g., 500 chats/mo) in the database JSON column.
    4. Send Welcome Email with magic login link.

5.2 Multi-Property Context

To ensure the bot knows which villa the guest is viewing, we pass context via the URL.

  1. URL Parameter: The widget is embedded with ?property_id=villa_123.
  2. Typebot Variable: Typebot reads this into a system variable.
  3. Flowise Filter: When executing RAG, Flowise filters vectors where metadata.propertyId == villa_123.

6. Repository Structure (Monorepo)

Managed via TurboRepo to ensure type safety across the stack.

  • apps/dashboard: Next.js 14. The Agent Inbox and Admin Panel.
  • apps/widget: Vite + React. The embeddable bundle script for clients.
  • packages/trigger: Trigger.dev (v3). The backend business logic and scheduled tasks.
  • packages/database: Prisma. Shared schema and Supabase client type definitions.

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

Every architectural choice incurs a cost. Here is the analysis for OxaWay:

A. The Wrapper Pattern vs. Headless UI

  • Decision: Use a Wrapper around the Typebot Iframe.
  • Benefit: Reduces frontend dev time by ~60%. We utilize Typebot's native UI for 90% of interactions.
  • The Tax (Cost): User Experience friction. Switching from Iframe (Bot) to Custom UI (Human) may cause a slight visual "flicker" or layout shift. Maintaining state sync between the Iframe and the parent window requires robust window.postMessage handling.

B. Hybrid Hosting (Hetzner + Cloud)

  • Decision: Host stateless compute on Hetzner; State/Data on Cloud (Supabase).
  • Benefit: Best of both worlds. Cheap compute for heavy lifting (Flowise/Typebot) but managed reliability for the database.
  • The Tax (Cost): Latency and Security. We introduce network hops between Germany (Hetzner) and the Supabase region. We must meticulously manage firewall rules to ensure only our Hetzner IPs can access the Supabase DB directly if using connection pooling.

C. Trigger.dev (Cloud)

  • Decision: Use the managed Cloud version of Trigger.dev for Phase 1.
  • Benefit: Zero infrastructure maintenance for the task queue. Guaranteed delivery of webhooks.
  • The Tax (Cost): Dependency. If we need to move off-cloud later (for data sovereignty or cost), we must provision a heavy Redis/Postgres infrastructure to self-host Trigger.dev v3.

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.