Personal project · Chrome extension + dashboard
Built to check the math. It changed how she books the week.
A consultant dentist works rotationally across around twenty clinics. The practice-management portal recorded every procedure she performed and never once told her what she had earned. She was reconciling it by hand, in a spreadsheet, thirty minutes a day. This replaced that — and then turned into something she plans with.
The gap
The portal had one job. Her pay wasn't it.
It was built to serve patient records — appointments, treatment plans, invoices, clinic operations — and it does that well. But a consultant rotating between clinics sits downstream of a system that sets her pay and gives her no surface inside it. Every fact she needed was already in there. Nothing joined them.
The join is the product. Everything above it already existed.
Every number she needed was already in the system. None of them were in the same place.
The problem was never data collection.Before
Thirty minutes a day. The travel was worse.
Neither loop was difficult. That was the problem — nothing about them justified the time they took, and there was no version of the day where they could be skipped.
- Open the portal, one patient at a time
- Read off the procedure and the amount
- Type it into the sheet
- Repeat for every patient seen that day
- At month end, total it and hope it matched
- Scroll back through appointment history to reconstruct where she had been
- Work out the route between clinics, in order
- Look up the fare for each leg
- Screenshot it as evidence
- Repeat for every leg of every day
Now it happens while she works, not after. Travel comes along with it — every leg derived from the appointments already captured, so the month-end reconstruction stopped existing.
None of it was hard. All of it was expensive.
Thirty minutes daily, plus an evening lost at the end of every month.Constraint
You don't get to change the source system.
The portal is not mine, it is not going to change, and it has to keep working exactly as it does for everyone else in the practice. Everything else followed from that.
A passenger, not a driver
The extension reads what is already on screen or already in flight. It captures as she works — it doesn't crawl, and it never writes back.
Two paths in
A clean API response where one existed, resilient parsing of the rendered page where there wasn't. The portal spans two generations of framework; both had to be handled.
Local only
Nothing leaves the machine. Records live in extension storage and IndexedDB, with backup and restore against the one failure mode Chrome imposes.
The product
One month, fully joined.
Earnings, work value, the clinic split and the incentive position on one surface — the view the portal was never going to provide. Below is the real dashboard, running on fabricated records.
The turn
She stopped checking the past and started steering the month.
This is the part I did not design for. It was built to verify. Within a few weeks it was being used to plan, and that turned out to be the more valuable half.
Which slots to take
A clinic-wise and day-wise split of her own earnings, not the clinic's revenue.
Next week's availability now goes where the work actually pays.
How much effort is left
The incentive scheme steps at fixed thresholds. The first she knew of crossing one used to be the credited payment.
The remaining distance is on screen all month.
What is still open
Unconnected payments, incomplete work-done entries, procedures with no amount against them.
Surfaced the day they appear, not discovered at month end.
Before, the month was a result. Now it's a decision.
Uncertainty
It says what it doesn't know.
Invoice totals don't map cleanly onto individual procedures. Coupons and care plans absorb value in ways that may or may not be credited back later. A tool that guesses here is worse than the spreadsheet it replaced, because it is confidently wrong and nobody thinks to check it.
reduced from payable this month
₹45,500 of it is Preventive Care Plan — may still be credited
That last line is the whole design position. The interface has a number it could print and declines to, because the money may still arrive and stating it either way would be a guess dressed as a fact.
- Four payment states, reported explicitly rather than collapsed into one figure.
- Missing amounts are counted, not quietly dropped from the total.
- Nothing is borrowed. A procedure with no amount of its own shows an em dash — never another patient's figure for the same treatment.
What it catches
Now there are two sets of books.
At month end the practice issues a work-done sheet. Until now it was the only record, which made it the truth by default. Her captured data is a counterparty to it — and where the two disagree, the disagreement is specific enough to raise the same week.
One click produces the practice's own sheet format, prefilled — travel included, captured as a byproduct of the daily run rather than reconstructed at the end of the month.
Close
The number has to be right when nobody checks it.
One person relies on this to know what she is owed. She will not audit it — that is the entire point of it existing. So every release ships against live data rather than synthetic fixtures, and every bug gets diagnosed from a real export, because the only failure that matters here is a number that is wrong and looks right.
Two loops of manual work, replaced by a surface that reports what it knows and admits what it doesn't.
All work