An invoice's finalisation-time PDF render/store (fds__setInvoiceFile) can
fail silently; the row stays finalised with [file] = NULL and inv/rdoc
(the invoice list's preview icon) 404'd forever with no trace in any log.
- inv/rdoc and rem/idoc now regenerate and persist a missing document on
read, mirroring the legacy VB "idoc" fallback (Fuchs_Database ADR 0025),
gated to finalised + non-external invoices only — a draft render must
never be persisted, since fds__setInvoiceFile/fds__setReminderFile only
write WHERE [file] IS NULL and finalisation would then silently no-op.
- StoreInvoiceDocumentFileAsync/StoreReminderDocumentFileAsync now log
every distinct failure (render threw, render produced 0 bytes, DB write
threw, DB write matched 0 rows) instead of collapsing them into a single
silent empty-array return. The 0-rows case needed switching from
setSQLValue_async (reports success once the command completes, whatever
the row count) to setSQLValue_async_result, whose AffectedRows makes a
no-op UPDATE distinguishable from an actual write for the first time.
- HandleRequestIdoc/HandleReminderIdoc no longer treat
StoreInvoiceDocumentFileAsync's Array.Empty<byte>() failure signal as
success (a bare `ct == null` check never caught it), which would have
served a 0-byte "PDF".
- rdoc/HandleRequestIdoc reject a missing 'id' form field instead of doing
wasted work with an empty id.
- _BackupAndClearInvoiceFile.sql is annotated as a manual-only maintenance
utility, never called from app code, so it's clear why running it leaves
no application log trail.
- Client-side: $inv.pdfPreviewTimeout was 120 (ms) instead of 120000 — the
preview dialog was timing out client-side after 120ms on every call.
- Fixed a genuine process-wide test flake: PdfPipelineTests and
ERechnungMapperTests both install PdfSharp's global font resolver, and
whichever ran first would win, making the other's tests fail
deterministically once eRechnungLib's SystemFontResolver got there
first. FuchsPdf.EnsureFontResolver is now also race-safe under
concurrent first use (a check-then-set without a lock). Also removed
the InvoiceService.PublishAsync failure logging added mid-session after
code review found it duplicated every call site's own, more detailed
logging against ADR 0024's single-write-path rule.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>