refactor(ai): OCR sidecar canonical naming cleanup — typhoon→np-dms, remove hardcoded keys, asyncio.to_thread, ADR-040/041
CI / CD Pipeline / build (push) Successful in 7m37s
CI / CD Pipeline / deploy (push) Failing after 20m15s

This commit is contained in:
2026-06-20 16:37:04 +07:00
parent d418d791a4
commit a80ebef285
70 changed files with 5762 additions and 452 deletions
@@ -0,0 +1,115 @@
# OCR Sidecar — Desk-5439
HTTP API server สำหรับสกัดข้อความจาก PDF ผ่าน np-dms-ocr (Ollama) — รันบน Desk-5439 ตาม ADR-023A/ADR-040.
## สถาปัตยกรรม
```
Backend (QNAP) → POST /ocr-upload → OCR Sidecar (Desk-5439:8765)
PyMuPDF (fast-path: chars > 100)
↓ (ถ้า chars ≤ 100)
prepare_ocr_messages (typhoon_ocr)
+ poppler/pdftoppm (PDF → image)
np-dms-ocr via Ollama /v1/chat/completions
JSON → natural_text (Markdown)
```
## Endpoints
| Endpoint | Method | Auth | หน้าที่ |
|----------|--------|------|---------|
| `/health` | GET | — | ตรวจสอบสถานะ sidecar |
| `/ocr` | POST | X-API-Key | OCR จาก path (ใช้เมื่อ shared volume mount) |
| `/ocr-upload` | POST | X-API-Key | OCR จาก multipart file upload |
| `/embed` | POST | X-API-Key | BGE-M3 embedding (Dense + Sparse) พร้อม CPU fallback |
| `/rerank` | POST | X-API-Key | BGE-Reranker-Large chunk re-ranker พร้อม CPU fallback |
**Removed endpoints:**
- `POST /normalize` — ลบออกแล้วตาม ADR-040 Phase 8 (ไม่มี consumers)
## Environment Variables
| Variable | Default | หน้าที่ |
|----------|---------|---------|
| `OCR_SIDECAR_API_KEY` | (required) | API key สำหรับ authentication (Phase 1) |
| `OCR_SIDECAR_UPLOAD_BASE` | `/mnt/uploads` | Base path whitelist สำหรับ path traversal protection |
| `OLLAMA_API_URL` | `http://host.docker.internal:11434` | Ollama API URL |
| `OCR_MODEL` | `np-dms-ocr:latest` | ชื่อ OCR model ใน Ollama |
| `OCR_TIMEOUT` | `360` | Timeout วินาทีต่อ request |
| `OCR_CHAR_THRESHOLD` | `100` | Fast-path threshold (chars > 100 = ใช้ text layer โดยตรง) |
| `OCR_MAX_PAGES` | `0` | จำนวนหน้าสูงสุด (0 = ทุกหน้า) |
| `OCR_ACTIVE_PROFILE` | (optional) | ชื่อ profile ใน `ai_execution_profiles` |
| `VRAM_HEADROOM_THRESHOLD_MB` | `3000.0` | Threshold สำหรับ CPU fallback |
| `RETRIEVAL_TIMEOUT_SECONDS` | `30.0` | Timeout สำหรับ /embed และ /rerank |
| `MAX_SYSTEM_PROMPT_LENGTH` | `10000` | ความยาวสูงสุดของ systemPrompt |
## การ Deploy
```bash
# 1. คัดลอก .env.example เป็น .env และกรอกค่า
cp .env.example .env
# แก้ OCR_SIDECAR_API_KEY เป็นค่าจริง
# 2. Build และรัน
docker compose up -d --build
# 3. ตรวจสอบ
curl http://192.168.10.100:8765/health
```
## การทดสอบ
```bash
# รันทุก test (จาก project root)
python -m pytest tests/ -v
# รันเฉพาะ unit tests
python -m pytest tests/unit/ocr-sidecar/ -v
# รันเฉพาะ integration tests
python -m pytest tests/integration/ocr-sidecar/ -v
```
### Test Coverage
| Test File | หน้าที่ |
|-----------|---------|
| `test_path_traversal.py` | Path traversal protection (US1) |
| `test_api_key_validation.py` | API key validation (US1) |
| `test_residency_wiring.py` | Adaptive OCR residency wiring (US2) |
| `test_cpu_fallback.py` | CPU fallback for /embed and /rerank (US2) |
| `test_parameter_governance.py` | Runtime parameter governance (US3) |
| `test_active_prompt.py` | System prompt + DMS tags injection (US3) |
| `test_async_performance.py` | Async I/O + lifespan + concurrent requests (US4) |
## ADR-040 Phases
| Phase | Status | หน้าที่ |
|-------|--------|---------|
| Phase 1-2 | ✅ Complete | Setup + Foundational |
| Phase 3 | ✅ Complete | US1: Security Hardening |
| Phase 4 | ✅ Complete | US2: GPU Resource Management |
| Phase 5 | ✅ Complete | US3: Parameter Governance |
| Phase 6 | ✅ Complete | US4: Async I/O Performance |
| Phase 7 | ⏳ Blocked | US5: Network Isolation Auth (รอ ADR-041) |
| Phase 8 | ✅ Complete | Remove /normalize endpoint |
| Phase 9 | ✅ Complete | Polish & documentation |
## ไฟล์ในโปรเจกต์
```
ocr-sidecar/
├── app.py — FastAPI server (async I/O, lifespan)
├── Dockerfile — Docker image (python:3.10-slim + poppler + curl)
├── docker-compose.yml — Compose config (ocr-sidecar + ollama-metrics)
├── requirements.txt — Python dependencies
├── .env.example — Environment template
├── services/
│ ├── vram_monitor.py — VRAM headroom monitoring
│ └── residency_policy.py — Adaptive OCR residency calculation
└── tests/
└── test_retrieval_fallback.py — Retrieval fallback tests
```