- InvoiceService.ResolveInlineImagesAsync now fetches an invoice's
distinct whitelisted images concurrently (SemaphoreSlim-capped at 4)
instead of one at a time. It ran inline on every invoice render,
including repeated draft-preview renders, so N sequential mfr-portal
round-trips could otherwise add N x latency to a user-facing request.
- Add fuchs.invoice.inlineimages.fetches (counter, tagged by outcome:
success/http_error/bad_content_type/oversized/exception) and
fuchs.invoice.inlineimages.resolve.duration (histogram) to
FuchsTelemetry, matching the project's observability convention for
outbound-HTTP operations.
- MigraDocExtensions.HtmlConverter's pre-resolved-image parameter is
renamed inlineImages -> resolvedImages with generic docs: the
converter fetches nothing and knows nothing about invoices — which
images to resolve, and any whitelist/network policy, is entirely the
caller's concern (InvoiceService, ADR 0018 today; any future caller
tomorrow).
- Add tests asserting fetches actually overlap (not just faster) and
that the new counter/histogram are recorded.
- Update ADR 0018 to describe the concurrent fetch, telemetry, and the
generalized converter parameter.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>