Files
lcbp3/specs/88-logs/session-2026-05-30-ocr-sandbox-two-step.md
T
admin 52b96d01de
CI / CD Pipeline / build (push) Successful in 5m5s
CI / CD Pipeline / deploy (push) Successful in 3m48s
690608:0012 ADR-035-135 #08
2026-06-08 00:12:31 +07:00

68 lines
3.6 KiB
Markdown

# Session 10 — 2026-05-30 (OCR Sandbox Two-Step Flow)
## Summary
แยก OCR Sandbox เป็น 2 steps ตาม spec 231: Step 1 OCR-only → Step 2 AI Extraction เพื่อให้ admin ตรวจคุณภาพ OCR ก่อนทดสอบ AI prompt
## Backend Changes (B1-B5)
- **AiBatchJobType**: เพิ่ม `sandbox-ocr-only` และ `sandbox-ai-extract` job types
- **AiBatchProcessor**:
- เพิ่ม `processSandboxOcrOnly()` — รัน OCR เท่านั้น, cache OCR text ใน Redis key `ai:sandbox:ocr:{idempotencyKey}` (TTL 3600s)
- เพิ่ม `processSandboxAiExtract()` — ดึง OCR text จาก cache, resolve prompt version (active หรือ version ที่ระบุ), replace {{ocr_text}} และ {{master_data_context}}, run LLM
- **AiPromptsService**: เพิ่ม `findByVersion(promptType, versionNumber)` method สำหรับดึง prompt version ที่ระบุ
- **AiController**:
- เพิ่ม `POST /ai/admin/sandbox/ocr` — Step 1 endpoint (รับ file multipart/form-data)
- เพิ่ม `POST /ai/admin/sandbox/ai-extract` — Step 2 endpoint (รับ requestPublicId + optional promptVersion)
- **AiQueueService**: อัปเดต `enqueueSandboxJob()` รองรับ job types ใหม่และ extraPayload สำหรับส่ง promptVersion
## Frontend Changes (F1-F3)
- **adminAiService**: เพิ่ม `submitSandboxOcr(file)` และ `submitSandboxAiExtract(requestPublicId, promptVersion)` methods
- **OcrSandboxPromptManager.tsx**:
- เพิ่ม states: `sandboxStep` ('ocr'|'ai'), `ocrResult` (requestPublicId, ocrText, ocrUsed), `selectedPromptVersion`
- เพิ่ม handlers: `handleStep1Ocr()` (poll OCR result), `handleStep2AiExtract()` (poll AI result), `handleResetSandbox()`
- Refactor UI: Step 1 (upload + Run OCR button) → Step 2 (prompt version dropdown + Run AI Extraction button + Reset button)
- แสดง OCR Raw Text card หลัง Step 1 เสร็จ (สีน้ำเงิน, badge บอก PaddleOCR/Fast Path)
- แสดง AI Extraction result หลัง Step 2 เสร็จ (สีเขียว, badge บอก promptVersionUsed)
## Schema Fix (ADR-009 + ADR-019)
- **Delta SQL**: สร้าง `2026-05-30-add-ai-prompts-publicId.sql` เพิ่ม `publicId CHAR(36) UNIQUE` column ใน `ai_prompts` table
- **Root Cause**: Entity มี `publicId` field แต่ DB table ไม่มี column นี้ → QueryFailedError: "Unknown column 'AiPrompt.publicId' in 'SELECT'"
- **Fix**: ใช้ CHAR(36) แทน UUID type (MariaDB compatible), generate UUID สำหรับ existing records ด้วย `UUID()` function
## Verification
- Backend TypeScript: ✅ ผ่าน (`npx tsc --noEmit`)
- Frontend TypeScript: ✅ ผ่าน (`npx tsc --noEmit`)
- ESLint: ✅ ผ่าน (แก้ unused `user` parameter ใน `submitSandboxAiExtract`)
## Data Flow
```
Step 1: Upload PDF → POST /ai/admin/sandbox/ocr
BullMQ: sandbox-ocr-only job
OCR Service → Cache OCR text (ai:sandbox:ocr:{id})
Frontend displays OCR Raw Text
Step 2: Select prompt version → POST /ai/admin/sandbox/ai-extract
BullMQ: sandbox-ai-extract job
Retrieve OCR text from cache (ai:sandbox:ocr:{id})
Replace {{ocr_text}} → LLM → JSON result
Frontend displays AI Extraction result
```
## Pending
- Run delta SQL `2026-05-30-add-ai-prompts-publicId.sql` ใน production database
- Restart backend service หลัง apply delta
- Test 2-step flow จริงใน production environment