Case Study: Building a Multi-Tenant AI Support Platform with Human Handoff

Executive Summary
Deploying AI chatbots in enterprise support environments requires solving two non-negotiable engineering challenges: strict tenant data isolation and a deterministic human escalation protocol. If an AI agent hallucinates or faces a complex inquiry, it must gracefully pause itself and route the issue to a human support agent without losing chat context.
This case study breaks down an MVP platform built with Next.js (App Router), Supabase (SSR Auth & Row Level Security), and the Vercel AI SDK. It allows admins to manage multi-tenant bots, restrict deployment via domain allowlists, and handle live agent handoffs in real-time.
The Core Challenges
1. Zero-Data-Leak Multi-Tenancy
In a multi-tenant SaaS, customer support logs contain sensitive PII (Personally Identifiable Information). Relying solely on application-level WHERE tenant_id = x filters in SQL queries is risky. A single missing condition in a route handler can leak customer data across organizations.
2. Graceful AI-to-Human Escalation
AI agents should not attempt to handle 100% of tickets. When users request a human or express high frustration, the system must:
- Intent Detection: Automatically identify the user's request for a human or signs of frustration.
- Instant Flagging: Highlight the ticket immediately in the real-time agent dashboard.
- Automated Pause: Turn off AI replies on that thread to prevent bot-human response collisions.
Architecture & Security Model
+-------------------------------------------------------------------+
| CLIENT EMBEDDABLE WIDGET (Vanilla CSS) |
| - Domain Allowlist Checked via SSR Middleware |
+-------------------------------------------------------------------+
│
▼
+-------------------------------------------------------------------+
| NEXT.JS APP ROUTER BACKEND |
| - Vercel AI SDK Engine + Native Tool Calling |
| - Real-Time Live Inbox Workspace for Human Support Agents |
+-------------------------------------------------------------------+
│
▼
+-------------------------------------------------------------------+
| SUPABASE DATABASE & RLS LAYER |
| - Strict Row Level Security Policies (auth.uid() = tenant_id) |
| - Real-Time Subscription Channels for Live Inbox Overrides |
+-------------------------------------------------------------------+Key Technical Implementations
1. Database Protection via Supabase Row Level Security (RLS)
Instead of handling authorization purely in Next.js API routes, security policies were pushed down directly to the PostgreSQL database layer using PLpgSQL Policies.
Even if a client attempts to query the database directly, Supabase enforces that users can only view or mutate records belonging to their authenticated tenant ID:
-- Enforcing Tenant Isolation on Chat Messages Table
ALTER TABLE public.chat_messages ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Tenants can only access their own organization messages"
ON public.chat_messages
FOR ALL
USING (
tenant_id = (
SELECT org_id FROM public.users
WHERE id = auth.uid()
)
);2. Native AI-to-Human Handoff via Tool Calling
Using the Vercel AI SDK, the assistant was equipped with a custom escalation tool. When the LLM detects that an inquiry requires human intervention, it executes escalateToHumanAgent():
// Vercel AI SDK Tool Calling Setup for Escalation
import { createTool } from 'ai';
import { z } from 'zod';
export const escalateToHumanTool = createTool({
description: 'Trigger this tool when the user explicitly asks for a human agent or when the issue cannot be resolved by AI.',
parameters: z.object({
ticketId: z.string().describe('The active ticket UUID'),
reason: z.string().describe('Brief explanation of why escalation is required'),
}),
execute: async ({ ticketId, reason }) => {
// 1. Update ticket status in Supabase
await supabase
.from('tickets')
.update({
status: 'escalated',
ai_paused: true,
escalation_reason: reason
})
.eq('id', ticketId);
// 2. Trigger Real-Time Notification to Agent Workspace
return {
success: true,
message: "I have flagged this conversation for a human agent. Our team will take over shortly.",
};
},
});3. Real-Time Agent Inbox Workspace
When a ticket is escalated:
- 1.The Supabase Realtime channel pushes the update to the support agent dashboard.
- 2.The agent inspects the full conversation context up to the escalation point.
- 3.The agent types a response directly into the live inbox, manually overriding the chat thread.
- 4.Once resolved, the agent can toggle
ai_paused = falseto return control to the AI bot.
4. Lightweight Embeddable Widget
To ensure the chatbot widget loads blazingly fast on external client websites without slowing down their page speeds:
- Lightweight Bundle: Avoided heavy UI frameworks to keep the total embed script size under 10kB.
- Vanilla Styling: Built using Vanilla CSS Modules to ensure maximum flexibility and fast loading.
- Domain Allowlists: Verifies the embedding origin header on SSR middleware before serving configuration.
Results & Production Links
The application is deployed on Vercel with real-time Supabase database bindings.
- Live Application: project-2-beta-silk.vercel.app
- GitHub Repository: github.com/aisquadx5-alt/project-2
Lessons Learned & Future Roadmap
- Security at the Database Layer: Pushing security policies down to Supabase RLS eliminates entire classes of authorization bugs.
- Explicit Escalation Triggers: Equipping the LLM with a dedicated tool to pause itself prevents conversational override loops.
- Extensible Pipeline: Structured to support RAG document parsing and website URL crawling in upcoming updates.
Need an Architecture Built or Automated?
Let's discuss how n8n workflows, custom tool-calling agents, or a modern SaaS MVP can accelerate your business.