--- type: task status: active created: 2026-08-20 repos: - repo: dyolink path: ~/PersonalProjects/dyolink branch: feat/treatment/add-voice-input-for-new-treatment-form base: origin/master role: extraction contract + resolvers + review sheet spec_slug: voice-treatment-entry merge_after: [] aliases: [voice treatment entry, voice input, dictation, mic] --- # Voice treatment entry **Status:** v1 is merged to `master` (`c07f550`…`dc10d8d`). The treatment form was then overhauled on top of it (`a3c14a1`, `7f92e73`, `72f885d`, `5d3597f`): one prosthesis type per tooth became **stacked jobs**, **jaw-level appliances** and a **category tree**. Voice still compiles against that model but can no longer express it, and in two places now writes data the form itself refuses. This revision adapts the extraction contract (§5), the resolvers (§6) and the review sheet (§7), and carries two recording defects found on Safari (§2, §9). Still blocked on the ASR spike (§11 item 1) before it is trustworthy in front of patients **Area:** Treatment workspace (CLINIC orgs) **Created:** 2026-08-20 · **Revised:** 2026-09-07 Fill a `TreatmentDetail` — including its lab dispatch — by speaking, instead of by tapping through the type dropdown, the FDI chart, the prosthesis job popover 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: `LabCaseToothProsthesis` rows | one assignment list — a target is a tooth **or a jaw**, and carries a **stack** of job codes | | 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` `