Case study 05 · Migration · Custom App · Automation

Rebuilding a SaaS Onboarding Engine on Client-Owned Infrastructure

A patient-education platform was running its entire business on a system it did not own. I rebuilt the machine underneath it on Supabase, Vercel, and a custom GoHighLevel app, and cut clinic onboarding from eight hours to ninety minutes.

The challenge

The client is a patient-education SaaS company serving dental and airway clinics. Every clinic gets its own white-labelled portal built on GoHighLevel. The whole delivery system had been built by an outside contractor, and when that relationship broke down, with lawyers involved, a hard problem surfaced. The business could keep selling, but it could not build, fix, or scale anything without the person it was trying to leave.

The specifics were worse than they first looked. The GoHighLevel app that provisioned every new clinic was registered under the contractor's own developer account, and there is no way to transfer one of those. The core workflows were asset-protected and hardcoded to a single clinic, so nothing generalised to the next one. Every internal notification was wired to the contractor's own email address. And the onboarding form wrote one way into a spreadsheet and never back, so client contracts could not auto-fill.

On top of all that, onboarding a single clinic took around eight hours of manual work, and there was a fixed webinar launch date bearing down.

What I built

Rather than patch the inherited setup, I rebuilt the onboarding engine as one owned pipeline, source of truth first. A clinic signs up, a form fires one webhook, and the rest provisions itself.

Client-owned provisioning app

A private GoHighLevel Marketplace app, rebuilt under the client's own developer account and authorised over OAuth. Scoped to exactly what a clinic build needs and nothing more.

Supabase as the single source of truth

One Postgres table holds every clinic's onboarding record. It also stores the OAuth token and a storage bucket for clinic logos, locked down with row-level security and service-role keys on the server side.

Serverless automation on Vercel

The provisioning logic runs as functions on Vercel: create the subaccount, push the snapshot, wire the menu links, generate white-label styling, send the notification. A workflow only has to send one email to kick off the full build.

Forms that write both ways

The admin and onboarding forms rebuilt as native HTML posting straight to the endpoint, replacing a broken form chain. Data now flows back into GoHighLevel fields by field ID, so contracts merge-fill instead of being re-typed.

A clean master snapshot

Eleven locked, single-clinic workflows rebuilt as unrestricted automations in a master account, so every new clinic inherits a working system instead of a fragile copy.

A documented SOP

The whole pipeline, from payment through to active user, written up as a standard operating procedure the client can hand to any future operator.

How it runs, step by step

  1. 1

    Sign-up

    • The clinic completes the onboarding form, which fires one webhook
  2. 2

    Automated build

    • The GoHighLevel subaccount is created through the client-owned app
    • The master snapshot (11 workflows) is pushed
    • White-label styling and menu links are built
    • Integration tokens, custom values and staff users are written
    • A notification email is sent. Supabase holds the single source of truth throughout
  3. 3

    Manual quality check

    • Domains, branding and workflows are published, then an end-to-end test is run as a real patient
  4. 4

    Live

    • The clinic becomes an active user

The full process map

Sign-up at the top, an automated build through Vercel and Supabase in the middle, then a short manual quality check before the clinic goes live. Green is a trigger, grey is an automated step, purple is the data layer, tan is a manual step.

Clinic Onboarding Pipeline Sign-up to a live clinic, on infrastructure the client owns Sign-up Automated build: Vercel Manual QA finish write read Clinic completes onboarding form Form fires one webhook to Vercel onboard.js provisions the GHL subaccount through the client-owned app (OAuth) Master snapshot pushed: 11 workflows White-label CSS and menu links built Notification email sent Integration tokens, custom values, staff users written DNS, domains, branding, workflows published End-to-end test as a real patient Supabase single source of truth Clinic live: Active user

What changed

1.5h

To onboard a clinic, down from around eight hours of manual work

11

Locked single-clinic workflows rebuilt clean and reusable across every clinic

100%

Infrastructure now owned by the client: developer account, app, code and data

1

Source of truth in Supabase driving the entire pipeline end to end

Before

Onboarding a clinic meant hours of manual setup, a provisioning app owned by someone else, workflows that only worked for a single clinic, and internal alerts landing in a third party's inbox. Nothing could be changed without the outgoing contractor.

After

A clinic completes one form. Vercel stands up the subaccount through the client's own app, pushes the snapshot, generates the branding, and writes everything to Supabase. A short manual QA pass finishes the build. The client owns every piece and can onboard the next clinic without me.

Inherited a system you do not actually own? If a contractor built your business on infrastructure you cannot control, that is fixable, and usually without starting from zero. Book an Ops Review and we will map what it takes to get it back.

Book an Ops Review

Back to all case studies

Want this kind of work in your business?

Book an Ops Review and we'll talk through what's breaking and what would actually fix it.