# Milestone 3 — Dental Core (Implementation Notes)

## Scope note (v2.2)
Built under the **web-only MVP** scope: the Flutter app and standalone REST
API were removed; all JSON endpoints used by the chart/calendar/galleries are
internal web routes. The shell is mobile-first (bottom tab bar < 768px,
sidebar ≥ 768px) and PWA-ready (manifest + minimal no-PHI-cache service
worker).

## 1 · FDI dental chart — the centerpiece
- `tooth_records` is an append-only clinical log; the chart is *reconstructed*
  (`ToothChartService::chartFor`) — latest non-planned record per tooth wins,
  planned items render as a dashed halo. Full per-tooth timeline in the panel.
- Surfaces stored as JSON (M,O,D,B,L), picked via a touch-friendly cross grid.
- Screen layout: two scrollable arches (patient's right on screen-left, as in
  clinical charts), sticky side panel on desktop, stacked on mobile.
- Records created by plan items are protected from direct deletion.

## 2 · Procedures catalog
ar/en names, 9 categories, default price (whole IQD) + duration, and
`default_condition` — the chart effect written when a plan item completes.
~24 common Iraqi-market procedures are seeded into every new clinic
(`DefaultProcedures::seed`, hooked into signup).

## 3 · Treatment plans
- Items are tooth-linked (FDI + surfaces) with per-item pricing; plan totals =
  non-cancelled items − discount (validated ≤ gross).
- Status machine: draft→proposed→accepted→in_progress→completed (+cancel).
- **Automatic chart updates:** adding a tooth item writes a *Planned* record;
  `completeItem()` writes the *Completed* record and rolls the plan to
  in_progress / completed automatically.
- PDF via mPDF (`composer require mpdf/mpdf`) — chosen for real Arabic
  shaping/RTL; the same renderer feeds WhatsApp PDF attachments in M5.

## 4 · Before/After photos & 5 · X-rays
- PHI files stored on the **private** disk, streamed through a
  tenant-scoped, policy-checked route — never the public webroot.
- GD thumbnails (no new packages). Before/after pairing is a self-FK
  (`paired_with_id`); the gallery renders a CSS `clip-path` comparison
  slider. X-ray viewer: zoom slider + wheel zoom + pointer pan.
- Tooth tagging on any file (validated FDI list), plus optional links to a
  treatment plan or appointment.

## 6 · Clinical timeline
`TimelineService` merges appointments, chart records, plans, and files into
one descending feed with clinic-local timestamps. Payments slot in during M4
(the event shape is final).

## Tests (24 new)
Chart: 32-tooth FDI integrity, surfaces, invalid-FDI rejection, history
ordering, planned-vs-current precedence, RBAC. Plans: planned/completed chart
side-effects, totals/discount, cancelled-item exclusion, auto status rolling,
double-completion guard, transition guard. Files: upload + thumbnail +
tagging, invalid-tag filtering, pairing rules, cross-tenant streaming 404,
unpair-on-delete. Timeline: multi-source merge ordering.

## New dependency
`composer require mpdf/mpdf` (PDF only; everything else uses GD/CDN).
