Every delivery note now carries a QR of its own number, bottom-right, so a
scanner app can resolve the note straight off the printed page.
Drawn as VECTOR — one <Rect> per dark module — not a PNG. Stays crisp at any
print size, adds ~2.5 KB of shapes rather than a compressed blob, and never
touches react-pdf's raster image path, which is exactly what the old
pdf().toString() pipeline silently corrupted.
Verified by decoding rather than eyeballing: the real PDF rasterised at 200
dpi (a normal office laser print) and scanned across the WHOLE page returns
"DN26100401". 28pt over a 21-module code plus the 4-module quiet zone is
~0.96pt per module, comfortably above the ~0.5mm consumer scanners need.
The tests round-trip the matrix through a real decoder (jsQR) at 2, 3, 4 and
6 px/module, where 2px is the pessimistic end of the real print size.
SECURITY NOTE, recorded deliberately: the value is a bare sequential number
(DN{YY}{MM}{DD}{NN} from 01 each day), so it is enumerable. That is acceptable
while the consumer is a closed, logged-in internal app, and the scanner's
resolve endpoint is behind assertBrowserSession. If a QR is ever exposed to
customers, encode an unguessable per-note token instead —
DN26100401.<base64url(HMAC-SHA256(noteId, SECRET))[0..22]> — which needs no new
column because it is recomputed rather than stored.
Also adds an optional `signatureImage` prop to the document: a captured
signature PNG drawn on the "Received By" rule. Verified rendering; the pad
that will feed it is not built yet.