#002Everwood BookingLearningIntermediate

My First Real Architecture for an AI Booking SaaS

How the architecture for an AI booking widget grew out of real product problems, not a wish list of trendy tools.

By the Everwood founder · June 22, 2026 · 7 min read

Tools
Next.jsSupabaseOpenAITypeScript
Concepts
System ArchitectureMulti-TenantTool CallingState ManagementBooking Flow
Mission Brief
Goal

Design an architecture that supports an AI booking assistant, a business dashboard, and multi-tenant data isolation in a single project.

Problem

The product needed more than a chatbot. It needed a database-driven booking system with an AI layer that could query real business data and take real actions.

Lesson

The architecture should grow from product requirements. Picking tools before understanding the problem costs you months.

Read as

The Build

After deciding to build an AI booking widget for local businesses, I needed to figure out how the pieces would actually fit together. This was not just a chat interface. It needed a customer-facing widget, a business dashboard, a service catalog, worker schedules, availability logic, appointment creation, and an AI assistant that could use all of that data in a real conversation.

I planned for multi-tenant from the start. If this was going to work for more than one salon, every piece of business data needed to be isolated per business. That decision shaped everything else.

The Problem

I knew the basics of database design, but I was not working at an architecture level. I had a lot of ideas for features and ways to give the AI context and tools. The problem was not a lack of ideas. It was too many ideas before the core booking flow actually worked.

I also did not fully understand how to use LLMs correctly when I started. I knew how to call the API. I did not know how to structure a product around it. That gap slowed the whole project down.

Assumption vs Reality

What I Thought Would Work

I figured the architecture would be straightforward. Next.js for the frontend and API routes, Supabase for the database, OpenAI for the AI layer. Wire them together, write a good prompt, and the booking flow would work. I also assumed that giving the AI as much freedom as possible would produce the best results, so I let it handle most of the booking logic on its own while I focused on testing limits and learning what the boundaries were.

What Actually Happened

The stack choices were mostly right, but the way I connected them was not. Giving the AI open-ended control over the booking flow meant it would skip steps, make assumptions about availability, and try to be helpful in ways that broke things. The architecture needed clearer boundaries. The AI needed defined tools with specific purposes, not open-ended access to the database. And the database needed to drive the booking state, not the conversation history.

The Fix

I restructured around a few core principles.

Next.js App Router handles the frontend and the API routes. One project, no separate backend server. I chose Next.js because it had a built-in backend and I was familiar with JavaScript. I had used Express before, but I wanted to learn something new.

Supabase is the single database shared between the widget and the dashboard. I originally chose it because everyone was talking about it and because it supported vector databases for RAG. Over time, it became the real source of truth for booking state, not just storage. Row Level Security handles multi-tenant data isolation, which I planned from the first day.

The AI assistant has specific tools that interact with the database: pulling services, checking availability, getting business information. The more business context the AI has, the better it handles questions and understands what the user is trying to book. But the tools have boundaries now. The AI queries data and collects booking information through defined tool calls instead of making open-ended decisions.

Lesson Unlocked

The architecture should grow from the product requirements, not from a list of tools you want to try. Supabase was a good pick because PostgreSQL, RLS, and vector support fit the actual needs. Next.js was a good pick because the built-in backend meant one project instead of two. But I chose both of them partly because of hype, not because I fully understood what I needed yet. The AI layer was where I struggled the most. Not because the tools were wrong, but because I did not design clear boundaries for what the AI should and should not do. Architecture is not just about picking the right services. It is about defining how they talk to each other and what each piece is responsible for.

Business Translation

For a business owner considering an AI booking tool, the architecture matters even if you never see it. A well-structured system means the AI gives correct answers about your services and availability. A poorly structured one means the AI guesses, skips steps, or books appointments that do not make sense. The difference between a booking bot that feels reliable and one that feels broken is usually not the AI model. It is how the product is built around it.

Builder Notes

I know the basics of database design but not at an architecture level. That honesty shaped a lot of my decisions. I leaned on Supabase RLS for multi-tenant isolation because it handled the hard parts for me. I kept everything in one Next.js project because managing a separate backend was more complexity than I needed.

Technical Note 1

The widget and the dashboard share one Supabase database. No separate backend service. API routes in Next.js handle everything the AI and the dashboard need.

Technical Note 2

Supabase RLS was planned from day one for multi-tenant isolation. Every query is scoped to a business ID.

Technical Note 3

The AI uses tool calling to interact with the database. Each tool has a specific job: fetch services, check availability, get business info. No open-ended database access.

Technical Note 4

I avoided adding Python or FastAPI to the stack. Since I was calling LLM APIs and not training models, I did not need a separate language. That said, the system prompt grew too large over time and the full context stopped fitting in the model window. I am now learning Python and LangGraph to handle state management differently. If it works, I may eventually move the AI backend to Python.

Technical Note 5

Vector database support in Supabase was one of the original reasons I chose it. RAG for business FAQs is still on the roadmap.

What I'd Do Differently

I would start with the smallest possible architecture: one database table for appointments, one for services, one API route for the AI to call, and nothing else. Get one booking flow working end to end before adding worker schedules, availability logic, or extra AI tools.

I would also define the AI boundaries before writing the first prompt. What tools does it have? What can it do? What should it never do? Those decisions are architecture decisions, not prompt decisions.

Next Experiment

The booking flow itself. Now that the architecture is in place, the next challenge is making the step-by-step booking conversation actually work: collecting the right information in the right order without the AI skipping steps or asking for things it already knows.

Founder JourneyAI AgentsBooking WidgetSaaS

The information on this website is provided for general educational purposes only and may not apply to your specific setup or environment. It should not be considered professional advice. Always consult a qualified technician when appropriate.