Skip to content

Bulk scan ux parallelizable ocr against evidence matrix - #317

Merged
kilodesodiq-arch merged 3 commits into
ChainForgee:mainfrom
BigJohn-dev:Bulk-scan-UX-parallelizable-OCR-against-evidence-matrix
Jul 23, 2026
Merged

Bulk scan ux parallelizable ocr against evidence matrix#317
kilodesodiq-arch merged 3 commits into
ChainForgee:mainfrom
BigJohn-dev:Bulk-scan-UX-parallelizable-OCR-against-evidence-matrix

Conversation

@BigJohn-dev

Copy link
Copy Markdown
Contributor

Closes #301

PR: BulkScannerScreen — Concurrent Scan Pipeline

Backlog item: #93 (docs/maintainer-issue-backlog.md)
Files changed: app/mobile/src/screens/BulkScannerScreen.tsx, app/mobile/src/__tests__/BulkScannerScreen.test.tsx
Difficulty: Medium | Effort: M

Problem

BulkScannerScreen processed QR codes sequentially. Field operators scanning
dozens of items per minute experienced throughput limited to one
verification round-trip at a time.

Solution

Introduced a bounded concurrent scan pipeline with three mechanisms:

Concurrency control (up to 4 in-flight)

  • inFlightRef (mutable ref) guards the callback against stale-state races —
    multiple rapid onBarCodeScanned events within the same render cycle now
    share a single synchronous counter.
  • inFlightCount (state) remains for UI display and for disabling the
    BarCodeScanner callback (onBarCodeScanned={undefined}) once at capacity.
  • MAX_CONCURRENT = 4 allows the camera to keep framing while earlier scans
    resolve in the background.

Deduplication

  • seenRef tracks aidId → timestamp pairs.
  • Scans of the same aidId within DEDUP_TTL_MS (5 s) are skipped with a
    visible "Duplicate scan — skipped" badge.
  • Stale entries are evicted on each new scan to prevent unbounded map growth.

Rate limiting

  • Re-scans of the same aidId within RATE_LIMIT_MS (300 ms) are rejected
    with a "Rate limited — slow down" badge, even outside the dedup window.

Acceptance criteria

Criterion Status
Up to 4 concurrent in-flight scans inFlightRef guard + onBarCodeScanned disabled at capacity
Deduplicated results seenRef TTL-based dedup with eviction
Rate limit handled ✅ Per-aidId cooldown check
Test asserts throughput ≥ 2× on 50 items ✅ See test details below

Test details

Concurrency cap

Simulates rapid synchronous scans and asserts maxObserved ≤ MAX_CONCURRENT.

Throughput ≥ 2× (50 items)

Mocks queueClaimConfirmation with a configurable async delay.
Fires 50 scan events through the component's handler in rapid succession,
measures wall-clock completion time, and compares against a sequential baseline
(50 × delay). Asserts speedup ≥ 2.

Dedup correctness

Feed ['aid-1', 'aid-2', 'aid-1', 'aid-3', 'aid-2'] through the dedup logic
and assert ['processed', 'processed', 'skipped', 'processed', 'skipped'].

Rate limit correctness

Record a scan timestamp and immediately re-scan the same aidId. Assert
the second scan is rate-limited.

Key implementation notes

// Race-condition fix: ref for guard, state for display
const inFlightRef = useRef(0);

// In handleBarCodeScanned:
if (inFlightRef.current >= MAX_CONCURRENT) return;
inFlightRef.current += 1;
setInFlightCount(prev => prev + 1);
try { ... } finally {
  inFlightRef.current -= 1;
  setInFlightCount(prev => prev - 1);
}

inFlightCount is removed from the useCallback dependency array, since
the guard no longer depends on state. This eliminates re-render cascades and
stale-closure bugs.

Rollback

Revert the two changed files. No migration or feature-flag required.

Copy link
Copy Markdown
Contributor

👋 Thanks for the contribution! This PR contains code/test changes and CI workflows were never auto-triggered (a GitHub Actions safety requirement for cross-repo forks). To unblock this for merging, a maintainer needs to either:\n\n1. Manually click 'Approve and run workflows' on this PR's Actions tab via the GitHub UI, or\n2. Approve the pending CI on the PR checks page.\n\nOnce the CI checks pass, this can be merged. 🚀

@kilodesodiq-arch kilodesodiq-arch left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kilodesodiq-arch
kilodesodiq-arch merged commit 3a7d872 into ChainForgee:main Jul 23, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bulk-scan UX: parallelizable OCR against evidence matrix

2 participants