docs(readme): fix stale auth/reliability claims, link app walkthrough
- Auth section described a hardcoded admin/password stub; it's now real JWT + bcrypt on /api/v1/* (verified against the actual route handlers). - Known Limitations listed the pending-queue and non-transactional item writes as still-open bugs; both were fixed 2026-07-08 - marked resolved. - Corrected the poll-loop timing (2s x 130 retries = ~4.3min, not "2 min"). - Noted the confirmation-gate step now in the PUT flow, and that Product Scan classification is DINOv2-primary (YOLO fallback), single-pass at upload time - not the separate LAN-dependent call it used to be. - Linked screenshots/v2/WORKFLOW.md + the new slide deck as the visual app walkthrough reference. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JSgYVUWJTGMk7SZqqHH8xy
This commit is contained in:
1 parent
d4c83d2119
commit
e70ad37e6d
1 file changed
+14
-6
@@ -46,7 +46,7 @@ Two consumers of the same backend exist:
|
||||
| Structuring LLM | **vLLM serving PaddleOCR-VL-1.6-0.9B** | Reassembles OCR text fragments into coherent structured text |
|
||||
| Database | **PostgreSQL 15** | Documents, line items, SKU/vendor/customer/store master data |
|
||||
| Orchestration | **Docker Compose** (multi-stage GPU Dockerfile) | Runs the whole backend as one stack |
|
||||
| Product scan (secondary) | **YOLO classifier + PaddleOCR** (`classify_ocr_server.py`, `:8120`) | Single-product photo → product match + expiry-date extraction |
|
||||
| Product scan (secondary) | **DINOv2 similarity search** (YOLO classifier fallback) **+ PaddleOCR** (`classify_ocr_server.py`, `:8120`) | Single-product photo → SKU match via nearest-embedding lookup against reference photos + expiry-date extraction |
|
||||
|
||||
---
|
||||
|
||||
@@ -107,12 +107,17 @@ sequenceDiagram
|
||||
GW-->>App: Parsed result once ready
|
||||
end
|
||||
App->>App: Operator reviews & corrects
|
||||
App->>App: Confirmation dialog (receiver name + consent checkbox)
|
||||
App->>GW: PUT /documents/:id (final data)
|
||||
App->>App: Generate & print delivery receipt PDF
|
||||
```
|
||||
|
||||
The poll loop actually runs every 2 seconds for up to 130 attempts (~4.3 minutes) before giving up and surfacing a timeout error — see `lib/features/documents/pending_documents_provider.dart`.
|
||||
|
||||
For the full field-by-field extraction rules (fused-digit correction, date sanitization, the triple-check SKU matcher, fuzzy store resolution), see [`docs/workflow_detail_aplikasi.md`](docs/workflow_detail_aplikasi.md) and [`docs/regex_rules_example.md`](docs/regex_rules_example.md).
|
||||
|
||||
For a visual, screen-by-screen walkthrough of the Flutter app itself (every page, button, popup, and the algorithms behind them — blur detection, upload/poll/retry, DINOv2 product classification — all captured against the live backend), see [`screenshots/v2/WORKFLOW.md`](screenshots/v2/WORKFLOW.md) and the companion slide deck [`screenshots/v2/Prima-Mart-Scanner-Workflow.pptx`](screenshots/v2/Prima-Mart-Scanner-Workflow.pptx).
|
||||
|
||||
---
|
||||
|
||||
## OCR Accuracy
|
||||
@@ -172,6 +177,7 @@ Reproduce this yourself with `backend/pfm-web-app/scripts/accuracy-check.mts` (`
|
||||
│ ├── features/ # auth, camera, documents, editor
|
||||
│ └── models/
|
||||
├── docs/ # Deep-dive workflow & extraction-rule docs
|
||||
├── screenshots/v2/ # App walkthrough: WORKFLOW.md + slide deck, real-backend screenshots
|
||||
├── test/ # Flutter widget/unit tests
|
||||
├── docker-compose.yml # ⭐ Canonical backend stack — run this one
|
||||
├── docker-compose.demo.yml # Production-mode override (see below)
|
||||
@@ -268,7 +274,7 @@ This drops the dev bind-mount and runs `npm start` against the image's own `npm
|
||||
|
||||
- **Single GPU pipeline, no horizontal scaling.** There's one `pipeline-api` and one `vllm-server` container. Concurrent uploads queue behind the GPU; this is a real throughput ceiling worth load-testing before a multi-driver demo, not just a single-user smoke test.
|
||||
|
||||
- **Auth is a demo stub, not real security.** `/api/v1/auth/login` only accepts a single hardcoded `admin`/`password` pair and returns a fixed literal token string — no route actually verifies that token server-side, and every API route sets `Access-Control-Allow-Origin: *`. Fine for a controlled LAN/demo deployment; do not expose this stack to the open internet as-is.
|
||||
- **`/api/v1/*` enforces real auth; the classic dev routes deliberately don't.** `/api/v1/auth/login` checks a bcrypt-hashed password against a real `accounts` table and signs a JWT; `/api/v1/documents/*` (list, upload, PUT-by-id) reject any request with a missing/invalid token with a real `401`. The Flutter app always goes through this surface. The **classic routes** (`/api/upload`, `/api/parse`, `/api/history`, etc.) and the root/`scan-pfm`/`manual-label` web pages have no login flow and never will — they're dev-only internal tooling, not part of the driver-facing product. Every API route still sets `Access-Control-Allow-Origin: *`, so this is fine for a controlled LAN/demo deployment but not for exposing the stack to the open internet as-is.
|
||||
|
||||
- **The Android release build is debug-signed.** `android/app/build.gradle.kts` has a `// TODO: Add your own signing config` and currently signs release builds with the debug key. Fine for internal install/testing, not for Play Store distribution.
|
||||
|
||||
@@ -289,9 +295,11 @@ This drops the dev bind-mount and runs `npm start` against the image's own `npm
|
||||
|
||||
## Known Limitations
|
||||
|
||||
Tracked, not yet fixed — worth knowing before relying on this for unattended field use:
|
||||
Previously tracked here as open gaps, both now fixed and worth noting as resolved:
|
||||
- ~~Pending-upload queue is in-memory only~~ — it's now persisted to a local Hive box (`lib/core/storage/local_storage.dart`), so an OS-level app kill mid-upload no longer loses the document; the queue reloads and resumes on next launch.
|
||||
- ~~Item-row writes on document save aren't wrapped in a transaction~~ — `PUT /documents/:id` now runs inside `withTransaction` (`backend/pfm-web-app/src/app/api/v1/documents/[id]/route.ts`).
|
||||
|
||||
- The pending-upload queue is in-memory only; an OS-level app kill mid-upload loses that document with no trace or retry affordance.
|
||||
- Item-row writes on document save aren't wrapped in a transaction — a failure mid-write can leave a document with its header saved but item rows silently missing.
|
||||
Still open, worth knowing before relying on this for unattended field use:
|
||||
- The **DO Scan review form's** validation fails silently on submit if a required field (e.g. driver name) is empty — `Form.validate()` returns false and the confirm button's `onPressed` just returns, with no toast or scroll-to-error to tell the operator why nothing happened.
|
||||
|
||||
See `docs/` for the deeper workflow documentation these decisions were audited against.
|
||||
See `docs/` and `screenshots/v2/WORKFLOW.md` for the deeper workflow documentation these decisions were audited against.
|
||||
Reference in new issue
Block a user