docs(plan): per-sale expiry tracking design — batch registry + candidate matching

Grilled 2026-07-16 with the user; full decision record in
docs/expiry-tracking-plan.md. Core reframe: expiry is captured once per
batch at DO intake (staff-typed on the stock-entry confirmation page, from
the physical packs), so the cashier scan only MATCHES OCR fragments against
the 1-3 known in-stock batch dates instead of free-reading damaged
dot-matrix prints (proven model-capability ceiling, 2026-07-15). Fallback:
auto-FEFO + 'inferred' flag, zero cashier interaction. No cloud, ever.

- docs/expiry-tracking-plan.md: architecture, matching algorithm spec
  (resolveExpiryFromEvidence), schema/API deltas, phases 1-3, testing plan
- backend plans §13 (13.1-13.4): matcher util + offline tuning, route
  wiring + expiry_source provenance, multi-frame union, dot-matrix
  recognizer fine-tune
- root plans §10 (10.1-10.3): cashier fast path, inferred badge +
  end-of-day review, burst capture for mounted camera
- stock-feature-plan.md: extension note (batch dropdown becomes the
  manual-override path)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q8TumxFDnyVnfsR3mxPXfX
This commit is contained in:
Rafhan Mazaya FathurrahmanandClaude Fable 5 committed 2026-07-16 17:00:36 +07:00
1 parent 721dea41dc
commit e6daa9b053
7 files changed
+350 -333

No files matched your search

+43 -5
View File
@@ -487,15 +487,53 @@ implemented** — no code for this feature exists in the codebase yet.
9.4 (needs backend §12.2's decrement hook, not just §12.1's CRUD). 9.5-9.7 are
design-completeness fixes to fold into 9.1-9.4's implementation, not a separate pass.*
## 10. Cashier Fast Path — Automated Expiry Resolution
`lib/features/editor/` (product editor), `lib/features/documents/`,
`lib/features/camera/`
Added 2026-07-16 from a user-directed grilling session (ad-hoc feature per
`AGENTS.md` §7). **Read
[docs/expiry-tracking-plan.md](../docs/expiry-tracking-plan.md) first** — full
design and confirmed decisions (checkout must be fully automated: zero typing,
zero blocking prompts; unresolvable scans auto-record the FEFO batch with an
`inferred` flag). Consumes backend §13's resolution
(`resolvedBatch`/`source`/`score` inside `productScan`). **Blocked on 9.1–9.4
and backend §13.2.**
- **10.1** [TODO] **One-tap (or zero-tap) confirm at the cashier.** The Product
Scan editor pre-selects backend §13's resolved batch; when `source` is
`single_batch`/`matched_exact`/`matched_fragment`, the flow collapses to a
single confirm tap with the resolved expiry shown prominently — grill at
pickup whether to go full auto-confirm (no tap) for high-confidence
resolutions. The §9.4 batch dropdown remains as the manual-override path
only (override ⇒ backend records `expiry_source = 'manual'`).
- **10.2** [TODO] **`inferred` badge + end-of-day review list.** Sales resolved
as `inferred_fefo` show a small amber "perkiraan" badge in the editor and in
the history/documents list — informational only, never a blocking prompt
(confirmed decision). New review entry point (drawer or History filter)
listing flagged sales via backend §13.2's `?expiry_source=inferred_fefo`
filter, so staff can optionally correct them after hours with the packs in
hand — zero checkout impact by design.
- **10.3** [TODO] **Phase 2 — burst capture mode for a mounted camera.** Camera
layer gains a burst mode (N frames over ~1s) intended for a fixed-mounted
phone at the checkout counter; frames upload together and backend §13.3
unions OCR evidence across them. Includes a settings toggle (hand-held
single-shot vs mounted burst). Blocked on backend §13.3.
*Suggested order: 10.1 → 10.2 (10.1's `source` plumbing feeds 10.2's badge);
10.3 only after Phase-1 field measurement says fragment quality is the
bottleneck.*
---
*Sections 1-9 (Flutter) are the only sections this file tracks. Backend
*Sections 1-10 (Flutter) are the only sections this file tracks. Backend
enhancements (formerly sections 5-8 here, removed 2026-07-08) now live
exclusively in [backend/plans/next-enhancements.md](../backend/plans/next-enhancements.md);
that file's §9 holds the backend counterparts to this file's §6-7, §10
holds the backend counterparts to this file's §8, and §12 holds the backend
counterparts to this file's §9 (see
[docs/api-contract-map.md](../docs/api-contract-map.md) and
[docs/stock-feature-plan.md](../docs/stock-feature-plan.md) for the shared
holds the backend counterparts to this file's §8, §12 holds the backend
counterparts to this file's §9, and §13 holds the backend counterparts to
this file's §10 (see [docs/api-contract-map.md](../docs/api-contract-map.md),
[docs/stock-feature-plan.md](../docs/stock-feature-plan.md), and
[docs/expiry-tracking-plan.md](../docs/expiry-tracking-plan.md) for the shared
design docs).*