7.0 KiB
7.0 KiB
TODO
Phase 0: Infrastructure (DONE)
- Azure VMs created and configured (jt-ub, jt-win)
- Ubuntu VM provisioned (Docker, Go, Python, rclone, zsh, dotfiles)
- Directory structures on both VMs (William's layout)
- Sample document generator (7 generators, Azure Claude content pools, CJK fonts)
- Project restructure: Tracker/Setup.bat + Tracker/Code/{Sync,Tools,Tracker}
- Windows rclone sync setup (Setup.bat, Win-Setup.ps1, sync.ps1, config.ini)
- rclone auto-download + self-contained install in _LLM/Code/Sync/rclone/
- Password-based SFTP auth (demo), config.ini for server details
- .sync_ignore generated on setup (excludes_LLM/, dotfiles, temp/lock files)
- 5-minute scheduled task (JingTian-Sync)
- Pull-first-then-push: bidirectional files pulled with --update, excluded from push
- Bidirectional file list in config.ini (e.g. Admin/Tracker.xlsx)
- Daily log rotation in _LLM/Code/Sync/logs/
- Ubuntu VM SSH password auth enabled (Azure cloud-init was blocking it)
- Both sync directions tested and working
- Old JingTian-Rclone repo archived on Gitea
Phase 1: Services (Services-First Approach)
Rationale: De-risk unknowns (Docling OCR quality, Ollama CPU inference speed) before building orchestrator.
1a. Docker Compose + Docling (DONE)
- Docker Compose base (Docling service)
- Test Docling API with sample PDFs (curl)
- Validate OCR quality on real PDFs + generated samples
- Test OCR on images (PNG) — works with
force_ocr=true
Docling API Spec:
- Image:
ds4sd/docling-serve:latest - Port:
5001 - Endpoint:
POST /v1/convert/file - Form params:
files=@<path>;type=application/pdf,to_formats=md,do_ocr=true - Response:
{ "document": { "md_content": "..." }, "status": "success" } - OCR engine:
easyocr(default), supports CJK
OCR Options:
do_ocr=true— enabled by default, processes bitmap contentforce_ocr=true— use for images/scanned PDFs (replaces existing text with OCR)ocr_engine—easyocr(default),tesseract,rapidocr,tesserocr,ocrmacocr_lang— language codes (engine-specific), e.g.ch_simfor Simplified Chinese
Tested Formats:
- PDF (Filing Receipt) — extracted text, tables, CJK content ✅
- PNG (Email screenshot) — extracted subject, dates, recipient ✅
- PNG with
ocr_lang=ch_tra— Traditional Chinese extracted correctly (官藥坊) ✅
Portable Chinese OCR:
- Auto-downloads
ch_sim(Simplified) andch_tra(Traditional) models on first run - Models persist in
docling_modelsvolume - First run takes ~1-2 min extra for model download; subsequent runs instant
- Use
ocr_lang=ch_trafor HK/Taiwan,ocr_lang=ch_simfor Mainland China
1b. Ollama (DONE)
- Add Ollama to Docker Compose (Qwen3-1.7B, CPU mode)
- Test structured extraction prompt (curl)
- Measure inference time per document (~15-30s on 4 vCPU)
- Validate extraction accuracy (deadline, doc type, etc.)
Ollama API Spec:
- Image:
ollama/ollama:0.9.3 - Port:
11434 - Model:
qwen3:1.7b(~1.4 GB, auto-pulled on startup) - Endpoint:
POST /api/generate - Body:
{"model":"qwen3:1.7b","prompt":"...","stream":false,"options":{"temperature":0}} - Response:
{ "response": "<json>" }(strip<think>...</think>tags in post-processing) - Note: Qwen3 includes reasoning by default;
/no_thinkleaves empty tags, so strip instead
1c. Python Tools Service (DONE)
- FastAPI + openpyxl service
- Generic Excel API (not tracker-specific)
- Test with Invoice_Schedule_2026Q1.xlsx
Tools API Spec:
- Image: Custom Dockerfile (python:3.12-slim + fastapi + openpyxl)
- Port:
8000 - Volume:
/data→/data/jingtian/BenjaminTeam
Endpoints:
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Health check |
/excel/sheets |
GET | List sheet names in workbook |
/excel/schema |
GET | Get column headers |
/excel/read |
GET | Read all rows |
/excel/row/{n} |
GET | Get specific row (1-indexed) |
Query Params:
file_path(required) — path relative to/data/sheet_name(required) — name of the sheet to readheader_row(optional, default=1) — which row contains headers
Tested:
- Invoice_Schedule_2026Q1.xlsx with
header_row=4— extracted 6 invoice rows ✅ - Columns: Client, Matter Ref, TM Number, Description, Amount (HKD), Due Date, Status
Future Endpoints (Phase 2+):
POST /excel/row— Add new rowPUT /excel/row/{n}— Update specific rowDELETE /excel/row/{n}— Delete rowPOST /excel/format— Apply formatting
1d. Manual Integration Test (DONE)
- Chain test: PDF → Docling → Ollama → JSON extraction
- Chain test: PNG → Docling (Chinese OCR) → Ollama → JSON extraction
- Chain test: DOCX → Docling → Ollama → JSON extraction
- Chain test: XLSX → Tools API → Ollama → JSON summary
Tested Files:
| File | Type | Docling | Ollama | Key Extractions |
|---|---|---|---|---|
| Filing_Receipt_307800905.pdf | ✅ | ✅ | TM#307800905, NOVA, Class 9, deadline 30-05-2026 | |
| Email_Monee_...20260221.png | PNG | ✅ | ✅ | TM#306527151, 官藥坊, evidence of use |
| Letter_Re_TM306735835.docx | DOCX | ✅ | ✅ | TM#306735835, CALIFORNIA BABY, hearing 17-04-2026 |
| Invoice_Schedule_2026Q1.xlsx | XLSX | ✅ | ✅ | HKD 474,000 total, 6 invoices, 3 sent/1 paid/2 draft |
Notes:
- Qwen3 1.7b correctly extracted Chinese trademark 官藥坊 from PNG
- All deadlines, TM numbers, client names extracted accurately
- Minor: XLSX currency guessed as USD (HKD in source) — fix with better prompting
Phase 2: Go Orchestrator
- Init Go module in Tracker/
- Config loading (YAML)
- SQLite schema + migrations (documents, extractions, processing_log)
- Docling HTTP client
- Ollama HTTP client
- Tools service HTTP client
- File watcher (inotify on Ubuntu, 2-min stability check via SHA256 hash)
- State tracker integration (new/changed/skip logic)
- Pipeline orchestrator (read latest Tracker before writing, merge not overwrite)
Phase 3: Integration + Testing
- End-to-end test (drop file on Windows → syncs to Ubuntu → pipeline → Tracker updates → syncs back)
- Smoke test with real PDFs + generated samples
- README documentation
Future
- Key-based SFTP auth (replace password for production)
- Windows Go service (replace PowerShell scheduled task)
- File hash (SHA256) change detection on Windows side
- WhatsApp deadline notifications
- Processing retry logic
- Multi-client support
- Smarter bidirectional merge (cell-level, not file-level)