AI-prompt
You are a Senior Full-Stack Engineer and System Architect. Your task is to scaffold the initial codebase for "OxaWay," a B2B SaaS AI Concierge platform for the hospitality industry.
We are adhering to a strict System Architecture Design Document (SADD). Please read the following context and requirements carefully before generating any code.
1. Project Structure (Monorepo)
We will use TurboRepo for monorepo management. The structure must be:
apps/dashboard: Next.js 14 (App Router) for the Tenant Admin Panel (Agents/Admins).apps/widget: Vite + React for the embeddable chat widget script (Client-facing).packages/database: Shared Prisma schema and Supabase client configuration.packages/trigger: Trigger.dev (v3) workflow definitions for backend business logic.packages/ui: Shared UI components (Shadcn/UI).
2. Core Technology Stack
- Language: TypeScript (Strict mode).
- Database: Supabase (PostgreSQL) with
pgvectorenabled. - ORM: Prisma.
- Orchestration: Trigger.dev (v3) Cloud.
- Chat Engine: Typebot (Self-hosted via iframe).
- AI Logic: Flowise (Self-hosted API).
- State Management: Supabase Realtime (for session status sync).
3. The "Wrapper Pattern" Requirement (CRITICAL)
The apps/widget application is NOT a standard chat UI. It is a Wrapper Component that orchestrates the user experience. It must implement the following logic:
- Default State: Render the Typebot Standard Embed (via Iframe) for AI automation.
- Context Injection: It must parse the URL parameters (e.g.,
?property_id=123) and pass them as "Hidden Variables" to the Typebot instance. - Real-time Listener: On mount, subscribe to Supabase Realtime for the current
session_id. - Handover Logic:
- Listen for changes to the
statuscolumn in theSessiontable. - IF
statuschanges to'human_active', unmount the Typebot Iframe and mount a custom React Chat Interface (using Supabase for messages). - IF
statuschanges back to'resolved', swap back to the Typebot Iframe to trigger a feedback flow.
- Listen for changes to the
4. Data Model (Multi-Tenancy)
In packages/database/prisma/schema.prisma, define the following 3-tier hierarchy:
- Tenant: (e.g., "Emma Villas") -> Includes
stripe_id,config(JSON). - Property: (e.g., "Villa Corbaia") -> Belongs to Tenant. Includes
property_id(external ID),name,knowledge_base_id(Flowise ID). - Session: (The Chat) -> Belongs to Property. Includes
status(enum:ai_active,human_active,resolved),guest_info(JSON),platform(enum:web,whatsapp).
5. Implementation Steps
Please generate the shell commands to initialize the TurboRepo and then provide the code for the following key files:
Step A: Database Schema
- Write the
schema.prismafile implementing the hierarchy above.
Step B: The Widget Wrapper (apps/widget/src/App.tsx)
- Write the React component that handles the conditional rendering between the Typebot embed and the custom Human Chat UI based on Supabase Realtime events.
- Note: Do not fully implement the "Human Chat UI" yet, just a placeholder component. Focus on the switching logic.
Step C: Trigger.dev Setup (packages/trigger/src/trigger.ts)
- Initialize the Trigger.dev client.
- Create a placeholder task
onboard-tenantthat simulates creating a Stripe customer and inserting a Tenant into Supabase.
Constraints:
- Do not hardcode secrets. Use
process.env. - Ensure strict logical isolation (Row Level Security ideas can be commented, but enforce tenant_id in Prisma queries).
- Use functional React components with Hooks.
Start by proposing the folder structure and the schema.prisma.