From 648e8ed1f2314c030bc2a6975cc1ba86b01bd9a9 Mon Sep 17 00:00:00 2001 From: Amin Mousavi Date: Thu, 20 Aug 2026 16:51:57 +0330 Subject: [PATCH] docs: spec for voice-driven treatment detail entry Design spec for filling a TreatmentDetail by voice, settled across three grilling sessions (30 decisions, logged in the spec). Key shape: - two-stage pipeline: OpenRouter whisper-1 -> gemini-3.7-flash - the LLM emits *intents*, never FDI codes or ISO dates; pure Jest-tested backend resolvers own quadrant mapping and Jalali conversion - provider registry keyed by locale so fa can diverge from en/nl - review sheet confirms before anything touches the form - audio and transcripts are never persisted Co-Authored-By: Claude Opus 5 (1M context) --- docs/specs/voice-treatment-entry/spec.md | 709 +++++++++++++++++++++++ 1 file changed, 709 insertions(+) create mode 100644 docs/specs/voice-treatment-entry/spec.md diff --git a/docs/specs/voice-treatment-entry/spec.md b/docs/specs/voice-treatment-entry/spec.md new file mode 100644 index 0000000..8bbca52 --- /dev/null +++ b/docs/specs/voice-treatment-entry/spec.md @@ -0,0 +1,709 @@ +# Voice treatment entry + +**Status:** Draft — not started +**Area:** Treatment workspace (CLINIC orgs) +**Created:** 2026-08-20 + +Fill a `TreatmentDetail` — including its lab dispatch — by speaking, instead of by +tapping through the type dropdown, the FDI chart, the prosthesis wizard and the lab +picker. + +--- + +## 1. Goal + +A clinician on the Treatment tab taps a microphone, describes the treatment for the +already-selected patient in one utterance, and is shown a **review sheet** of what was +understood. Fields they tick are applied to the open detail chip. Nothing is written to +the form without confirmation. + +### In scope + +One recording produces **exactly one** `TreatmentDetail`, and may fill every field of it: + +| Field | Source | +|---|---| +| `treatmentType` | catalog code, matched against locale labels | +| `teeth` | FDI codes, via tooth-intent resolver | +| `toothSelectionGroups` | connected (bridge) / single spans | +| `comment` | cleaned dictated notes | +| lab: `prosthesisTypeCode` per tooth | default type + per-tooth overrides | +| lab: `destinationOrganizationId` | matched against the clinic's linked labs | +| lab: `dueDate` | via due-date intent resolver | + +### Out of scope (v1) + +- Multiple detail chips from one recording. +- `attachmentIds` — files cannot be dictated. +- Editing an existing detail by voice ("no, make that 15"). Confirming a recording always + creates a **new** detail (see §2). +- Creating the treatment or selecting the patient by voice. A patient is already + selected; voice only fills the form. +- Lab-side (`LAB` org) usage. Clinic only. + +--- + +## 2. User flow and UI integration + +### The control: Add detail, split + +The `Add detail` button gains a second segment holding the mic. The halves read as +siblings — both end in a new detail — but they are **independent actions**: + +- **Add half — unchanged.** Same `onAddDetail`, same seeding, same `setEntryStep`. It + gains a neighbour and nothing else. Its logic is not modified, wrapped or made + conditional. +- **Mic half** — starts a recording. Nothing is created until confirm (below). + +The `Add detail` `