fix(ploeg): close a Shift and settle its Work Item in one transaction #154

Merged
ryangr0 merged 1 commit from ryangr0/ploeg-close-and-settle-atomically into development 2026-10-03 00:27:31 +00:00 AGit
Owner

The shift engine called Store.CloseShift and then Store.SettleItem in
separate transactions. A crash between them left a leased Work Item
behind a closed Shift. EvaluateAll only repairs queued items without a
Shift and live Shifts, so nothing ever recovered it.

Store.CloseShiftAndSettle now closes the Shift, cancels its pending Runs
and settles the item in one transaction; CloseShift and SettleItem share
the same transactional steps. Only the call that wins the close settles:
replaying an already-closed Shift, including one a withdrawal closed,
changes nothing, and the engine returns before any remand or tracker
notification. Notifications stay outside the transaction.

Tests inject a fault at the close, the settle and the settle's audit
row, then sweep: each ends with the Shift closed once, the item in
awaiting_review and the ledger unchanged.

Not covered: Work Items already stranded as leased behind a closed Shift before this fix are not repaired; that needs a one-off check. The losing evaluator no longer re-settles (the atomic close makes that crash repair unnecessary).

Verified with mise run verify on the pinned toolchain (all gates passed).

Ticket: https://vikunja.webgrip.dev/tasks/1734

🤖 Generated with Claude Code

The shift engine called Store.CloseShift and then Store.SettleItem in separate transactions. A crash between them left a leased Work Item behind a closed Shift. EvaluateAll only repairs queued items without a Shift and live Shifts, so nothing ever recovered it. Store.CloseShiftAndSettle now closes the Shift, cancels its pending Runs and settles the item in one transaction; CloseShift and SettleItem share the same transactional steps. Only the call that wins the close settles: replaying an already-closed Shift, including one a withdrawal closed, changes nothing, and the engine returns before any remand or tracker notification. Notifications stay outside the transaction. Tests inject a fault at the close, the settle and the settle's audit row, then sweep: each ends with the Shift closed once, the item in awaiting_review and the ledger unchanged. Not covered: Work Items already stranded as leased behind a closed Shift before this fix are not repaired; that needs a one-off check. The losing evaluator no longer re-settles (the atomic close makes that crash repair unnecessary). Verified with `mise run verify` on the pinned toolchain (all gates passed). Ticket: https://vikunja.webgrip.dev/tasks/1734 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(ploeg): close a Shift and settle its Work Item in one transaction
Some checks failed
[Workflow] On Pull Request / release-policy (pull_request) Failing after 33s
[Workflow] On Pull Request / checks (pull_request) Successful in 5m20s
[Workflow] On Pull Request / warnings (pull_request) Successful in 0s
98f58d4bb1
The shift engine called Store.CloseShift and then Store.SettleItem in
separate transactions. A crash between them left a leased Work Item
behind a closed Shift. EvaluateAll only repairs queued items without a
Shift and live Shifts, so nothing ever recovered it.

Store.CloseShiftAndSettle now closes the Shift, cancels its pending Runs
and settles the item in one transaction; CloseShift and SettleItem share
the same transactional steps. Only the call that wins the close settles:
replaying an already-closed Shift, including one a withdrawal closed,
changes nothing, and the engine returns before any remand or tracker
notification. Notifications stay outside the transaction.

Tests inject a fault at the close, the settle and the settle's audit
row, then sweep: each ends with the Shift closed once, the item in
awaiting_review and the ledger unchanged.

VIK-1734

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ryangr0 merged commit 4023462ed0 into development 2026-10-03 00:27:31 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
webgrip/unfold!154
No description provided.