Make the Everwood dashboard genuinely self-serve: a business owner should be able to sign up, configure their product, test the widget, and launch without needing me to explain anything.
The app worked well locally. But local development lets you cheat because you are both the builder and the user. You know where everything is, which data is fake, and why an error happened. The user does not.
A working feature is not the same thing as a finished product experience. Production is not one big launch moment. It is a hundred small moments where the product stops depending on you.
The Build
Everwood started with one goal: build a booking widget a business could add to their website.
That grew quickly. The booking widget needed services, workers, hours, availability, confirmations, customer records, admin controls, chat logs, testing, subscriptions, onboarding, and account management.
At some point the mission shifted. It stopped being "can I make this feature work locally" and became "can a real business owner sign up, understand what to do, test the product, install it, and trust it without needing me?"
That question changed what I started building.
The Problem
The product kept landing in "almost production" states.
The booking widget existed, but the business still needed clear installation instructions. The dashboard loaded, but a new user needed onboarding to understand what Dashboard, All Products, and Account even meant. The booking product could be subscribed to, but the user needed product-specific guidance after subscribing. The widget could take bookings, but there was no way to test it without polluting real customer and appointment tables.
Every one of those gaps had the same shape: the product depended on me to fill the blank.
Superadmin could grant access, but the logic was fragile and not idempotent. The chat logs existed, but the UI felt like a database table, not an inbox. The account flow handled signup, delete, and reactivate, but the experience felt hacked together rather than intentional.
None of this was obvious while building locally. It only became visible when I started thinking like a business owner seeing the product for the first time.
Assumption vs Reality
I thought production readiness was a technical checklist. Deploy the app, set environment variables, connect Supabase, add RLS policies, fix bugs before users see them. Once that list was done, the product would be ready.
That checklist gets the app online. It does not make the app usable. Every unfinished flow becomes support work later. If the install instructions are unclear, I become support. If onboarding is missing, I become the tour guide. If test mode does not exist, I become QA for every business. A SaaS product cannot grow if every customer needs the founder sitting beside them.
The Fix
The fix was to start treating every feature as part of a complete user journey.
Not just "does this button work?" but "would a first-time business owner understand why this button exists, when to use it, and what happens after they click it?"
Onboarding needed layers. First-sign-in onboarding covering Dashboard, All Products, and Account. Then product-specific onboarding after subscribing to Booking, covering setup, services, workers, availability, widget testing, and installation. The first experience should feel simple, not overwhelming.
Test mode needed to be real. A business needs to test the widget before putting it on their website. But test bookings should not create real customers or appointments. The product needed a clear test mode with separate history or clearly flagged records that could be reset without fear.
Product access needed to be boring and reliable. When a superadmin grants or removes access, nothing should break. Granting Booking access twice should not cause problems. Revoking access should not leave partial states.
Dashboards needed to explain themselves. A dashboard should answer: what is happening, what needs attention, what changed recently, what should I do next. Not just display data.
Configuration needed to live where the user expects it. Booking settings inside Booking. Account settings inside Account. Subscriptions inside All Products. Information architecture determines whether the app feels obvious or confusing.
A working feature is not the same thing as a finished product experience. Local development lets you cheat. You are both the builder and the user. You know where the settings are, which data is fake, which page to visit, what button to click, and why an error happened. The user does not. When someone else uses the app, they reveal all the hidden assumptions you were carrying in your head. Every missing tooltip, unclear button, broken state, weird permission issue, and confusing page becomes visible. Production is not one big launch moment. It is a hundred small moments where the product stops depending on you.
For a nail salon, barber, landscaper, or any small service business, the product has to clear one bar: can this help my business without creating more work for me? They do not care that the backend is clean if they cannot figure out how to test the widget. They do not care that the AI booking assistant works if they do not know how to install it. They do not care that the dashboard has useful data if the layout makes them feel lost. Every gap in the product flow becomes a reason to call the builder instead of using the product. That is not a business. That is a consulting engagement with a nice UI.
Builder Notes
These are the production-readiness questions I now ask before calling a feature done. They are not about code quality. They are about whether the feature can stand on its own.
Technical Note 1
Can a new user understand it? If I have to explain it every time, the UI is not finished.
Technical Note 2
Can the user safely test it? If testing creates real business data, the feature is risky.
Technical Note 3
Can the user recover from mistakes? Delete, reactivate, reset, retry, and edit flows matter.
Technical Note 4
Can admins manage it safely? Superadmin tools need guardrails, idempotent actions, and audit trails.
Technical Note 5
Is the data protected? Multi-tenant apps need strong auth checks, RLS policies, and server-side validation.
Technical Note 6
Is the feature placed where the user expects it? Bad navigation creates support work.
Technical Note 7
Does the empty state teach the user what to do? A blank screen should not feel broken.
Technical Note 8
Does the product reduce dependency on me? This is the real test.
Before / After
- Features evaluated by whether they work locally
- Onboarding skipped because the builder already knows the product
- Test bookings mixed with real production data
- Product access logic fragile and not idempotent
- Dashboards designed to display data, not explain it
- Every unclear flow becomes a support question for the builder
- Features evaluated by whether a first-time user understands them
- Layered onboarding: platform-level first, product-specific after subscribing
- Test mode with separate records and a reset option
- Product access logic that handles repeated actions without breaking
- Dashboards that answer: what is happening, what needs attention, what next
- Flows designed to remove the builder from the support loop
What I'd Do Differently
I would design the self-serve journey earlier. Not the perfect architecture or the perfect UI. Just the basic path: signup, setup, test, launch, manage.
That path should exist as early as possible. Even if the first version is rough, it gives every feature a place to belong. Without it, the app becomes a collection of working parts. With it, it starts becoming a product.