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
| Component | Technology | Hosting Strategy | Rationale & Trade-offs |
|---|---|---|---|
| Hosting & DevOps | Hetzner + Coolify | Self-Hosted (Germany) | Pros: GDPR compliance, extremely low fixed cost (~€15/mo), "Vercel-like" DX. Cons: You own the uptime; requires manual backup config. |
| Database | Supabase | Cloud (Managed) | Pros: Handles Postgres, Vector Search (pgvector), and Realtime WebSockets out of the box. Cons: Vendor tie-in for Auth/Realtime features. |
| Orchestrator | Trigger.dev (v3) | Cloud (Managed) | Pros: Durable, code-first TypeScript workflows; reliable for long-running processes (bookings). Cons: External dependency for core logic execution. |
| AI Logic | Flowise | Self-Hosted | Pros: Visual RAG builder; enables "No-Code" adjustments to prompts without redeploying code. Cons: Node-based runtime can be memory hungry. |
| Chat Builder | Typebot | Self-Hosted | Pros: Visual flow builder; allows full white-labeling via bot.oxaway.ai.Cons: Iframe embed limits deep CSS customization. |
| Frontend | React Wrapper | Vercel / Netlify | Pros: 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.
- Default State: Renders the standard Typebot embed (Iframe).
- Monitoring: Subscribes to Supabase Realtime for the specific
session_id. - Handover Event: When
session.statuschanges tohuman_active:- The Wrapper unmounts the Typebot component.
- The Wrapper mounts the custom React Chat Interface.
- 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:
- Create Stripe Customer via API.
- Create Tenant Record in Supabase with
stripe_id. - Set Usage Limits (e.g., 500 chats/mo) in the database JSON column.
- 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.
- URL Parameter: The widget is embedded with
?property_id=villa_123. - Typebot Variable: Typebot reads this into a system variable.
- 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.postMessagehandling.
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)
- Audit Logs: Implement an
audit_logstable for compliance (tracking who changed bot settings/prompts). - Headless UI: Migrate from the "Wrapper" to a fully custom "Headless" UI using
@typebot.io/jsfor 100% seamless unified streams. - Voice Integration: Enable Flowise "Whisper" nodes for Audio-to-Text processing to support voice notes on WhatsApp.