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>
55 lines
2.3 KiB
SQL
55 lines
2.3 KiB
SQL
-- InvoiceRowsCompleted: the behandlingshistorik event for a migrated sales
|
|
-- invoice whose rows were written by complete_invoice_rows (migration
|
|
-- 20260906135730), from either of its writers: the migration wizard or the
|
|
-- hourly row-completion pass (#2291, #2312).
|
|
--
|
|
-- The pass inserts invoice_items and rewrites the header VAT split on
|
|
-- invoices whose stored split held no evidence. It writes no bokföringspost,
|
|
-- so BFL 5 kap 5 § (rättelse) does not bind it, but it is automated
|
|
-- processing of räkenskapsinformation, which BFL 5 kap 11 § and BFNAR 2013:2
|
|
-- p. 9.16 want in the behandlingshistorik: what was processed, when, and by
|
|
-- what. Until now the only trail was a log line per invoice in Vercel, and
|
|
-- the migration that wrote the invoices in the first place records no event
|
|
-- either.
|
|
--
|
|
-- One event per completed invoice, emitted by lib/invoices/complete-invoice-
|
|
-- rows.ts (the one TypeScript call site for the RPC, so a writer cannot reach
|
|
-- the RPC without the trail). Payload: the writer, the provider, the consent,
|
|
-- the row count, and the header split before and after when it was
|
|
-- rewritten. UUIDs, counts, amounts and enum strings only.
|
|
--
|
|
-- The aggregate is the invoice, which the aggregate_type CHECK did not admit
|
|
-- (no invoice-level event existed before). 'Invoice' is added the way
|
|
-- 20260423140500 added the AI streams; every value already in the constraint
|
|
-- stays. The catalog row goes in as for every other event type:
|
|
-- processing_history.event_type has an FK to it and the append is
|
|
-- best-effort, so an unregistered type would be lost silently
|
|
-- (lib/processing-history/append.ts, tests/pg/processing-event-types.pg.test.ts).
|
|
--
|
|
-- pg-test: tests/pg/invoice-rows-completed-event.pg.test.ts
|
|
|
|
ALTER TABLE public.processing_history
|
|
DROP CONSTRAINT IF EXISTS processing_history_aggregate_type_check;
|
|
|
|
ALTER TABLE public.processing_history
|
|
ADD CONSTRAINT processing_history_aggregate_type_check
|
|
CHECK (aggregate_type IN (
|
|
'Document',
|
|
'BankTransaction',
|
|
'MatchProposal',
|
|
'Verifikation',
|
|
'CounterpartyTemplate',
|
|
'Period',
|
|
'Migration',
|
|
'System',
|
|
'AIProposal',
|
|
'AIRequest',
|
|
'Invoice'
|
|
));
|
|
|
|
INSERT INTO public.processing_event_types (event_type)
|
|
VALUES ('InvoiceRowsCompleted')
|
|
ON CONFLICT (event_type) DO NOTHING;
|
|
|
|
NOTIFY pgrst, 'reload schema';
|