All work

AccuAligners, a clear-aligner lab that takes patient cases from dentists. 2023

Tooth-level prescriptions and staged payments for an aligner lab

Dentists send patient cases to AccuAligners through a web portal, and its prescription was a few on/off switches and a comment box. As one of two developers on the inherited Laravel 9 codebase, I turned it into guided questions and clickable tooth charts, restructured billing into milestones priced in the dentist’s own currency, and added attachments, voice notes and email alerts to each case’s messages.

Tooth numbering systems on one 32-tooth map
3
Kinds of tooth-level instruction
4
Countries mapped to a currency for pricing
237

How the case portal changed

The problem

Tooth-level instructions arrived as free text

Dentists use the lab’s portal to send patient cases: scans, photos, X-rays and a prescription. I joined the inherited Laravel 9 codebase as one of two developers. Its prescription had a few on/off clinical switches and a comment box, so which teeth to move, take out or leave alone had to be written out in words.

Billing was a processing fee and separate instalment orders, charged from the first price row whatever the dentist’s country. Each case’s messages were text only. At the same time, a teammate was adding a multi-tenant layer so that partner labs could run on the same portal.

Step one

A prescription the lab can read tooth by tooth

I rebuilt the prescription as a run of questions: mixed or permanent dentition, then Aesthetic or Full Arch Correction, then bite class I, II or III with the protocols for that class, then Maintain or Correct for the molars and canines on each side. Tooltips explain the choices, including why mixed dentition only allows Full Arch Correction.

Then the dentist clicks teeth on arch charts to mark the ones not to move, the ones to keep free of attachments and the ones to extract, and clicks gaps on a separate chart to keep spaces open. A switch shows the charts in Universal, FDI or Palmer numbering, and a 32-tooth map shows the saved choices back in whichever system the dentist picked.

Step two

Billing in milestones

I restructured the existing fees into milestones on each case: the digital model, the treatment plan, then aligner production in three equal stages (Lab Production, Packing and Delivery) or the whole balance at once. Each milestone is paid by card through Stripe, or by cheque or cash.

A partner lab can have payments switched off. Its new cases are then created already settled.

Step three

Prices in the dentist’s own currency

The dentist’s IP address gives a country, a map of 237 countries gives its currency, and the partner lab’s price row for that currency sets both the prices on screen and the currency of the Stripe charge. With no matching row, it falls back to the first price row. The price lists came with the portal; I added the lookup and moved the charges over to it.

The same lookup gives each viewer’s timezone, so message times show in local time.

The result

Messages with voice notes, and an email for each one

I upgraded each case’s text-only thread to take file attachments and voice notes recorded in the browser. A new message queues an email: to the dentist when the lab replies, and to the lab’s admins when the dentist writes. I added the email job and the database table for the job queue.

I also built a direct chat between partner-lab admins and the platform’s super admin, which crosses the tenant boundary on purpose, and let super admins create and edit cases. The result is a prescription the lab can read tooth by tooth, in the numbering the dentist picked, and billing that follows the case through production.

Before and after

The prescription

Before: A few on/off switches and a comment box

After: Guided questions with tooltips, and clickable tooth charts in Universal, FDI or Palmer numbering

Billing

Before: A processing fee and separate instalment orders

After: Digital model, treatment plan and three production stages on the case, or the balance at once, by card or by cheque or cash

Pricing

Before: Charges from the first price row

After: The price row for the dentist’s currency, found from their IP address

Messages

Before: Text only

After: Attachments, voice notes, queued emails both ways and local times, plus a direct chat with the super admin

All of it sits on the inherited portal, with its cases, files, orders and price lists, and on the multi-tenant layer for partner labs that my teammate built.

The work

Client
AccuAligners, a clear-aligner lab that takes patient cases from dentists
Role and period
One of two developers on an inherited Laravel 9 codebase, August to September 2023
My part
The prescription and tooth charts, milestone billing, local-currency pricing, the case-message upgrade, the admin chat and super-admin case editing. A teammate built the multi-tenant layer.
  • Laravel
  • PHP
  • MySQL
  • JavaScript
  • jQuery
  • Bootstrap
  • Stripe