A booking platform wired into the practice-management system, across seven clinics
A physiotherapy group runs seven clinics on the Gold Coast on a shared practice-management system (Nookal). The old WordPress site could take an enquiry, but not a real booking — every appointment still had to be typed into Nookal by hand at the front desk.
In plain terms
A custom booking website wired straight into the clinic's practice-management system, so a patient books a real appointment across any of seven clinics — plus Google Ads bringing new patients in.
Book a real appointment, not a request
The site reads live availability from the clinic's practice-management system and writes the booking back into it — so a patient sees the actual open slots and the appointment lands in the right diary, not a form the front desk has to re-key.
One system across seven clinics
Seven clinics, their practitioners, and their services all map to one booking flow — a patient picks a location and is only ever offered a practitioner who genuinely works there.
Ads bringing patients in — with the loop still to close
Two Google Ads campaigns run new-patient traffic to dedicated clinic landing pages, reported in a plain-English monthly PDF. The tracking that ties an ad click all the way through to a booked appointment is built and waiting to switch on.
The problem
The group had seven clinics, a full roster of practitioners, and one practice-management system holding every diary — but a website that couldn't touch it. A patient could fill in a form; someone at reception then read live availability off Nookal and typed the appointment in. Every booking was a double-handling job, and out of hours there was no way to book at all.
The complication is that Nookal's own data overstates where practitioners work — the assignment field lists a practitioner at clinics they never actually see patients at. Naively trusting it would let the site offer a booking that couldn't be honoured. And the group runs Google Ads for new patients, but the ad spend and the booking system were entirely separate — no line connecting a click to an appointment.
What we built
A custom Next.js site and multi-step booking flow that reads live availability from and writes real appointments into Nookal across all seven clinics — plus the Google Ads landing pages and reporting that bring new patients to it.
Booking wired directly into Nookal
The booking flow reads live availability from Nookal and writes the appointment straight back — verified end-to-end against the live API. A patient sees the actual open slots for a real practitioner, and the appointment lands in the clinic's diary without anyone re-keying it. Returning patients are matched to their existing Nookal record rather than duplicated.
Seven clinics, mapped to one flow
Every clinic, practitioner, and service maps to a single booking flow — seven locations, nine practitioners, eight services. Booking eligibility is driven by four months of real Nookal bookings, not the assignment field that overstates coverage, so a patient is never offered a practitioner who doesn't actually work at that clinic.
Writes that can't duplicate, failures that can't disappear
Nookal returns success even when a response is lost, so a retry would create a duplicate patient or appointment — the platform never auto-retries a write. And every booking that does fail is captured as a lead and raises an alert, so no patient who tried to book is silently lost.
A patient CRM mirrored from Nookal
Around 15,000 real patient records are mirrored into a Supabase database with per-patient history and preferred-clinic rollups, alongside per-clinic and per-practitioner daily metrics and AI-written daily briefings for the owners — an admin console over the operational data, gated behind Supabase auth.
Google Ads for new patients
Two Performance Max campaigns run new-patient traffic to dedicated, no-index clinic landing pages, at a modest managed spend. Each week's real figures are written into an on-brand PDF report with the reasoning behind every recommendation — campaign changes proposed for the owners' go-ahead, never auto-executed.
A fast, indexable site over the old WordPress
A page per clinic, per service, and per practitioner, plus a blog, served from a Next.js 16 codebase with Local Business schema and a full sitemap — replacing the WordPress site the group had outgrown.
How it fits together
From ad click to a real appointment in the clinic's diary
Read it left to right: a new patient arrives from an ad, books against live availability, and the appointment is written straight into the practice-management system. The dotted step — reporting the booking back to Google Ads — is built but not yet switched on in production.
Google Ads → clinic landing page
Two Performance Max campaigns, per-clinic pages
Book against live availability
Real open slots read from Nookal, not a contact form
Appointment written to Nookal
Returning patients matched; writes never auto-retry
Report the booking back to Ads
CheckpointBuilt, dark in production — the open loop
The click-to-booking measurement loop is the one piece not yet live: ad-side conversions are tracked, but a booked patient isn't yet tied back to the click that brought them in.
Inside the build
Real screens from the running platform, captured with placeholder data.

Where it stands
The platform is live and taking real bookings: a patient arrives, sees genuine open slots across any of the seven clinics, and the appointment is written into Nookal without the front desk re-keying it. The engineering that matters most is defensive — writes that won't duplicate, failed bookings that surface as leads, and booking eligibility drawn from real history rather than Nookal's overstated roster. Two honest gaps remain: the nightly syncs that keep the patient CRM current have run intermittently and need re-arming, and the tracking that would report a booked patient back to Google Ads — closing the loop from ad spend to appointment — is built but not yet live in production. The click ID is already carried into each booking, so closing that loop is a switch to flip, not a system to build.
Built with
Next project