#006Everwood BookingImprovedIntermediate

Why Supabase Became the Source of Truth for My Booking Widget

The AI is the part people notice. The database is the part that makes the AI useful. Without real business data behind it, the booking bot is just a chatbot that guesses.

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

Tools
Next.jsSupabaseOpenAITypeScript
Concepts
Database DesignMulti-TenantTool CallingAI GuardrailsSource of Truth
Mission Brief
Goal

Make Supabase the single source of truth for all business data so the AI booking assistant never has to guess about services, workers, availability, or appointments.

Problem

An AI booking assistant is only useful if it is grounded in real data. Without a reliable data layer, the bot invents services, guesses prices, and makes up availability.

Lesson

The AI is just an interface. The database is the product.

Read as

The Build

The AI booking widget was starting to work as a conversation, but the question behind every response was the same: where does the AI get its information? If a customer asks what services are available, the AI needs a real answer. If a customer picks a time, the AI needs to know if that time is actually open. If a customer asks about pricing, the AI cannot guess.

I always had Supabase connected from the start. The AI queries real data before it decides what to say to the customer. That was never optional. But how the data was structured, what was stored, and how the AI accessed it changed a lot as the product grew.

The Problem

The challenge was not choosing a database. It was figuring out what data the AI actually needs to do its job and making sure that data was complete enough to answer any question a customer could ask.

If the services table is missing duration or pricing, the AI cannot answer "how long does a gel manicure take?" If the workers table does not track which services each worker can do, the AI might suggest booking with someone who cannot perform that service. If blocked dates are not recorded, the AI might offer a time on a day the business is closed.

Every gap in the data becomes a gap in the AI. The bot does not know what it does not know. It either gives a wrong answer or gives no answer at all.

Assumption vs Reality

What I Thought Would Work

I thought the database was the straightforward part. Set up the tables, store the data, let the AI query it. The real work would be in the prompts and the conversation flow.

What Actually Happened

The database turned out to be the foundation everything else depends on. The prompts only work if the AI has real data to reference. The conversation flow only works if the tools return accurate results. The more I built, the more I realized that every product decision eventually pointed back to what was in the database and how it was structured.

The Fix

I structured the data around what the AI needs to answer customer questions and complete a booking.

Services have as much detail as possible: name, description, pricing, duration, category, and anything a customer might ask about. The goal is that the AI never has to guess or generalize when a customer asks a specific question about a service.

Workers are connected to services through a join table. Each worker at a business is linked to the specific services they can perform. This is not enforced by the prompt. It is enforced at the data level. The AI cannot suggest a worker for a service they are not linked to because the query will not return them.

The business table stores hours, open days, and blocked dates for closures. The AI checks this before showing any availability.

Appointments are the main transactional record. Right now, the AI creates appointments directly through tool calls. I am considering moving this so the tool call invokes an API route that does more validation on the appointment object before creating it in the backend. That would add a layer of safety between the AI and the database write.

I do not have a separate customer table yet. That is a known gap, but it is not a gap I need to fill right now. We are not tracking visit history or loyalty data yet, and if we need to look up a customer we can query by name from the appointment records. When CRM features like reminders, re-booking prompts, and visit tracking come into the product, a dedicated customer table will be necessary.

RAG is running on the Everwood Tech site already, but it is not integrated into the booking widget yet. Supabase supports vector storage, which is one of the reasons I chose it, and that will come into play when the booking assistant needs to answer more open-ended questions about the business beyond what is in the structured tables.

Lesson Unlocked

The smarter the AI feels to the customer, the more important the boring database layer becomes. Nobody notices the database when it works. They notice immediately when it does not, because the AI starts guessing, gets things wrong, or cannot answer a simple question. Starting with the business data layer before the conversation layer was the right order. Services, workers, hours, and blocked dates were the first things I stored. The chat interface came after. That order matters because you cannot build a useful AI product on top of incomplete data. The AI is just an interface. The database is the product.

Business Translation

When the AI booking assistant tells a customer the right price, shows the right services, and only offers times that are actually available, that is not the AI being smart. That is the database being complete. For a salon owner, this means your real business information is what drives the bot. Your services, your workers, your hours. The AI is not making things up or pulling from some generic list. It is reading from your actual data. When you update a service price or block off a holiday, the AI knows immediately because it checks before every response. That is the difference between a booking bot that feels trustworthy and one that feels like it is guessing.

Builder Notes

Supabase was easy to set up and the UI is straightforward to navigate. I am sure there is a better way to use it and I am probably not using it to its full potential yet, but it has handled everything the product has needed so far.

Technical Note 1

The schema started with four core areas: business info (hours, blocked dates), services (with full detail), workers (with a join table to services), and appointments.

Technical Note 2

Each business has a slug used for tenant identification. The slug is pushed with every API payload so the system knows which business the request belongs to.

Technical Note 3

RLS is in place for multi-tenant isolation, but with only one business using it right now, the multi-tenant setup has not been stress-tested at scale.

Technical Note 4

The AI accesses the database through tool calls that hit API routes. It can read services, workers, availability, and business info. It can currently create appointments directly.

Technical Note 5

Moving appointment creation behind an API validation layer is a planned improvement so the backend can validate the appointment object before the write.

Technical Note 6

No customer table exists yet. Appointment records are the only customer-facing data. A dedicated customer table will be needed for CRM features like reminders and visit tracking.

Technical Note 7

RAG is live on the Everwood Tech site but not yet integrated into the booking widget. Supabase vector storage will support this when the booking assistant needs to answer open-ended business questions.

What I'd Do Differently

I would map out every question a customer could ask during a booking and make sure the database could answer each one before building the AI layer. "What services do you offer?" "How much is a gel manicure?" "Is Sarah available on Monday?" "Are you open on holidays?" Every one of those needs a table, a column, or a relationship to answer. If the data is not there, the AI cannot help.

Next Experiment

The prompt problem. The database is solid and the tools work, but the system prompt that ties it all together grew too large over time. The next post covers why that happened, what it broke, and how I am rethinking prompt design as a product decision.

SaaSBooking WidgetSupabaseAI Agents

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.