fix(backend): read a tooth code whatever script its digits are in
The extraction model transcribes Persian speech, so it can hand back "۲۶" in Persian digits or "2 6" from a digit-by-digit dictation. Both were compared literally against /^[1-8][1-8]$/, missed, and fell through to the positional branch with no quadrant — where the tooth was reported as "not understood". The clinician loses a tooth and is told the words were the problem. normalizeFdiCode() now runs at both the branch choice and the final validation, so the two cannot disagree. toLatinDigits moves out of jalali.ts into common/digits.ts: it was exported but unused in production, and a tooth module reaching into the calendar module would read as an accident. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,8 @@
|
||||
* midline pairs (11–21, 41–31) are neighbours, exactly as the chart treats them.
|
||||
*/
|
||||
|
||||
import { toLatinDigits } from './digits';
|
||||
|
||||
export type Arch = 'upper' | 'lower';
|
||||
|
||||
/** Which side of the *patient*, not of the screen. Quadrant 1 is the patient's upper right. */
|
||||
@@ -65,6 +67,19 @@ export function isFdiTooth(value: unknown): value is string {
|
||||
return typeof value === 'string' && FDI_TOOTH_IDS.has(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up a tooth code the extraction model echoed back, before it is matched.
|
||||
*
|
||||
* The model is transcribing Persian speech, so it can hand back "۲۶" in Persian digits or
|
||||
* "2 6" from a digit-by-digit dictation. Neither matches an FDI code literally, and a
|
||||
* near-miss here does not fail loudly — the tooth quietly turns into "not understood".
|
||||
* Returns '' for anything that is not a string.
|
||||
*/
|
||||
export function normalizeFdiCode(value: unknown): string {
|
||||
if (typeof value !== 'string') return '';
|
||||
return toLatinDigits(value).replace(/\s+/g, '');
|
||||
}
|
||||
|
||||
function archOrder(tooth: string): readonly string[] | null {
|
||||
if ((FDI_UPPER_ARCH_ORDER as readonly string[]).includes(tooth))
|
||||
return FDI_UPPER_ARCH_ORDER;
|
||||
|
||||
Reference in New Issue
Block a user