compressPhoto skipped HEIC on purpose (Chrome can't decode it), so an
iPhone driver's photos went up as HEIC. WFDASH's AI check can't read
HEIC and most desktop browsers can't show it — Thabo's first two invoice
photos on 2026-10-20 went unread.
Now HEIC/HEIF is always re-encoded to JPEG (downscaled to 2000px) when
the browser can decode it (Safari on iOS/macOS can). Where it can't, the
original is uploaded as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Confirm Collection locks while saving ("Saving…") and the page drops a
second collect for an item already in flight. Repeat taps on slow data
re-ran the save and re-uploaded the photo (7 identical copies on one
item on 2026-10-16).
- PO headers (and a single-PO supplier's list) get an Invoice button:
photograph the supplier invoice once per PO, then "add pg 2", "pg 3".
Pages go onto one customer line of the PO as invoice-<PO>-p<N>.jpg;
WFDASH Collection Confirm already gathers photos per PO card. The page
count is also kept on the device so it survives lines dropping off.
- PO button opens the PO PDF in one tap (shared buildPoFileUrl in
lib/poDocs.ts, also used by the item detail modal).
- Collect modal says whether the PO's invoice is already uploaded, so
the per-item photo is only for problems with the item.
- Photos now upload at 2000px / q0.8 (was 1200px / q0.7) so small print
on invoices stays readable for the AI checks.
- Supplier header counts and detailed view now include items in PO
grouping mode (they showed 0 items before).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every pickup-photo upload on 2026-10-12 failed: 86 of 86 attempts
came back `400 unexpected EOF`, median 7.6s, max 15.6s. The old
comment here blamed a PocketBase `image/*` mime-detection bug, which
was wrong on both counts — `order_item_attachements` has
mimeTypes=null, so nothing was checking the format. Go's multipart
parser was hitting end-of-body before the declared Content-Length
arrived: a 3-8MB Android camera file truncated in transit on mobile
data.
The office side never hit this because WFDASH re-encodes to
1200px/q70 in attachment-compressor.ts before storing. This adds the
same treatment on the driver side so both produce comparable images
(~150-300KB, sub-second transfer).
compressPhoto() never throws and never returns null — on any decode
failure it hands back the original file. Compression here is an
optimisation, not a correctness requirement, so it must never turn a
photo that might have uploaded fine into a hard error.