The treatment form was overhauled after voice v1 merged (a3c14a1,7f92e73,72f885d,5d3597f): one prosthesis type per tooth became stacked jobs, jaw-level appliances and a category tree. Voice still compiled against it but could no longer express it, and in two places wrote data the form itself refuses. Rewrites the extraction contract (§5), the resolver rules and the unresolved-reason table (§6), the review sheet (§7) and verification (§12), and records decisions 34-46. Adds the repos: block and a progress ledger so the task resolves from the branch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4.2 KiB
4.2 KiB
type, status, repos
| type | status | repos | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| task-progress | active |
|
PROGRESS — Voice Treatment Entry
Spec: spec.md
Adapting the merged voice feature to the overhauled prosthesis model (spec §5–§7,
decisions 34–46). v1 shipped on master; this branch revises it.
Status legend: ⬜ not started · 🟡 in progress · ✅ done · ⛔ blocked
| # | Work item | Repo | Status | Notes / refs |
|---|---|---|---|---|
| 1 | pickRecordingMimeType falls back to the empty hint instead of null |
dyolink |
⬜ | §9. The Safari failure |
| 2 | voiceForEditor also checks isMediaRecorderSupported() |
dyolink |
⬜ | §2 render policy, TreatmentWorkspace.tsx |
| 3 | Add Vitest for the frontend's pure helpers; update CLAUDE.md |
dyolink |
⬜ | §12. One dev dep, one config, one script |
| 4 | buildCatalog passes category / subcategory / chartRegion / stackGroup through |
dyolink |
⬜ | §5. voice.service.ts already receives all four |
| 5 | Wire schema: prosthesisAssignments, arch: 'both'; drop default + overrides |
dyolink |
⬜ | §5, extraction.wire.ts |
| 6 | Resolver: assignments, arch derivation, leaf-vs-category classification | dyolink |
⬜ | §5, §6, extraction.resolver.ts |
| 7 | Resolver: new unresolved reasons; retire tooth_not_selected |
dyolink |
⬜ | §6 reason table |
| 8 | Resolver: a resolved assignment forces treatmentType to prosthesis |
dyolink |
⬜ | §5. Only prosthesis is labDependent |
| 9 | Prompt: present the catalog as a tree; teach stacks and jaw-level codes | dyolink |
⬜ | §5, extraction.prompt.ts |
| 10 | Backend Jest suites for items 6–8, including the namespace-disjointness assertion | dyolink |
⬜ | §12 |
| 11 | Frontend types follow the new ResolvedExtraction |
dyolink |
⬜ | types/voice.ts |
| 12 | voiceReviewRows: merged row, chip folding, retire complete as a blocker |
dyolink |
⬜ | §6, §7 |
| 13 | VoiceReviewSheet: merged row, chart colours, three chip kinds |
dyolink |
⬜ | §7. crownColors / rootColors / archHighlight already exist |
| 14 | applyVoiceResult writes through applyLeafToJobs; handles arch rows |
dyolink |
⬜ | §6, §7 |
| 15 | Vitest specs for prosthesisTree.ts and voiceReviewRows.ts |
dyolink |
⬜ | §12 |
| 16 | New user-visible strings in en.json, fa.json, nl.json |
dyolink |
⬜ | i18n is mandatory, not a follow-up |
| 17 | Run every gate in §12, then the manual pass including Safari and iPad | dyolink |
⬜ | §12 |
Key decisions
Full table in the spec's §13, rows 34–46. The load-bearing ones:
- One assignment list, no default type. A default plus per-tooth overrides has a precedence rule, and that rule already mis-filled tooth 13 once.
- An arch target is derived from the code's
chartRegion, not declared on the wire. The catalog already answers it, andpartial_denturealready carrieschartRegion: 'crown'. - Stack rules stay frontend-only. The backend's dispatch check knows nothing about
stacking; porting
canStackLeafwould make voice stricter than the manual path and create a second copy of a rule that must never disagree. - Teeth and prosthesis merge into one sheet row for lab-dependent types. Two ticks can
save an empty detail today, because
persistDraftprunes lab-dependent details to their jobs. - Nothing is guessed. A missing material, a missing jaw and a missing quadrant all become chips. A jobless tooth is named and left out.
Deviations from spec
(none yet)
Next steps / open questions
- Amin reviews and approves this spec revision. That approval is the only human gate before
/orchestrate --dry. - Open items 15 and 16 in §11 are carried forward unchanged and are not in this branch: the pre-authentication body limit on the voice path, and transcript salvage still being specified but not built.
feat/voice-treatment-entryandbackup/pre-rebase-voiceare stale local branches from the v1 work. Safe to delete once this lands.