Case Study · 02

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.

RoleSenior Full-Stack Engineer & Automation Architect
Focus areasInternal tooling, n8n automations, CRM workflows, ops visibility
Engagement4 months · build & rollout, solo
Stack
Next.jsn8nGoogle Sheets APIPostgresTwilio
01

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.

02

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.

Why it needed to be done

Quiet failures compound until they're expensive.

Risk surface

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.

Solution

What was built and how it fits together.

01Sheets-to-Postgres sync layer
A sync process reads the live Google Sheets data into a normalized Postgres schema on a short interval. The dashboard reads from Postgres; the team keeps using Sheets exactly as before.
02Ranked action queue
Every patient who needs contact is surfaced in a single ranked list with a reason, a suggested action, and a last-contact timestamp. The front desk sees one queue instead of five spreadsheet tabs.
03n8n automation workflows
n8n drives the reminder spine: booking-lapse detection, SMS and email dispatches via Twilio, reminder scheduling, and escalation paths. Workflows are visible and editable without touching code.
04Revenue-at-risk derivation
A nightly rollup calculates the revenue at risk from each patient category — overdue invoices, lapsed bookings, cold contacts — and surfaces it as a single number the practice manager can act on.
05Audited contact log
Every automated and manual contact event is written to an append-only log. The front desk can see the full history for any patient without cross-referencing sheets or checking phone logs.
06Two-way Sheets write-back
When the dashboard marks a reminder sent or an invoice chased, the status writes back to the originating sheet. The Sheets stay the source of truth; the dashboard is the interface.
Key technical work

The pieces of the build that mattered most.

01

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.

Sheets APIPostgresIncremental sync
02

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.

Scoring algorithmQueue UINext.js
03

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.

n8nTwilioAutomation
04

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.

Revenue modelAggregationReporting
05

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.

Audit logDeduplicationCompliance
06

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.

Conflict resolutionBi-directional sync
Business impact

What came out of it.

placeholderRevenue at riskA live number the practice manager can act on, replacing a feeling with a figure. Exact amount varies by week.
placeholderFollow-up rate~96%Patients requiring action now reach that contact stage. Previously estimated at under 60% due to manual oversight.
placeholderInvoice cycle< 7dMedian time from invoice issue to first chase, down from 14+ days under the manual process.
placeholderTime to build4moFrom first call to the front desk using it daily. No sheet migrations, no disruption to the existing workflow.

Values marked placeholder are representative — replace with measured numbers from the live system once available.

Final result

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.

Single ranked queue replacing five manual tabs
Automated reminder and escalation pipeline via n8n
Live revenue-at-risk metric surfaced each morning
Audited contact log replacing phone notes
Google Sheets workflow unchanged for the front desk
Next engagement

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.

Book a callbilalasharf@gmail.com