* fix(transactions): allow re-linking a bank tx stranded on a reversed verifikat (#988)
A transaction whose journal_entry_id points at a reversed/cancelled entry reads
as "utan koppling" in the UI (the transactions page enriches only status='posted'
links), yet the re-booking guards treated ANY non-null pointer as "already
linked". So a storno'd/corrected transaction could never be linked to another
verifikat or re-categorized: the exact symptom in issue #988.
Add a shared hasLiveJournalEntryLink() predicate used by every re-booking guard
(linkTransactionToJournalEntry, manualLink, categorize-core, and the MCP link
stage-check): a pointer at a non-posted entry is treated as re-linkable, and the
two optimistic-locked writes now lock on the exact previous pointer (null OR the
stale id) instead of always .is(null), so the overwrite goes through race-safely.
hasLiveJournalEntryLink fails closed on a read error so a transient blip can't
detach a genuinely live link.
The source was fixed in #726 (reverseEntry/correctEntry now detach/re-point the
tx); this makes the guards self-heal for the pre-#726 backlog and any future
best-effort miss.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(transactions): detect 0-row CAS before invoice effects; fix categorize commit test
Addresses PR review (CodeRabbit Critical + CI):
- link-journal-entry.ts: the tx UPDATE now .select('id') and treats a 0-row
result as LINK_TX_TX_ALREADY_LINKED, failing BEFORE any invoice settlement /
invoice_payments insert. Without this, a concurrent re-link that lost the CAS
would still mark the invoice paid against a transaction we didn't link (same
optimistic-lock contract manualLink already enforces).
- pending-operations commit route test: the categorize_transaction "already
categorized" case now enqueues the hasLiveJournalEntryLink status read (posted
= live) so it still returns 409. This was the core-only CI failure: the new
liveness read in categorize-core consumed a queued response.
- Updated the link happy-path / invoice-race test enqueues to return a row for
the now-selecting tx UPDATE.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>