Files
accounted/docs/SETTLEMENT_ACCOUNT_REMEDIATION.md
T
Mattsson 8299ee9fb4 fix(bookkeeping): resolve settlement account in all categorization flows and ship mis-booking audit (#1383)
Completes the #985/#986/#987 caller sweep: categorize-core, v1
batch-categorize, pending-operation edits and the MCP categorize path now
resolve the settlement leg from the transaction's cash account instead of
inheriting a hardcoded or stale account. Extends the correct_entry preview
with currency, tax and dimension line metadata so staged corrections
preserve full line fidelity. Adds a read-only audit query and a runbook for
reviewing and correcting historical mis-bookings via staged storno with
explicit approval; no automated bulk mutation.

Fixes #1001

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 18:45:38 +02:00

105 lines
5.4 KiB
Markdown

# Settlement account remediation
Use this runbook to review journal entries that may have been posted against a
different settlement account than the cash account linked to their source bank
transaction. It covers historical entries created before and around the fixes
for issues #985, #986, and #987.
The audit is intentionally broader than a list of confirmed errors. A current
`cash_account_id` does not prove that the transaction had that link when the
entry was posted. Never correct an entry from query output alone.
## Invariants
- Never edit or delete a posted journal entry.
- Correct a confirmed error with storno plus a replacement entry through
`gnubok_correct_entry`.
- Keep every replacement line balanced and preserve the original line metadata.
- Do not write directly to `journal_entries` or `journal_entry_lines`.
- Do not correct a locked or closed period without a separately reviewed and
explicitly approved unlock or reopening workflow.
- Never run a production correction without explicit approval for the exact
company, vouchers, and replacement lines.
## Detect candidates
Run [`scripts/audit-settlement-account-mismatches.sql`](../scripts/audit-settlement-account-mismatches.sql)
against the intended database. The query is read-only and returns current
posted entries whose exact directional settlement leg differs from
`cash_accounts.ledger_account`.
Treat `review_priority` only as an ordering aid:
- `high_review_priority_hardcoded_1930_signature` matches the known historical
failure shape, but still needs evidence review.
- `manual_review_payment_aware_correction_required` identifies a payment flow with a
mismatching account. Detection is supported, but the generic correction
procedure below is not. Stop and use a payment-aware correction path.
- Every `manual_review_*` result may be a later cash-account link, a manual
reconciliation, or another legitimate accounting shape.
## Review each candidate
1. Confirm the transaction belongs to the reported cash account using the
original bank feed or statement and the bank connection metadata.
2. Confirm that the cash-account link existed when the journal entry was
posted. `transaction_updated_at` close to `committed_at` is supporting
evidence, not proof.
3. Fetch the current journal entry and all lines. Stop if the entry was already
reversed, corrected, or linked manually after posting.
4. Confirm there is exactly one settlement leg and that its direction and SEK
amount match the bank transaction.
5. Confirm the only required accounting change is replacing the observed
settlement account with `expected_settlement_account`.
6. Check `effective_lock_status`. Both the fiscal period's `is_closed` and
`locked_at` fields and the company-wide `bookkeeping_locked_through` date
are authoritative lock layers. Any result other than `open` is a hard stop
for the ordinary correction flow. If VAT has already been filed, determine
whether an omprövning is required before reopening anything.
7. Stop when `booking_flow` is `customer_invoice_payment` or
`supplier_invoice_payment`. The generic correction service does not relink
all invoice-payment references from the reversed entry. A payment-aware,
tested correction procedure is required for those candidates.
Keep the reviewed candidate set, evidence, proposed replacement lines, and
reviewer identity together as the correction record.
## Stage the correction
For a confirmed candidate in an open and unlocked period:
1. Re-run the audit query immediately before staging and retain its
`original_lines` value. It includes currency amounts, exchange rates, tax
codes, dimensions, cost centers, and projects that the ordinary journal
query does not return.
2. Re-fetch the entry with `gnubok_query_journal` to confirm that its status,
voucher, amounts, and visible lines still match the fresh audit result.
3. Copy every object from `original_lines` into the `lines` input for
`gnubok_correct_entry`.
4. On the one confirmed settlement line, replace only `account_number` with
`expected_settlement_account`.
5. Preserve debit and credit amounts, line descriptions, currency metadata,
tax codes, dimensions, cost centers, and projects exactly as recorded.
6. Verify that total debits equal total credits and both totals are positive.
7. Stage `gnubok_correct_entry` using the voucher reference or freshly fetched
entry UUID. Review its original and correction previews line by line.
The preview must show the preserved currency, tax, and dimension metadata.
8. Approve the staged operation with `gnubok_approve_pending_operation` only
after the exact operation has explicit authorization. High-risk approval
requires `confirmed: true`.
Do not use `gnubok_reverse_journal_entry` by itself for this case. The business
event remains valid; only its settlement account is being corrected.
## Verify after approval
1. Confirm the original entry is retained with status `reversed`.
2. Confirm a posted storno and a posted corrected entry were created in the
intended fiscal period.
3. Confirm the bank transaction now links to the posted corrected entry.
4. Confirm the corrected settlement leg uses the expected account and amount.
5. Run `gnubok_get_general_ledger` for both the observed and expected accounts.
6. Re-run the audit query. The corrected transaction must no longer appear.
7. Record the new voucher references and verification evidence with the
reviewed candidate set.