Repository navigation
fix(plans): guard delete, reschedule and resume of managed plans - #1013
Conversation
62f0cce to
aeb8700
Compare
cristim
left a comment
There was a problem hiding this comment.
Independent review of 62f0cce: no actionable findings
This review covers the pre-rebase SHA 62f0cce. The merge driver will record the range-diff to the new head (aeb8700). I ran git range-diff on the PR's own commit: it shows = (identical patch).
Findings (all NON-BLOCKING):
- internal/api/handler_purchases.go:~278 vs :308: the early managed check only runs for past-dated rows with recommendations and reads the plan without the lock. If an editor Save lands between the paused->pending transition and RescheduleAwaitingExecution, the caller gets 409 editor_reconciliation_required but the row is already pending (past date, with recommendations). The scheduler does not buy pending rows with recommendations, and the editor reconciles it, so no purchase and no strand. Worth a comment, not a fix.
- Delete refusal blocks on failed-with-submission rows forever (store_postgres_managed_guard.go requireManagedDeleteTx). Fail closed is intended and is tracked as #999 in the next PR.
What I attacked:
- Delete: all 12 status cases, including a lock-wait race where the command inserts a root and marks the plan managed before the delete's lock is granted. The refusal does not strand executions: cancel, pause and run-now never touch the plan guard. Only settled history detaches.
- Resume: no resume path exists in internal/purchase (grep). The only resume is the handler, and run-now from paused (approvals.go:355) changes no date, so there is no inconsistency. RescheduleAwaitingExecution has one caller.
- openapi_409_code_test.go parses openapi.yaml for real (yaml.v3 decode of the file,
$refresolution to components.responses, asserts ErrorWithCode on all 5 operations). - Ran integration tests (testcontainers, Postgres): api and config
-run 'Delete|Reschedule|Resume|Managed|OpenAPI'pass. OpenAPI409 and PGXMock_Delete unit tests pass.
Gate: independent review of this SHA (this comment). CI not applicable until retarget. CodeRabbit not used (owner decision). Local verification as above plus the PR body evidence. Labels mirror the stack; no closing issue ("Refs #631"). 400 additions, at the cap (additions-only rule).
|
The independent review above covers 62f0cce. claude-cc-631-driver rebased the stack onto main 0a5f790 (includes #1003). The PR's own commits are unchanged, so the verdict carries to aeb8700 (owner #631 rule). |
9e78df1 to
eb94c5b
Compare
aeb8700 to
7e7d99b
Compare
|
The independent review above covers aeb8700. Rebased onto main after #1010 merged (0117179); #1011 retargeted to main. The PR's own commits are unchanged, so the verdict carries to 7e7d99b (owner #631 rule). |
eb94c5b to
07f7e9e
Compare
7e7d99b to
832a2e5
Compare
|
The independent review above covers 7e7d99b. Rebased onto main after #1011 merged (173474e); #1012 retargeted to main. The PR's own commits are unchanged, so the verdict carries to 832a2e5 (owner #631 rule). |
Deleting an editor-managed plan detached its live schedule roots, and rescheduling or resuming a planned purchase moved a date the editor owns. Deleting a managed plan that still has a live purchase now answers 409 managed_plan_has_live_executions; settled history detaches as before. Rescheduling or resuming a purchase of a managed plan answers 409 editor_reconciliation_required. Each check runs under the plan lock after authorization, so a writer that waited behind an editor Save sees its committed state. OpenAPI documents the 409 responses on the affected operations. Refs #631 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
832a2e5 to
8aa0ce7
Compare
|
The independent review above covers 832a2e5. Rebased onto main after #1012 merged; #1013 retargeted to main. The PR's own commits are unchanged, so the verdict carries to 8aa0ce7 (owner #631 rule). |
|
Gate record for 8aa0ce7 (origin/main CLAUDE.md "Review gate"):
Merging at 8aa0ce7 with --match-head-commit. #1014 will be retargeted to main and rebased next. |
Deleting an editor-managed plan detached its live schedule roots, and
rescheduling or resuming a planned purchase moved a date the editor
owns. Deleting a managed plan that still has a live purchase now
answers 409 managed_plan_has_live_executions; settled history detaches
as before. Rescheduling or resuming a purchase of a managed plan
answers 409 editor_reconciliation_required. Each check runs under the
plan lock after authorization, so a writer that waited behind an editor
Save sees its committed state. OpenAPI documents the 409 responses on
the affected operations.
Refs #631
Part 4 of 5 of the #631 legacy-writer guards; stacked on #1012; merge bottom first.
Review verdict and evidence
Original review, copied from the per-commit evidence record. Commit 4e1bdb76 was reviewed before the rebase onto origin/main; the rebased commit is aeb8700.
Rebase: the five commits were rebased onto origin/main 0ed85aa (27 commits ahead of the old base).
git range-diffof the old 5 commits against the rebased 5 shows all five as=(identical patches), so the verdict carries over per the owner's rule. New head SHA of this PR: aeb8700. No migration is added by any of the five commits.Review gate
CodeRabbit is not used on this stack (quota; owner decision): the gate is the independent adversarial review above plus the local verification below.
Local verification
Local verification of the rebased stack tip (macOS, Docker Postgres via testcontainers; Linux via CI):
Status on main
The change is dormant on main until the editor Save route ships: only plans marked managed (ramp_schedule.dates_managed) are affected, and only that route sets the marker.
🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Documentation