HEL-282: 写库路径事务提交与审计留痕自查修复

同类未提交即 close 回滚、业务与审计拆成两笔事务的路径一并收进可嵌套事务边界。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
总工
2026-08-30 23:02:14 +08:00
co-authored by Cursor multica-agent
parent 9e0e4a103a
commit 9193a3fce0
16 changed files with 511 additions and 257 deletions
+50
View File
@@ -257,6 +257,56 @@ class ProjectionTests(LedgerBase):
self.assertEqual("confirmed", revision["state"])
self.assertEqual("receivable", revision["subject_code"])
def test_reopen_subject_survives_connection_close(self) -> None:
"""HEL-282: create_event used to commit the replacement event while
the bank-source re-claim stayed uncommitted; close() dropped the claim."""
from bank_importer.db import connect as db_connect
self.pair(self.company_a, self.company_b, "100.00")
ledger_events.reconcile_bank_events(self.connection, actor=self.admin)
original_id = self.ledger_events()[0]["id"]
subjects.confirm_subject(
self.connection, original_id,
perspective_company_id=self.company_a, subject_code="receivable",
reason="确认应收", expected_revision=1, request_key="k1",
actor=self.admin,
)
new_id, _ = ledger_events.reopen_subject(
self.connection, original_id,
reason="科目复核更正为其他应收", actor=self.admin,
)
self.connection.close()
fresh = db_connect(self.db_path)
try:
claim = fresh.execute(
"SELECT ledger_event_id FROM ledger_event_bank_sources"
).fetchone()
new_state = fresh.execute(
"""
SELECT r.state FROM current_ledger_event_revisions c
JOIN ledger_event_revisions r ON r.id = c.revision_id
WHERE c.ledger_event_id = ?
""",
(new_id,),
).fetchone()
suggestions = fresh.execute(
"SELECT COUNT(*) AS n FROM ledger_subject_suggestions WHERE ledger_event_id = ?",
(new_id,),
).fetchone()["n"]
reversal = fresh.execute(
"""
SELECT COUNT(*) AS n FROM ledger_event_revisions
WHERE posting_kind = 'reversal' AND reverses_ledger_event_id = ?
""",
(original_id,),
).fetchone()["n"]
finally:
fresh.close()
self.assertEqual(new_id, claim["ledger_event_id"])
self.assertEqual("pending_subject", new_state["state"])
self.assertGreaterEqual(suggestions, 1)
self.assertEqual(1, reversal)
class SubjectSuggestionTests(LedgerBase):
def test_mirror_mapping_is_symmetric(self) -> None: