New: Asset scanning — Developer Guide (the deep dive)
The scanning journey was spread across three pages and mostly implied.
This traces it end to end: how a printed square of ink becomes an
updated database row.
Twelve sections, the substantive ones being:
- Three scanning surfaces (native camera / in-app scanner / USB gun)
and why none of them is redundant.
- The public base URL — the single most consequential line in the
feature. Why it must not come from the request, the localhost
banner, the sub-folder double-append that would otherwise be
printed onto physical labels, and the two tunnel traps (a rotating
free ngrok URL, and its browser-only interstitial that curl won't
show you).
- The resolve flow, including why three regexes deliberately disagree
(routing is permissive, validation is strict, dispatch is neither).
- The write path: one door, shared with the desktop editor, so a
phone edit gets the same audit trail and warranty sync — and why
the no-op skip is load-bearing both in production and in tests.
- The security model: the token is a name, not a password, and the
unknown-vs-another-company answers are identical on purpose.
- Two mobile strategies in one module — mobile-FIRST scan pages
versus the mobile-ADAPTED module — and the five-step hinge where
they meet, which is what makes a scan land on the detail pane with
the device Back button working.
- How to test a camera headlessly (Y4M fake camera) plus the four
traps hit doing it.
- Failure modes, each mapped to its actual cause.
Section 1b of the labels guide now points here instead of duplicating
it; cross-linked from both QR pages, Mobile: Assets, and the sidebar.
Asset QR labels: document the in-app camera scanner (#938)
Analyst page: a "Scanning a lot of labels" section — the two modes, the
already-set/counted-once behaviour, undo, serial fallback, torch, and
the https caveat stated plainly.
Developer guide: scanner.php / resolve_scan.php / vendored jsQR added to
the file table; a new 1b explaining why the scanner sits next to
scan.php and the decoded-text -> endpoint flow; the schema-gate table
extended; and the verification section gains the fake-camera method
(Y4M into --use-file-for-fake-video-capture), the duplicate-count bug it
caught, the transaction-based cross-company test, and the two headless
traps hit on the way.
QR asset labels (#935): user page + developer guide
A pair: there is real user-facing depth here (printing, scanning, using
a print house, and the reverse flow for pre-printed tags) as well as a
lot underneath.
Asset-QR-Labels.md — the two halves, asset tags and why they're unique
per company, printing one or a batch, what scanning gives you, handing
a job to a professional print house (variable data printing), and
assigning pre-printed tags by scanning.
Asset-QR-Labels-Developer-Guide.md — the two-identifier design and the
question that forces it; why per-company uniqueness CANNOT be a unique
index (NULL tenant_id defeats it, and an index that silently doesn't
apply is worse than none); why the URL is short; the schema gates and
which one is critical; why scan.php is mobile-first rather than
mobile-adapted, and why that's a deliberate departure from the
wrap-don't-edit rule; the print sheet and CSV; the tagging loop; and
the batch selection.
It also writes down four bugs found building it, each with the lesson
rather than just the fix: PHP casting numeric-string array keys to ints
(a dropdown disagreeing with its own page), fputcsv's deprecated
$escape writing HTML into a download, the open row having to be IN the
selection, and text selection starting on mousedown — which is why a
user-select class applied on click can never stop the first shift-click.
Assets.md gains a section pointing at both; _Sidebar.md lists them.