feat(compliance): InvoiceRowsCompleted behandlingshistorik event for migrated invoice rows (#2312) (#2357)

Every migrated sales invoice whose rows complete_invoice_rows writes, from
the migration wizard or the hourly row-completion pass, now leaves one
InvoiceRowsCompleted row in processing_history on a new Invoice aggregate:
the writer, the provider, the consent, the row count, and the header VAT
split before and after when the pass rewrote it (BFL 5 kap 11 §, BFNAR
2013:2 p. 9.16). One run shares one correlation id.

lib/invoices/complete-invoice-rows.ts is the one TypeScript call site for
the RPC and the one emitter: it appends only on wrote = true, records
nothing for already_filled or failed, and keeps the append best-effort
(logged, eventId null) like every other processing_history writer. The
wizard runs on the user's session client, so MigrationOptions takes a lazy
createHistoryClient for the service role. Invoice numbers stay out of the
payload (the personnummer guard would drop ten-digit ones).

Migration 20260906210100 widens the aggregate_type CHECK with Invoice and
registers the event type; pg test covers the catalog row, the aggregate,
and that the CHECK still refuses unknown aggregates.


Claude-Session: https://claude.ai/code/session_01LvMaHcTnwAfxzgYD1fGYX1

Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-09-06 21:04:53 +02:00
committed by GitHub
co-authored by Jakob Wennberg Claude Fable 5.1
parent ebbe50c0f3
commit 6906bc4aa2
14 changed files with 730 additions and 65 deletions
+1
View File
@@ -293,6 +293,7 @@ export type ProcessingHistoryAggregateType =
| 'Period'
| 'Migration'
| 'System'
| 'Invoice'
// Bank connection status
// 'pending_selection' = PSD2 consent granted, awaiting user to pick which