Clinic Dashboard , Automation & Patient Follow-Up
Turned a spreadsheet-driven clinic operation into a live operations dashboard. Patient action queue, automated follow-ups, reminder pipeline, and revenue-at-risk metrics, all sitting on top of the team's existing Google Sheets workflow.
Context
A multi-practitioner clinic was running its entire operation off Google Sheets — patient list, follow-ups, invoices, reminders, no-show tracking — manually maintained by two front-desk staff.
It worked. It was also fragile. Every reminder, every booking lapse, every invoice older than 14 days lived in someone's head or in a tab that hadn't been opened that day. Revenue was leaking, and the team couldn't see where.
The brief was deliberately small: don't replace the sheets, build a dashboard on top of them. The team's workflow couldn't pause for a migration, and the sheets contained logic that hadn't been written down anywhere else.
Problem
Patient follow-ups were a queue with no UI. The cost of forgetting one was a lost patient and an unpaid invoice.
The clinic had no way to see, at a glance, which patients needed action and what kind. Everything lived in cells. The staff knew roughly what to look for, but the cognitive load was high and errors were quiet.
Revenue at risk wasn't a number anyone could point to. It was a feeling. The team wanted to know exactly how much revenue was at risk from lapsed bookings and overdue invoices at any point in the day.
Quiet failures compound until they're expensive.
Quiet failures compound until they're expensive.
The clinic wasn't in crisis. It was slowly leaking revenue and patient relationships through the cracks in a manual system.
Missed follow-ups turning into lost patients
A patient who doesn't hear back within two days of a lapse has a meaningfully higher churn rate. There was no system to ensure they heard back at all.
Invoices aging past 30 days unnoticed
Overdue invoices were only visible if someone actively opened the right sheet. Several were aging past 30 days before anyone noticed.
No single revenue-at-risk number
Without a live aggregate, the practice manager couldn't triage effort — they couldn't tell whether today's fire was a $400 problem or a $4,000 problem.
What was built and how it fits together.
The pieces of the build that mattered most.
Sheets-to-Postgres sync
Google Sheets API polling with incremental sync into a normalized schema. Conflict resolution handles concurrent edits from the dashboard and Sheets without data loss.
Ranked action queue engine
A scoring function weighs recency, value, and lapse type to produce a single sorted queue. Updated on each sync cycle so the front desk always sees the most urgent patient first.
n8n workflow library
Six n8n workflows cover the full reminder and escalation spine. Each is parameterized by patient status and responds to manual overrides from the dashboard UI.
Revenue-at-risk model
Daily aggregation across invoice age, booking lapse, and cold-contact buckets. Produces a breakdown by category and a roll-up the practice manager can share in standup.
Audited dispatcher
All outbound contact events are written to an immutable log before dispatch. Duplicate suppression, rate limiting, and opt-out checks run at the dispatcher layer.
Write-back reconciliation
Bi-directional sync with conflict detection. The dashboard can write status changes back to Sheets; if the sheet changed in the interim, the conflict is surfaced rather than silently overwritten.
What came out of it.
Values marked placeholder are representative — replace with measured numbers from the live system once available.
A live operations dashboard the front desk actually opens every morning.
The clinic kept its spreadsheets. It also got a single ranked queue, an automated reminder spine, an audited contact history, and a revenue-at-risk number it can argue about in standup. The system has been running in daily use since rollout with no architectural changes.
Have a similar system to build or optimize?
If you're running operations on spreadsheets and need visibility without a full migration, send a few sentences and I'll respond within one business day.