feat: integrate Ground Truth review into Kombi Pipeline last step

- New StepGridReview component: split-view (scan image left, grid right),
  confidence stats, row-accept buttons, zoom controls
- Kombi Pipeline case 6 now uses StepGridReview instead of plain GridEditor
- Kombi step label changed to "Review & GT"
- Ground Truth queue page simplified to overview/navigation only
  (links to Kombi pipeline for actual review work)
- Deep-link support: /ai/ocr-overlay?session=xxx&mode=kombi

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-03-23 15:04:23 +01:00
parent 4e809c3860
commit 7a6eadde8b
4 changed files with 717 additions and 459 deletions

View File

@@ -1,6 +1,7 @@
'use client'
import { useCallback, useEffect, useState } from 'react'
import { useCallback, useEffect, useState, useRef } from 'react'
import { useSearchParams } from 'next/navigation'
import { PagePurpose } from '@/components/common/PagePurpose'
import { PipelineStepper } from '@/components/ocr-pipeline/PipelineStepper'
import { StepOrientation } from '@/components/ocr-pipeline/StepOrientation'
@@ -13,6 +14,7 @@ import { StepWordRecognition } from '@/components/ocr-pipeline/StepWordRecogniti
import { OverlayReconstruction } from '@/components/ocr-overlay/OverlayReconstruction'
import { PaddleDirectStep } from '@/components/ocr-overlay/PaddleDirectStep'
import { GridEditor } from '@/components/grid-editor/GridEditor'
import { StepGridReview } from '@/components/ocr-pipeline/StepGridReview'
import { OVERLAY_PIPELINE_STEPS, PADDLE_DIRECT_STEPS, KOMBI_STEPS, DOCUMENT_CATEGORIES, dbStepToOverlayUi, type PipelineStep, type SessionListItem, type DocumentCategory } from './types'
const KLAUSUR_API = '/klausur-api'
@@ -39,6 +41,9 @@ export default function OcrOverlayPage() {
})),
)
const searchParams = useSearchParams()
const deepLinkHandled = useRef(false)
useEffect(() => {
loadSessions()
}, [])
@@ -114,6 +119,22 @@ export default function OcrOverlayPage() {
}
}, [])
// Handle deep-link: ?session=xxx&mode=kombi (from GT Queue page)
useEffect(() => {
if (deepLinkHandled.current) return
const urlSession = searchParams.get('session')
const urlMode = searchParams.get('mode')
if (urlSession) {
deepLinkHandled.current = true
if (urlMode === 'kombi' || urlMode === 'paddle-direct') {
setMode(urlMode)
const baseSteps = urlMode === 'kombi' ? KOMBI_STEPS : PADDLE_DIRECT_STEPS
setSteps(baseSteps.map((s, i) => ({ ...s, status: i === 0 ? 'active' : 'pending' })))
}
openSession(urlSession)
}
}, [searchParams, openSession])
const deleteSession = useCallback(async (sid: string) => {
try {
await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sid}`, { method: 'DELETE' })
@@ -306,7 +327,7 @@ export default function OcrOverlayPage() {
) : null
case 6:
return mode === 'kombi' ? (
<GridEditor sessionId={sessionId} onNext={handleNext} />
<StepGridReview sessionId={sessionId} onNext={handleNext} />
) : null
default:
return null

View File

@@ -71,7 +71,7 @@ export const KOMBI_STEPS: PipelineStep[] = [
{ id: 'crop', name: 'Zuschneiden', icon: '✂️', status: 'pending' },
{ id: 'kombi', name: 'PP-OCRv5 + Tesseract', icon: '🔀', status: 'pending' },
{ id: 'structure', name: 'Struktur', icon: '🔍', status: 'pending' },
{ id: 'grid-editor', name: 'Tabelle', icon: '📊', status: 'pending' },
{ id: 'grid-editor', name: 'Review & GT', icon: '📊', status: 'pending' },
]
/** Map from DB step to overlay UI step index */