When the worksheet selection (N bank rows vs one verifikat) misses by a
few kronor, 'Bokför mellanskillnaden som Bankavgift / Räntekostnad /
Ränteintäkt / Öresavrundning och koppla' books the remainder on
6570 / 8410 / 8310 / 3740 against the bank account, links the rows to the
main verifikat and anchors the residual verifikat through
transaction_voucher_links. Bank accounts only (Skatteverket posts ränta
and avgifter as rows of their own), capped at 5 000 kr, direction-checked
against the kind; links are made first and undone if the booking is
refused. Dashboard + v1 doors (transactions:write, Idempotency-Key,
dry run), API skill regenerated.
The bridge now treats transaction_voucher_links as links on both sides:
migration 20260824190000 re-creates get_unlinked_gl_lines and
get_account_gl_lines_for_matching to count junction-linked verifikat as
matched (pg-real test), and the TS engine + items do the same for the
transactions. This also stops bulk-booked samlingsverifikat from
polluting the open buckets. 'Koppla bort' drops the junction rows too.
Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
'Matcha manuellt' as designed: outside rows on the left (multi-select),
verifikat without an outside row on the right (single-select), the
selection's arithmetic in the footer, and one Koppla that is enabled only
when the difference is 0. Mode lives in the URL (?mode=match).
Engine: a pair is now one OR MANY outside rows against one verifikat.
Bank groups link per transaction (manualLink allows N:1 by design, so
partial success is reported per row). Skattekonto groups go through the
new linkSkattekontoRows: the verifikat's 1630 side must settle the sum,
one guarded UPDATE links the whole group, and a partial hit is rolled
back as LINK_RACE. 1:M stays UNSUPPORTED_PAIR_SHAPE until the residual
link table (6c). v1 pitfalls + API skill regenerated.
Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>