diff --git a/backend/src/modules/ai/processors/ai-batch.processor.ts b/backend/src/modules/ai/processors/ai-batch.processor.ts index 574616b8..ef9816d6 100644 --- a/backend/src/modules/ai/processors/ai-batch.processor.ts +++ b/backend/src/modules/ai/processors/ai-batch.processor.ts @@ -346,6 +346,8 @@ export class AiBatchProcessor extends WorkerHost { requestPublicId: idempotencyKey, status: 'completed', answer: JSON.stringify(extractedMetadata, null, 2), + ocrText: ocrResult.text, + ocrUsed: ocrResult.ocrUsed, promptVersionUsed: activePrompt.versionNumber, completedAt: new Date().toISOString(), }) diff --git a/frontend/components/admin/ai/OcrSandboxPromptManager.tsx b/frontend/components/admin/ai/OcrSandboxPromptManager.tsx index 991920c5..a21241fd 100644 --- a/frontend/components/admin/ai/OcrSandboxPromptManager.tsx +++ b/frontend/components/admin/ai/OcrSandboxPromptManager.tsx @@ -4,6 +4,7 @@ // - 2026-05-25: Extracted inline strings to i18n keys via useTranslations() (Obs #1 fix) // - 2026-05-25: Refactored sandbox polling to useSandboxRun hook (Obs #2 fix) // - 2026-05-26: เพิ่มการตรวจสอบ versionsQuery.data แบบทนทานเพื่อป้องกัน Error N.find is not a function ในกรณีที่ API ส่งข้อมูลแบบ wrapped object มา +// - 2026-05-29: เพิ่ม OCR Raw Text section ในผล sandbox 'use client'; import React, { useState, useEffect } from 'react'; @@ -23,6 +24,7 @@ import { ScrollText, Loader2, StickyNote, + ScanText, } from 'lucide-react'; import { useAiPrompts, useSandboxRun } from '@/hooks/use-ai-prompts'; import { useTranslations } from '@/hooks/use-translations'; @@ -50,7 +52,7 @@ export default function OcrSandboxPromptManager() { : (versionsData && typeof versionsData === 'object' && 'data' in versionsData && Array.isArray((versionsData as { data: unknown }).data)) ? (versionsData as { data: AiPrompt[] }).data : []; - const activePrompt = versions.find((v) => v.isActive); + const activePrompt = versions.find((v) => Boolean(v.isActive)); const [templateText, setTemplateText] = useState(''); const [ocrFile, setOcrFile] = useState(null); const [manualNote, setManualNote] = useState(''); @@ -333,6 +335,24 @@ export default function OcrSandboxPromptManager() { )} {sandboxState.result && sandboxState.result.status === 'completed' && (
+ + + + + OCR Raw Text + + + {sandboxState.result.ocrUsed ? 'PaddleOCR' : 'Fast Path (Text Layer)'} + + + +
+
+                        {sandboxState.result.ocrText || '(ไม่มีข้อความ)'}
+                      
+
+
+
diff --git a/frontend/components/admin/ai/PromptVersionHistory.tsx b/frontend/components/admin/ai/PromptVersionHistory.tsx index 7ea1072f..243537e4 100644 --- a/frontend/components/admin/ai/PromptVersionHistory.tsx +++ b/frontend/components/admin/ai/PromptVersionHistory.tsx @@ -55,12 +55,14 @@ export default function PromptVersionHistory({ ไม่พบเวอร์ชันอื่นในระบบ
) : ( - versions.map((version) => ( + versions.map((version) => { + const isActive = version.isActive === true || (version.isActive as unknown) === 1; + return (
@@ -69,7 +71,7 @@ export default function PromptVersionHistory({ v{version.versionNumber} - {version.isActive ? ( + {isActive ? ( ใช้งานจริง (Active) @@ -133,7 +135,7 @@ export default function PromptVersionHistory({
)}
- )) + );}) )} diff --git a/frontend/lib/services/admin-ai.service.ts b/frontend/lib/services/admin-ai.service.ts index 11b00dd9..9a69aaf9 100644 --- a/frontend/lib/services/admin-ai.service.ts +++ b/frontend/lib/services/admin-ai.service.ts @@ -6,6 +6,7 @@ // - 2026-05-21: เพิ่ม service method `submitSandboxExtract` สำหรับอัปโหลดไฟล์ใน OCR Sandbox (T043). // - 2026-05-25: เพิ่ม methods สำหรับจัดการโมเดล AI แบบไดนามิก (ADR-027). // - 2026-05-29: เพิ่ม ocr field ใน AiSystemHealth interface ตาม OcrService.checkHealth() +// - 2026-05-29: เพิ่ม ocrText, ocrUsed, promptVersionUsed ใน AiSandboxJobResult import api from '../api/client'; @@ -60,6 +61,9 @@ export interface AiSandboxJobResult { requestPublicId: string; status: 'pending' | 'processing' | 'completed' | 'failed' | 'cancelled' | 'not_found'; answer?: string; + ocrText?: string; + ocrUsed?: boolean; + promptVersionUsed?: number; citations?: AiRagCitation[]; confidence?: number; usedFallbackModel?: boolean;