refactor(transcribe): extract t-mark + draw-cue policy into tested helpers (#327)
Some checks failed
CI / Unit & Component Tests (push) Failing after 2m33s
CI / OCR Service Tests (push) Successful in 24s
CI / Backend Unit Tests (push) Successful in 3m42s
CI / fail2ban Regex (push) Successful in 43s
CI / Semgrep Security Scan (push) Successful in 22s
CI / Compose Bucket Idempotency (push) Successful in 1m7s

Review follow-up (Sara, fast-follow): the t no-active-region guard and the
draw-cue arm/disarm rule lived inline in the page with no direct coverage.
Extracted to pure resolveTrainingMark() (no-op when no region; recognition
enrolled flip) and canArmDraw()/shouldDisarmDraw(), each with unit tests
(10 cases total). The page now arms the draw cue only via canArmDraw and
disarms via shouldDisarmDraw, and routes t through resolveTrainingMark.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit was merged in pull request #728.
This commit is contained in:
Marcel
2026-06-04 17:37:29 +02:00
committed by marcel
parent 8c198f22be
commit 1e5e8e43e8
5 changed files with 103 additions and 12 deletions

View File

@@ -13,6 +13,8 @@ import { transcribeShortcuts } from '$lib/shared/actions/transcribeShortcuts';
import { createOcrJob } from '$lib/ocr/useOcrJob.svelte';
import { createTranscriptionBlocks } from '$lib/document/transcription/useTranscriptionBlocks.svelte';
import { stepRegion } from '$lib/document/transcription/regionNavigation';
import { resolveTrainingMark } from '$lib/document/transcription/trainingMark';
import { canArmDraw, shouldDisarmDraw } from '$lib/document/transcription/drawCue';
import { createFileLoader } from '$lib/document/viewer/useFileLoader.svelte';
import { scrollToCommentFromQuery } from '$lib/shared/utils/deepLinkScroll';
import { getConfirmService } from '$lib/shared/services/confirm.svelte';
@@ -112,17 +114,9 @@ function toggleMode() {
if (canWrite) panelMode = panelMode === 'read' ? 'edit' : 'read';
}
// Training enrollment is document-level — two fixed script-type chips
// (KURRENT_RECOGNITION / KURRENT_SEGMENTATION); there is no per-region training
// flag (that would arrive with #321). "t" toggles the primary recognition
// enrollment and stays a no-op unless a region is active, so it reads as an
// action on the region the transcriber is working on.
const RECOGNITION_TRAINING_LABEL = 'KURRENT_RECOGNITION';
function toggleTrainingMark() {
if (!activeAnnotationId) return;
const enrolled = !(doc.trainingLabels ?? []).includes(RECOGNITION_TRAINING_LABEL);
transcription.toggleTrainingLabel(RECOGNITION_TRAINING_LABEL, enrolled);
const toggle = resolveTrainingMark(activeAnnotationId, doc.trainingLabels ?? []);
if (toggle) transcription.toggleTrainingLabel(toggle.label, toggle.enrolled);
}
function deleteCurrentRegion() {
@@ -131,7 +125,7 @@ function deleteCurrentRegion() {
// Disarm the draw cue whenever we leave edit mode.
$effect(() => {
if (panelMode !== 'edit') drawArmed = false;
if (shouldDisarmDraw(panelMode)) drawArmed = false;
});
const shortcutOptions = {
@@ -142,7 +136,9 @@ const shortcutOptions = {
goToPrevRegion: () => goToRegion(-1),
toggleMode,
closePanel: () => (transcribeMode = false),
startDrawMode: () => (drawArmed = true),
startDrawMode: () => {
if (canArmDraw(panelMode)) drawArmed = true;
},
toggleTrainingMark,
deleteCurrentRegion,
openCheatsheet: () => (cheatsheetOpen = true)