diff --git a/docs/specs/voice-treatment-entry/spec.md b/docs/specs/voice-treatment-entry/spec.md index 70fd5e0..0b83fcd 100644 --- a/docs/specs/voice-treatment-entry/spec.md +++ b/docs/specs/voice-treatment-entry/spec.md @@ -1,7 +1,8 @@ # Voice treatment entry -**Status:** Implemented on `feat/voice-treatment-entry`. First live test on 2026-08-21 -sent the tooth path back for revision — a spoken number is now read as its FDI code (§6). +**Status:** Implemented on `feat/voice-treatment-entry`, with one specified piece missing — +the transcript-salvage dialog (§9). First live test on 2026-08-21 sent the tooth path back +for revision — a spoken number is now read as its FDI code (§6). 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 @@ -537,7 +538,14 @@ English Nest exception for a user-facing failure. | `VOICE_NOT_AVAILABLE` | no profile for locale (v1); plan flag off, once enforced | | `VOICE_RATE_LIMITED` | throttle | -**Transcript salvage:** when ASR succeeded and only extraction failed, the response still +**Transcript salvage — specified, NOT built.** The backend half exists: `VOICE_EXTRACT_FAILED` +carries `details.transcript` and `HttpExceptionFilter` forwards it. The client half was +never written — `onError` only resolves a message through `getUserFacingError`, which never +reads `details`, so the transcript is shipped in an error body and dropped. Either build the +dialog below or stop returning the transcript; shipping dictation to the client and +discarding it is the worst of both. + +When ASR succeeded and only extraction failed, the response still carries the transcript and the failure dialog offers *"افزودن به یادداشت"*. That action **creates a new detail with only `comment` set to the transcript** — everything else left at `newDetail()` defaults. The words were captured and paid for; only the structure was