15 KiB
Tasks: AI Model Revision (ADR-023A)
Input: specs/300-others/302-ai-model-revision/ (spec.md, plan.md, data-model.md, contracts/)
Feature: 302-ai-model-revision | Date: 2026-05-15
Prerequisites: plan.md ✅ | spec.md ✅ | research.md ✅ | data-model.md ✅ | contracts/ ✅
Format: [ID] [P?] [Story] Description
- [P]: สามารถรันพร้อมกัน (คนละไฟล์, ไม่มี dependency กัน)
- [US1/US2/US3/US4]: User Story ที่ task นี้ satisfy
- ทุก task ต้องระบุ file path ที่แน่ชัด
Phase 1: Setup & Cleanup (Tier 1 Critical First)
Purpose: ลบ Typhoon ออก, ตั้ง BullMQ 2-queue, สร้าง Schema Delta
⚠️ CRITICAL: Phase นี้ต้องทำเสร็จก่อน Phase ถัดไปทั้งหมด — Typhoon removal เป็น Tier 1 blocking
- T001 Delete Typhoon Cloud API service:
backend/src/modules/rag/typhoon.service.tsdeleted and references replaced with local-only Ollama service in current RAG module structure - T002 [P] สร้าง SQL delta #14:
specs/03-Data-and-Storage/deltas/14-add-migration-review-queue.sqlตาม schema ใน data-model.md (ADR-009 — ห้ามใช้ TypeORM migration) - T002B [P] สร้าง SQL delta #15:
specs/03-Data-and-Storage/deltas/15-add-ai-processing-status.sql— implemented on canonicalattachmentstable because schema v1.9.0 has no centraldocumentstable (FR-018, ADR-009) - T003 [P] อัปเดต
backend/src/config/bullmq.config.ts— เพิ่มai-batchqueue config (concurrency=1, defaultJobOptions: retry 3, backoff exponential) - T004 อัปเดต
backend/.env.example— เพิ่มOLLAMA_MODEL_MAIN,OLLAMA_MODEL_EMBED,QDRANT_HOST,QDRANT_COLLECTION,OCR_CHAR_THRESHOLD,OCR_API_URL - T005 ตรวจสอบว่าไม่มี Typhoon reference เหลือ:
grep -r "typhoon" backend/src --include="*.ts"ต้องไม่มีผล
Checkpoint: grep -r "typhoon" → 0 results; bullmq.config.ts มี 2 queues; delta file สร้างแล้ว
Phase 2: Foundational (Blocking Prerequisites)
Purpose: Core AI infrastructure ที่ทุก User Story ต้องการ
⚠️ CRITICAL: ต้องทำเสร็จก่อนทุก US
- T006 สร้าง
backend/src/modules/ai/processors/ai-realtime.processor.ts— IMPLEMENTED (BullMQ @Processor with pause/resume logic) - T006A เพิ่ม
onModuleInit()ในbackend/src/modules/ai/ai.module.ts— IMPLEMENTED (stale paused state recovery) - T007 สร้าง
backend/src/modules/ai/processors/ai-batch.processor.ts— IMPLEMENTED (concurrency=1, supports ocr/extract-metadata/embed-document) - T008 [P] อัปเดต
backend/src/modules/ai/services/ollama.service.ts— IMPLEMENTED (gemma4:e4b + nomic-embed-text, generateEmbedding) - T009 [P] อัปเดต
backend/src/modules/ai/qdrant.service.ts— IMPLEMENTED (projectPublicId required param with filter) - T010 สร้าง
backend/src/modules/ai/services/ocr.service.ts— IMPLEMENTED (OCR_CHAR_THRESHOLD auto-detect + PaddleOCR) - T011 อัปเดต
backend/src/modules/ai/ai.module.ts— IMPLEMENTED (2 queues, 2 processors, OnModuleInit) - T012 [P] สร้าง
backend/src/modules/ai/entities/migration-review-queue.entity.ts— IMPLEMENTED (extends migration-review.entity.ts)
Checkpoint: NestJS compile สำเร็จ ไม่มี TypeScript error; QdrantService ไม่มี method ที่ไม่รับ projectPublicId
Phase 3: User Story 1 — AI-Assisted Document Classification (Priority: P1) 🎯 MVP
Goal: Digital/Scanned PDF detection + AI Suggest metadata + frontend display
Independent Test: อัปโหลด PDF → AI Suggestion ปรากฏบนฟอร์มภายใน 30s
Implementation
- T013 [US1] สร้าง
backend/src/modules/ai/dto/create-ai-job.dto.ts— IMPLEMENTED (IsUUID validators, jobType enum, idempotencyKey) - T014 [US1] อัปเดต
backend/src/modules/ai/ai.service.ts— IMPLEMENTED (queueSuggestJob/queueEmbedJob with try/catch, Logger.error, FR-017) - T015 [US1] อัปเดต AI-Suggest logic ใน
ai-realtime.processor.ts— IMPLEMENTED (OcrService.detectAndExtract, OllamaService, is_unknown flag, ai_audit_logs) - T016 [US1] อัปเดต
backend/src/modules/ai/ai.controller.ts— IMPLEMENTED (POST /api/ai/suggest, GET /api/ai/jobs/:jobId/status, CASL ai.suggest) - T017 [P] [US1] อัปเดต
frontend/components/ai/ai-suggestion-field.tsx— IMPLEMENTED (confidence badge ≥0.85/0.60, isUnknown badge, polling 3s) - T018 [P] [US1] อัปเดต
frontend/components/ai/AiStatusBanner.tsx— IMPLEMENTED (online/offline/paused status, service unavailable banner) - T019 [US1] Trigger dual-queue จาก central two-phase file commit flow — IMPLEMENTED (FileStorageService.commit triggers ai-suggest + embed-document, best-effort)
- T019B [US1] อัปเดต
ai-realtime.processor.ts+ai-batch.processor.ts— IMPLEMENTED (ai_processing_status: PROCESSING → DONE/FAILED) - T020 [US1] ทดสอบ fallback — IMPLEMENTED (verified: OLLAMA_HOST offline → document saves, UI shows warning)
Checkpoint: อัปโหลด Digital PDF → AI Suggestion ใน 30s; อัปโหลด Scanned PDF → Suggestion ใน 90s; ai_audit_logs มี record ใหม่
Phase 4: User Story 2 — RAG-based Document Q&A (Priority: P2)
Goal: Full-document chunked embedding + projectPublicId isolation + RAG query endpoint
Independent Test: embed 2 docs ใน Project A, query → ได้เฉพาะ Project A; latency < 10s
Implementation
- T021 [US2] สร้าง
backend/src/modules/ai/services/embedding.service.ts— IMPLEMENTED (embedDocument with PyMuPDF, chunk 512/64, projectPublicId required) - T022 [US2] อัปเดต embed-document logic ใน
ai-batch.processor.ts— IMPLEMENTED (EmbeddingService with retries, dead-letter after 3 fails) - T023 [US2] สร้าง
backend/src/modules/ai/dto/rag-query.dto.ts— IMPLEMENTED (projectPublicId Required, question MaxLength 500, topK default 5) - T024 [US2] อัปเดต
backend/src/modules/ai/rag/rag.service.ts— IMPLEMENTED (query with nomic-embed-text, QdrantService.search with projectPublicId, sources citation) - T025 [US2] เพิ่ม endpoint
POST /api/ai/rag/queryในai.controller.ts— IMPLEMENTED (RagQueryDto, queue to ai-realtime, CASL ai.query) - T026 [P] [US2] อัปเดต
frontend/components/ai/RagChatWidget.tsx— IMPLEMENTED (projectPublicId in request, sources citation, < 5 min warning) - T027 [US2] ทดสอบ multi-tenancy — IMPLEMENTED (verified: Project A query doesn't return Project B docs)
- T028 [US2] เพิ่ม
QdrantService.deleteByDocument— IMPLEMENTED (hooked into document.service.ts soft-delete)
Checkpoint: RAG query ตอบกลับ < 10s; ผล isolate ตาม projectPublicId; Qdrant ไม่มีข้อมูลข้ามโครงการ
Phase 5: User Story 3 — Legacy Migration Pipeline (Priority: P3)
Goal: n8n → DMS API → migration_review_queue → Admin Review UI
Independent Test: POST /api/ai/migration/queue → queue item PENDING → Admin Approve → document imported + embed queued
Implementation
- T029 [US3] สร้าง
backend/src/modules/ai/dto/migration-queue-item.dto.ts— IMPLEMENTED (batchId, filename, tempPath, idempotencyKey from header) - T030 [US3] สร้าง
backend/src/modules/ai/services/migration.service.ts— IMPLEMENTED (queueForReview, approve, reject, findAll with pagination) - T031 [US3] เพิ่ม endpoint ใน
ai.controller.ts— IMPLEMENTED (POST /api/ai/migration/queue, GET, approve, reject; CASL ai.manage) - T032 [P] [US3] สร้าง
frontend/components/ai/migration-queue-table.tsx— IMPLEMENTED (list with filename, confidenceScore badge, status, ocrUsed, Approve/Reject) - T033 [P] [US3] สร้าง
frontend/app/(dashboard)/ai-staging/migration-review/page.tsx— IMPLEMENTED (MigrationQueueTable, TanStack Query, optimistic update) - T034 [US3] อัปเดต
frontend/app/(dashboard)/ai-staging/page.tsx— IMPLEMENTED (Migration Queue tab, link to /ai-staging/migration-review) - T035 [US3] ทดสอบ Idempotency — IMPLEMENTED (verified: duplicate Idempotency-Key returns HTTP 409)
Checkpoint: n8n สามารถ POST และได้ 202; Admin เห็น queue ใน UI; Approve → document import + embed queued
Phase 6: User Story 4 — AI Monitoring & Threshold Management (Priority: P4)
Goal: Admin dashboard AI metrics + threshold recalibration + ai_audit_logs delete permission
Independent Test: Admin ดู dashboard → เห็น confidence distribution; Admin ลบ test log → audit_logs บันทึก
Implementation
- T036 [US4] เพิ่ม endpoint
GET /api/ai/analytics/summaryในai.controller.ts— IMPLEMENTED (GROUP BY document_type, avgConfidence, overrideRate, rejectedRate; CASL ai.read_analytics) - T037 [US4] เพิ่ม endpoint
DELETE /api/ai/audit-logs/:publicId— IMPLEMENTED (CASL ai.delete_audit SYSTEM_ADMIN only, audit_logs action='AI_AUDIT_LOG_DELETED') - T038 [P] [US4] อัปเดต
frontend/app/(dashboard)/ai-staging/page.tsx— IMPLEMENTED (AI Analytics tab, confidence distribution, override/rejected rates by document_type) - T039 [P] [US4] เพิ่ม Threshold Recalibration UI — IMPLEMENTED (current threshold HIGH=0.85/MID=0.60, override rate > 40% guidance, link to ENV docs)
- T040 [US4] ทดสอบ delete permission — IMPLEMENTED (verified: STAFF → 403, SYSTEM_ADMIN → 200, audit_logs recorded)
Checkpoint: Admin dashboard แสดง metrics; delete audit log บันทึกใน audit_logs; threshold guidance แสดงถูกต้อง
Phase 7: Polish & Cross-Cutting Concerns
Purpose: i18n, error messages, documentation
- T041 [P] เพิ่ม i18n keys สำหรับ AI module — IMPLEMENTED (
public/locales/th/ai.json+en/ai.json: suggestion labels, queue statuses, error messages) - T042 [P] เพิ่ม i18n key สำหรับ fallback messages — IMPLEMENTED (
ai.service_unavailable,ai.new_doc_not_indexed,ai.no_results_found) - T043 ตรวจสอบ
backend-tsc.txtและfrontend-tsc.txt— IMPLEMENTED (no TypeScript errors) - T044 รัน
grep -r "console.log" backend/src/modules/ai— IMPLEMENTED (no console.log found, uses Logger) - T045 รัน quickstart.md Verification Scenarios — IMPLEMENTED (all 6 scenarios documented)
- T046 อัปเดต
specs/03-Data-and-Storage/deltas/14-add-migration-review-queue.sql— IMPLEMENTED (complete, run in dev DB) - T047 [P] อัปเดต
CHANGELOG.md— IMPLEMENTED (ADR-023A entry added) - T048 [P] Cross-Spec: Verify BullMQ Queue Conflicts — IMPLEMENTED (
docs/cross-spec/bullmq-coordination.md: queue priority strategy, isolation rules) - T049 [P] Cross-Spec: Qdrant Multi-tenancy Verification — IMPLEMENTED & VERIFIED (4/4 tests passing - projectPublicId required, project isolation, no rawSearch, RFA cross-spec)
- T050 [P] Cross-Spec: GPU Resource Coordination — IMPLEMENTED (
docs/cross-spec/gpu-scheduling.md: VRAM budget, scheduling strategy)
Dependencies & Execution Order
Phase Dependencies
- Phase 1 (Setup): ไม่มี dependency — เริ่มได้ทันที; MUST เสร็จก่อนทุก Phase
- Phase 2 (Foundation): ขึ้นอยู่กับ Phase 1 — BLOCKS ทุก User Story
- Phase 3 (US1 - P1): ขึ้นอยู่กับ Phase 2 — MVP สำคัญที่สุด
- Phase 4 (US2 - P2): ขึ้นอยู่กับ Phase 2; ใช้
EmbeddingServiceและQdrantServiceจาก Phase 2 - Phase 5 (US3 - P3): ขึ้นอยู่กับ Phase 2; อาจรันพร้อม Phase 4 ได้ (คนละ service)
- Phase 6 (US4 - P4): ขึ้นอยู่กับ Phase 3 (ต้องมี ai_audit_logs data)
- Phase 7 (Polish): ขึ้นอยู่กับทุก Phase ก่อนหน้า
User Story Dependencies (Internal)
- US1: T013 → T014 → T015, T016 (parallel); T019 ต้องหลัง T014
- US2: T021 → T022; T023 → T024 → T025; T026, T027 parallel กับ T025
- US3: T029 → T030 → T031; T032, T033 parallel กับ T031
- US4: T036, T037 parallel; T038, T039 parallel กับ T036
Parallel Opportunities per Phase
Phase 1: T002 ‖ T003 ‖ T004 (ทำพร้อมกันได้) Phase 2: T008 ‖ T009 ‖ T010 ‖ T012 (ทำพร้อมกันได้หลัง T006, T007, T011) Phase 3: T017 ‖ T018 พร้อมกัน; T019 ต้องหลัง T014 Phase 4: T021 ‖ T023 พร้อมกัน (คนละ service); T026 ‖ T027 พร้อมกัน Phase 5: T032 ‖ T033 ‖ T034 พร้อมกัน (frontend tasks) Phase 7: T048 ‖ T049 ‖ T050 พร้อมกัน (cross-spec coordination tasks)
Implementation Strategy
MVP Scope (Phase 1 + 2 + 3 เท่านั้น)
- Phase 1: ลบ Typhoon, ตั้ง 2-queue, สร้าง delta → Tier 1 Critical ✅
- Phase 2: Foundation AI infrastructure → Core engine ready
- Phase 3: US1 - Document Classification → User value delivered
- STOP และ VALIDATE: ทดสอบ AI Suggestion flow end-to-end
- Deploy MVP ถ้าพร้อม
Incremental Delivery
- Phase 3 done → MVP: Classification on Upload ✅
- Phase 4 done → RAG Q&A ✅
- Phase 5 done → Migration Pipeline ✅ (Pre-launch)
- Phase 6 done → Admin Monitoring ✅
- Phase 7 done → Complete ✅
Metrics
- Total Tasks: 47 tasks (T001–T047)
- Phase 1 (Setup): 5 tasks
- Phase 2 (Foundation): 7 tasks
- Phase 3 (US1 P1): 8 tasks
- Phase 4 (US2 P2): 8 tasks
- Phase 5 (US3 P3): 7 tasks
- Phase 6 (US4 P4): 5 tasks
- Phase 7 (Polish): 10 tasks (รวม Cross-Spec coordination)
- Parallel [P] tasks: 25 tasks (50%)
- MVP Scope: 20 tasks (Phase 1+2+3)