Files
asepharyana-hub/docs/plan/tools/implementation.md
T

323 lines
12 KiB
Markdown
Raw Normal View History

# Implementation Plan
## Phase Breakdown
```
Phase 1 — Foundation + Document Scanner MVP
├── Milestone 1.1: Rust backend skeleton (Gateway + Worker + NATS + Redis)
├── Milestone 1.2: Scanner pipeline core (edge → warp → enhance → B&W)
├── Milestone 1.3: Next.js frontend + upload + download
└── Milestone 1.4: OCR + searchable PDF + WebSocket progress
Phase 2 — Scanner Complete + Image Tools
├── Milestone 2.1: Scanner fallback manual crop + PWA camera
├── Milestone 2.2: Image compress, resize, convert (WASM client-side)
├── Milestone 2.3: Background removal (ONNX)
└── Milestone 2.4: Batch processing
Phase 3 — PDF Tools + Video/Audio
├── Milestone 3.1: PDF merge, split, images-to-pdf
├── Milestone 3.2: Video compress, extract audio
└── Milestone 3.3: Final polish + load testing
```
---
## Phase 1: Foundation + Document Scanner MVP
### Milestone 1.1 — Rust Backend Skeleton
**Goal**: Gateway + Worker bisa connected ke NATS + Redis, upload flow work.
**Tasks**:
| # | Task | Files | Detail |
|---|------|-------|--------|
| 1.1.1 | Init Rust workspace | `apps/tools/backend/Cargo.toml` | Workspace dengan 3 crate: `gateway`, `workers`, `common` |
| 1.1.2 | Common types | `common/src/types.rs` | `JobStatus`, `Job`, `Tool`, `ScanOptions`, `UploadResponse` |
| 1.1.3 | Common error | `common/src/error.rs` | `PipelineError`, `UploadError`, `NatsError` |
| 1.1.4 | NATS subjects | `common/src/nats.rs` | Constants untuk semua subject/stream |
| 1.1.5 | Gateway: config | `gateway/src/config.rs` | Env-based config (Redis URL, NATS URL, storage path) |
| 1.1.6 | Gateway: upload route | `gateway/src/routes/upload.rs` | Multipart upload, validasi, save ke temp, publish NATS |
| 1.1.7 | Gateway: job status | `gateway/src/routes/job.rs` | GET job status dari Redis |
| 1.1.8 | Gateway: download | `gateway/src/routes/download.rs` | Stream file dari storage |
| 1.1.9 | Gateway: NATS publish | `gateway/src/nats/publisher.rs` | Publish job + progress |
| 1.1.10 | Gateway: Redis job | `gateway/src/redis/job.rs` | CRUD job status di Redis |
| 1.1.11 | Gateway: main | `gateway/src/main.rs` | Axum app bootstrap + routes |
| 1.1.12 | Workers: main loop | `workers/src/main.rs` | NATS consumer, dispatch ke tool handler |
| 1.1.13 | Workers: NATS consumer | `workers/src/nats/consumer.rs` | Subscribe jobs queue, ack/nack |
| 1.1.14 | Worker: scanner stub | `workers/src/scanner/mod.rs` | Cuma menerima job, update progress, complete |
**Acceptance**: `curl -X POST -F "file=@test.jpg" -F "tool=scan" http://localhost:3001/api/upload` → return job_id, setelah beberapa detik `GET /api/job/:id` return completed.
**Effort**: ~3-4 hari
---
### Milestone 1.2 — Scanner Pipeline Core
**Goal**: Image processing pipeline bisa ngubah foto miring jadi lurus + bersih + hitam-putih. Belum termasuk OCR dan PDF.
**Tasks**:
| # | Task | Detail | Referensi |
|---|------|--------|-----------|
| 1.2.1 | Edge detection | Canny + morphological close + adaptive fallback | `pipeline.md` Stage 2-3 |
| 1.2.2 | Corner detection | Contour detection, largest rectangle filter, polygon approximation | `pipeline.md` Stage 3 |
| 1.2.3 | Perspective warp | DLT homography + backward mapping + bilinear interpolation | `pipeline.md` Stage 4 |
| 1.2.4 | Shadow removal | Adaptive illumination correction + Retinex | `pipeline.md` Stage 5 |
| 1.2.5 | Binarization | Sauvola local threshold + integral image optimization | `pipeline.md` Stage 6 |
| 1.2.6 | Deskew | Hough transform line detection + rotation | `pipeline.md` Stage 7 |
| 1.2.7 | Image enhancement | CLAHE + sharpen + contrast | `pipeline.md` Stage 5 |
| 1.2.8 | Pipeline assembly | All stages connected, progress callback per stage | `pipeline.md` Complete assembly |
**Critical Algorithm**: Perspective warp via SVD untuk homography matrix. Butuh implementasi DLT algorithm atau pin `nalgebra` crate.
```rust
// Pseudo untuk testing before optimization
// imageproc contour → corner detection → warp
let edges = robust_edge_detection(&gray);
let corners = find_document_corners(&edges)?;
let warped = perspective_warp(&original, corners);
let cleaned = remove_shadow(&warped);
let binary = binarize(&cleaned);
let final_img = deskew(&binary);
```
**Acceptance**: Image foto miring test → keluar hasil lurus bersih hitam-putih.
**Effort**: ~5-7 hari (ini bagian paling susah)
---
### Milestone 1.3 — Next.js Frontend
**Goal**: User bisa upload foto, liat progress, download hasil.
**Tasks**:
| # | Task | Detail |
|---|------|--------|
| 1.3.1 | Init Next.js app | `bun create next-app` dengan Tailwind v4 + shadcn/ui |
| 1.3.2 | Landing page | Cards: Scan, Image, PDF — link ke masing-masing tool |
| 1.3.3 | Upload zone component | Drag & drop + file picker, validasi tipe/ukuran |
| 1.3.4 | Scanner page | `/scan` — upload area, tool options, progress bar |
| 1.3.5 | API upload route | Next.js API route → proxy ke Rust Gateway |
| 1.3.6 | Progress bar component | Animated bar + stage label dari WebSocket |
| 1.3.7 | Preview component | Before/after comparison slider |
| 1.3.8 | Result page | Preview + download button + file info |
| 1.3.9 | Error handling | Upload error, processing error, timeout |
**Acceptance**: User upload foto → liat progress bar → download PDF.
**Effort**: ~3-4 hari
---
### Milestone 1.4 — OCR + Searchable PDF
**Goal**: Output berupa PDF dengan hidden text layer — teks bisa di-copy, file bisa di-search.
**Tasks**:
| # | Task | Detail |
|---|------|--------|
| 1.4.1 | Install Tesseract data | Tambah `tessdata` di Docker image |
| 1.4.2 | OCR integration | `leptess` binding, set language, get text + word boxes |
| 1.4.3 | PDF generation | `lopdf` — page with image + invisible text layer |
| 1.4.4 | WebSocket progress | NATS consumer di Gateway → broadcast ke WS client |
| 1.4.5 | Auto-cleanup scheduler | NATS cron tiap 10 menit, hapus file expired >1 jam |
| 1.4.6 | Rate limiting | Redis sliding window per IP, per tool |
**Acceptance**: Download PDF → buka di browser → teks bisa di-select + di-search.
**Effort**: ~3-4 hari
---
### Phase 1 Total: ~14-19 hari kerja
---
## Phase 2: Scanner Complete + Image Tools
### Milestone 2.1 — Scanner Fallback + PWA
**Goal**: Scanner robust — kalau auto gagal, user bisa atur manual. Kamera langsung dari browser.
**Tasks**:
| # | Task | Detail |
|---|------|--------|
| 2.1.1 | Manual crop UI | Canvas: 4 draggable corners, background image |
| 2.1.2 | Fallback pipeline | Auto → gagal → manual → kirim corners ke worker |
| 2.1.3 | Camera capture | PWA: akses kamera via `getUserMedia`, capture frame |
| 2.1.4 | Auto-exposure helper | Tap to focus + exposure lock |
| 2.1.5 | Batch multi-page | Upload multiple photos → 1 PDF result |
**Effort**: ~4-5 hari
---
### Milestone 2.2 — Image Tools
**Goal**: Compress, resize, convert image langsung di browser (WASM).
**Tasks**:
| # | Task | Detail |
|---|------|--------|
| 2.2.1 | WASM image crate | Compile `image` crate to WASM via `wasm-pack` |
| 2.2.2 | Compress UI | Slider kualitas %, preview perbandingan ukuran |
| 2.2.3 | Resize UI | Input dimensi, lock aspect ratio, preview |
| 2.2.4 | Convert UI | Pilih format output, preview |
| 2.2.5 | Client-side processing | Semua image tool jalan di browser — no upload needed |
| 2.2.6 | Fallback server-side | Kalau WASM gagal/browser tua → upload ke server worker |
**WASM Strategy**:
```rust
// apps/tools/backend/wasm/src/lib.rs
use wasm_bindgen::prelude::*;
use image::{DynamicImage, ImageFormat};
use std::io::Cursor;
#[wasm_bindgen]
pub fn compress_jpeg(bytes: &[u8], quality: u8) -> Vec<u8> {
let img = image::load_from_memory(bytes).unwrap();
let mut output = Cursor::new(Vec::new());
img.write_to(&mut output, ImageFormat::Jpeg).unwrap();
// quality compression via mozjpeg or custom
output.into_inner()
}
```
**Effort**: ~4-5 hari
---
### Milestone 2.3 — Background Removal
**Goal**: Hapus background foto pake AI model ONNX — jalan di Rust native.
**Tasks**:
| # | Task | Detail |
|---|------|--------|
| 2.3.1 | Download RMBG model | `rmbg-1.4.onnx` (atau model lebih kecil seperti `u2net`) |
| 2.3.2 | ONNX Runtime binding | `ort` crate — load model, run inference |
| 2.3.3 | Pre/post processing | Resize ke 1024x1024 → normalize → softmax → threshold |
| 2.3.4 | Mask application | Alpha channel: background transparent / warna solid |
| 2.3.5 | Image preview | Before/after dengan background removal |
**Model Options**:
| Model | Size | Quality | Notes |
|-------|------|---------|-------|
| RMBG-1.4 | ~50MB | Excellent | BRIA, butuh license untuk commercial |
| U-2-Net | ~170MB | Good | Open source, lebih besar |
| MODNet | ~25MB | Good | Ringan, cepat |
| Dis_seg | ~8MB | Decent | Paling kecil, cocok untuk VPS |
**Effort**: ~3-4 hari
---
### Milestone 2.4 — Batch Processing
**Goal**: Upload 10-20 foto sekaligus, diproses parallel, jadi 1 PDF.
**Tasks**:
| # | Task | Detail |
|---|------|--------|
| 2.4.1 | Batch upload UI | Drop zone accept multiple files, thumbnail list |
| 2.4.2 | Group job | 1 group job = N individual jobs, track per-item progress |
| 2.4.3 | Rayon parallel | Worker process multiple pages in parallel |
| 2.4.4 | PDF merger | `lopdf` merge multiple pages → 1 document |
**Effort**: ~3-4 hari
---
## Phase 3: PDF + Video/Audio Tools
### Milestone 3.1 — PDF Tools
| # | Task | Detail |
|---|------|--------|
| 3.1.1 | Merge PDF | Upload 2+ PDF, `lopdf` merge pages |
| 3.1.2 | Split PDF | Input pages "1-3,5,7-9", ekstrak + save jadi 1 file |
| 3.1.3 | Images to PDF | Upload images, sort order, jadi 1 PDF |
| 3.1.4 | PDF compress | Re-encode embedded images dengan kualitas lebih rendah |
| 3.1.5 | PDF to images | Tiap halaman → JPEG/PNG |
**Effort**: ~4-5 hari
---
### Milestone 3.2 — Video/Audio Tools
| # | Task | Detail |
|---|------|--------|
| 3.2.1 | Video compress | FFmpeg binding (`ffmpeg-next`), turunin bitrate + resolusi |
| 3.2.2 | Extract audio | MP4 → MP3 via FFmpeg |
| 3.2.3 | Trim video | Start/end time → cut segment |
| 3.2.4 | GIF maker | Video segment → GIF, atur FPS + dimensi |
| 3.2.5 | Audio convert | Format conversion via FFmpeg |
**Catatan**: Video processing heavy — butuh dedicated worker dengan resource lebih besar. Queue priority: video jobs ke stream terpisah dengan max 1 concurrent.
**Effort**: ~5-7 hari
---
### Milestone 3.3 — Final Polish
| # | Task | Detail |
|---|------|--------|
| 3.3.1 | Theme integration | Twilight Terminal theme dari hub |
| 3.3.2 | Responsive design | Mobile-first, touch-friendly crop |
| 3.3.3 | Error monitoring | Error tracking, alert kalau pipeline gagal |
| 3.3.4 | Load testing | k6: simulasi concurrent users, measure P50/P95/P99 latency |
| 3.3.5 | Dashboard integration | Link dari hub dashboard → tools stats |
**Effort**: ~3-4 hari
---
## Timeline Summary
```
Minggu 1: Gateway + upload/download + edge detection + warp
Minggu 2: Enhance + binarization + deskew + Next.js frontend
Minggu 3: OCR + PDF + WebSocket + rate limit + cleanup
─── MVP LAUNCH (Document Scanner ready) ───
Minggu 4: Manual crop fallback + PWA camera + batch
Minggu 5: WASM image tools + compress/resize/convert
Minggu 6: Background removal (ONNX) + PDF tools
─── V1 LAUNCH (Scanner + Image + PDF) ───
Minggu 7: Video/audio tools + final polish
Minggu 8: Load testing + bug fixes + deployment
```
## Critical Path
```
Edge Detection ──▶ Corner Detection ──▶ Perspective Warp
│ │
│ ┌────────┘
│ ▼
│ Shadow Removal ──▶ Binarization ──▶ Deskew
│ │
│ ┌─────────────┘
│ ▼
│ OCR ──▶ PDF Gen ──▶ Output
└───(Kalau gagal)─── Manual Crop ◀── Frontend Canvas
```
**Risks**:
1. Edge detection paling rentan gagal — pipeline harus graceful fallback ke manual crop
2. Homography SVD implementasi perlu numerik stabil — test dengan extreme perspective angles
3. OCR kualitas sangat tergantung pada binarization — Sauvola parameter perlu tuning
4. WASM image processing size besar (~2MB gzipped) — perlu code splitting + lazy load