323 lines
12 KiB
Markdown
323 lines
12 KiB
Markdown
# 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
|