Pier Log Folder-Wide Rescan (multi-file upload overwrite fix)
Bug (MAN-9155, folder 758bff90e3f4649b300141c3, 2026-08-06): Zoe uploaded
two pier-log images ~1s apart via the portal. Each upload Vision-parsed only
its own file and wrote PIERLOGS/pier_log.json wholesale — the 6-pier sheet
(11:48:14) was overwritten by the 2-pier sheet (11:48:27), leaving 2 of 8
piers. The “SOW expected 8, got 2” warning fired but nothing acted on it.
Data repaired same day via ensure_pier_log_parsed(force=True).
Fix (entirely-api 1a2515d): rescan_pier_log_folder() in
pier_log_parser is now the single write path for Vision pier-log results:
- Folder-wide: one Vision call over ALL parseable files in
PIERLOGS/(same asensure_pier_log_parsed force=True), so a later sheet can never erase an earlier one. Skipspier_log.jsonand the_tmp_visionstaging subdir. - Debounce/coalesce: first caller sets a Redis
pierlog:rescan:pending:*key and sleeps 5s; uploads landing in that window returncoalescedand are covered by the pending holder’s scan. Invariant: raw file is written BEFORE the rescan call, and pending is released BEFORE the folder listing — so a coalesced upload is always on disk when the scan runs. - Cross-process lock:
pierlog:rescan:lock:*(TTL 15 min) serializes execution across the api AND worker containers — both write pier_log.json, an in-process asyncio.Lock was never enough. In-process fallbacks cover Redis outages. Deliberately NOT built on ARQ_job_iddedup (keep_result collision suppresses repeats ~1h — reference_arq_dedup_bug). - No clobber on failure: if Vision fails folder-wide and a valid
pier_log.json exists, it is kept (
kept_existing) instead of being overwritten by a single-file legacy placeholder.
Entry points routed through it: auto_parse_pier_log (portal files
background pipeline — its outer per-folder lock removed so coalescing works;
RFI uploads — auto-response now handles coalesced), worker
task_parse_pierlog_vision (field media single+batch, field_upload,
WhatsApp — enqueued file list is now informational only),
document_parser_service._parse_and_save_pier_log (chat uploads / reparse),
and ensure_pier_log_parsed (delegates with debounce 0). CSV/Excel keep the
legacy single-file parser. The unlikely.pics draft flow (pierlog_upload.py)
already batched all files into one Vision call and is unchanged.
Tests: tests/test_pierlog_rescan.py (9, incl. the burst repro). Suite 450
passed. Deployed 2026-08-06 via up -d --build unlikely-api worker scheduler;
new code verified inside all three containers.