fix(writeback): publish ledger entries to QuickBooks one entry at a time - #1469
Conversation
Write-back tracked QuickBooks ids per event, so an event's entries went together or not at all: - close published every entry linked to an event, whatever its period; - a rejection partway through a multi-entry event dropped the ids of the entries that had already landed, and the retry posted them again; - a schedule's auto-reversal carried no event link, so it never published. Ids are now recorded per entry in metadata.qb_entry_ids (qb_external_id is kept, comma-joined, for the cross-source matcher). Close publishes only the entries in the period it is closing, every entry is built before the first POST, a partial failure keeps what landed, and the event is fulfilled once no draft remains. The obligation handler links the reversal to its event. Execute also applies close's source rule, so synced-in QuickBooks events are never sent back; refuses an event with no drafted ledger rows instead of publishing its captured metadata; and moves to pending only where that transition is legal. Re-authorizing a QuickBooks connection against a different company is refused.
|
Change classification: normal — platform or application code changed. A normal change carries a documented automated review on this pull request before merge, in place of a second human approver. The |
|
@claude please review this PR |
|
Claude finished @jfrench9's task in 3m 50s —— View job Review
Note: the sandbox's network fetch was unavailable, so I read the changed files directly on the checked-out branch rather than diffing against SummaryThis is a well-scoped, carefully-reasoned fix. The per-entry tracking model ( Two things worth a look, neither blocking: 1. return ExecuteEventBlockResponse(
event_id=str(event.id),
status=str(event.status),
qb_external_id=next(iter(newly_published.values()), None)
or next(iter(published.values()), None),
qb_error=None,
)
2. Everything else checked out:
Test coverage matches the claims in the PR description (period-scoped publish, per-entry eligibility, mid-batch rejection, mapping-error-posts-nothing, reversal linking, re-OAuth realm check) and the new |
Summary
QuickBooks write-back tracked QuickBooks ids per event, so an event's entries were published together or not at all. That caused three defects on
qb_authoritative/hybridgraphs:Changes
metadata.qb_entry_ids.qb_external_idis still written, comma-joined, for the cross-source matcher in the loader. Each POST's RequestId is the entry id.entry_idsfor the entries in the period it is closing. The event becomesfulfilledonce no draft of it remains, so an entry in a later period publishes when that period closes.schedule_entry_duelinks the reversal entry to its event.execute-event-blockapplies close's source rule. Synced-in QuickBooks events are never sent back.pending. A failed publish moves the event topendingonly where that transition is legal.captured→pendingused to strand the event.pending_oauth.Compatibility
qb_external_idwithoutqb_entry_ids. They are treated as fully published, exactly as before.Tests
entry_idsscoping.just test-allpasses.🤖 Generated with Claude Code