diff --git a/backend/src/modules/ai/services/ocr.service.ts b/backend/src/modules/ai/services/ocr.service.ts index 8b3324c3..467dd26c 100644 --- a/backend/src/modules/ai/services/ocr.service.ts +++ b/backend/src/modules/ai/services/ocr.service.ts @@ -2,6 +2,7 @@ // Change Log // - 2026-05-15: เพิ่ม OCR auto-detection service สำหรับ ADR-023A. // - 2026-05-25: แก้ไข AggregateError (empty message) จาก axios โดย wrap เป็น Error พร้อม context ที่ชัดเจน. +// - 2026-05-25: เพิ่ม path remapping (OCR_UPLOAD_BASE_PATH) เพื่อแปลง local upload path เป็น path ที่ sidecar เห็นผ่าน CIFS. import { Injectable, Logger } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; @@ -28,6 +29,8 @@ export class OcrService { private readonly logger = new Logger(OcrService.name); private readonly threshold: number; private readonly ocrApiUrl: string; + private readonly localUploadBase: string; + private readonly sidecarUploadBase: string; constructor(private readonly configService: ConfigService) { this.threshold = this.configService.get('OCR_CHAR_THRESHOLD', 100); @@ -35,6 +38,22 @@ export class OcrService { 'OCR_API_URL', 'http://localhost:8765' ); + // path ที่ backend เห็น → path ที่ sidecar เห็น (ผ่าน CIFS mount) + this.localUploadBase = this.configService + .get('UPLOAD_PERMANENT_DIR', '/app/uploads/permanent') + .replace(/\/permanent$/, ''); + this.sidecarUploadBase = this.configService.get( + 'OCR_SIDECAR_UPLOAD_BASE', + '/mnt/uploads' + ); + } + + /** แปลง local upload path เป็น path ที่ sidecar เห็นผ่าน CIFS mount */ + private remapPath(localPath: string): string { + if (this.localUploadBase && localPath.startsWith(this.localUploadBase)) { + return localPath.replace(this.localUploadBase, this.sidecarUploadBase); + } + return localPath; } /** ตรวจสอบ text layer ก่อนเลือก OCR slow path */ @@ -54,9 +73,11 @@ export class OcrService { } try { + const sidecarPath = this.remapPath(input.pdfPath); + this.logger.debug(`OCR path remap: ${input.pdfPath} → ${sidecarPath}`); const response = await axios.post( `${this.ocrApiUrl}/ocr`, - { pdfPath: input.pdfPath }, + { pdfPath: sidecarPath }, { timeout: 90000 } ); return { diff --git a/specs/04-Infrastructure-OPS/04-00-docker-compose/QNAP/app/.env.example b/specs/04-Infrastructure-OPS/04-00-docker-compose/QNAP/app/.env.example index 0a220482..901aa148 100644 --- a/specs/04-Infrastructure-OPS/04-00-docker-compose/QNAP/app/.env.example +++ b/specs/04-Infrastructure-OPS/04-00-docker-compose/QNAP/app/.env.example @@ -88,6 +88,7 @@ OLLAMA_URL=http://192.168.10.100:11434 # PaddleOCR Sidecar (Admin Desktop Desk-5439 — ADR-023A) OCR_API_URL=http://192.168.10.100:8765 OCR_CHAR_THRESHOLD=100 +OCR_SIDECAR_UPLOAD_BASE=/mnt/uploads # Thai preprocessing microservice (PyThaiNLP — Admin Desktop) THAI_PREPROCESS_URL=http://192.168.10.100:8765 diff --git a/specs/04-Infrastructure-OPS/04-00-docker-compose/QNAP/app/docker-compose-app.yml b/specs/04-Infrastructure-OPS/04-00-docker-compose/QNAP/app/docker-compose-app.yml index b26f6552..3c200850 100644 --- a/specs/04-Infrastructure-OPS/04-00-docker-compose/QNAP/app/docker-compose-app.yml +++ b/specs/04-Infrastructure-OPS/04-00-docker-compose/QNAP/app/docker-compose-app.yml @@ -98,6 +98,7 @@ services: # --- PaddleOCR Sidecar (Desk-5439 — ADR-023A) --- OCR_API_URL: ${OCR_API_URL:?OCR_API_URL required} OCR_CHAR_THRESHOLD: ${OCR_CHAR_THRESHOLD:-100} + OCR_SIDECAR_UPLOAD_BASE: ${OCR_SIDECAR_UPLOAD_BASE:-/mnt/uploads} # --- Numbering --- NUMBERING_LOCK_TIMEOUT: '5000' NUMBERING_RESERVATION_TTL: '300'