Repository navigation
fix(api): answer refused managed-plan writes with a 409 code - #1011
Conversation
|
Warning Review limit reached
This review includes 3 billable files and costs up to $0.75.
Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing. Or wait 10 minutes for your next included review. View limit details
Comment |
a8c0812 to
4a51fe0
Compare
658b93d to
eabeaf1
Compare
cristim
left a comment
There was a problem hiding this comment.
Independent review of 658b93d: no actionable findings
Scope note: this review covers the pre-rebase SHA. The merge driver will record the range-diff to the new head (eabeaf1); git range-diff on the PR's own commit shows =. Reviewed as the delta over #1010 (a8c0812).
Findings:
- NON-BLOCKING: internal/api/openapi.yaml is not updated. The new 409 body code
editor_reconciliation_requiredand the managed-plan refusal are not described on PUT/PATCH /api/plans/{id} (409 text at ~364) or POST /api/plans/{id}/purchases (~447). No test enforces it, and the editor is dormant, but the spec should say it before the editor ships. Suggested fix: add the code to those 409 descriptions in a follow-up.
What I attacked:
- Consistency: the sentinel maps in one place, mapCreatePlanStorageError (handler_plans.go:147), used by PUT, PATCH, create and disablePlan; every store error from the guarded callers (handler_plans.go:328, :811, handler_purchases.go:672) flows through it. Same 409 plus
details.codeshape as the other NewClientErrorWithDetails 409s (handler_purchases.go:2182 etc.). - A legitimate unmanaged plan cannot reach this branch: the sentinel is only produced by the managed guard.
- Mutation probes (2, reverted): map branch disabled -> TestLegacyWritesOnManagedPlanMapToEditorRefusal and TestManagedPlanRefusalIsHTTP409WithCode fail; code string changed -> TestManagedPlanRefusalIsHTTP409WithCode fails. Real Postgres api Managed tests pass at this SHA.
Gate: CI not applicable until retarget (base is fix/631-guard-plan-update). Labels match the issue set. CodeRabbit: no threads. Additions 170 lines.
|
The independent review above covers 658b93d. claude-cc-631-driver rebased the stack onto main 0a5f790 (includes #1003). The PR's own commits are unchanged, so the verdict carries to eabeaf1 (owner #631 rule). |
A legacy PUT, PATCH or plan disable that the config store refused for an editor-managed plan surfaced as a 500. Map the refusal to 409 with code editor_reconciliation_required and a message pointing the user to the schedule editor. Authorization still runs first, so a caller who may not change the plan gets 403 or 404 and never learns the plan is managed. The code and the planEditorRefusal helper live in a shared file the editor routes will reuse. Refs #631 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
eabeaf1 to
c614ca0
Compare
|
The independent review above covers eabeaf1. Rebased onto main after #1010 merged (0117179); #1011 retargeted to main. The PR's own commits are unchanged, so the verdict carries to c614ca0 (owner #631 rule). |
|
Gate record for c614ca0 (origin/main CLAUDE.md "Review gate"):
Merging at c614ca0 with --match-head-commit. #1012 will be retargeted to main and rebased next. |
A legacy PUT, PATCH or plan disable that the config store refused for
an editor-managed plan surfaced as a 500. Map the refusal to 409 with
code editor_reconciliation_required and a message pointing the user to
the schedule editor. Authorization still runs first, so a caller who may
not change the plan gets 403 or 404 and never learns the plan is
managed. The code and the planEditorRefusal helper live in a shared file
the editor routes will reuse.
Refs #631
Part 2 of 5 of the #631 legacy-writer guards; stacked on #1010; merge bottom first.
Review verdict and evidence
Original review, copied from the per-commit evidence record. Commit 33185f6b was reviewed before the rebase onto origin/main; the rebased commit is eabeaf1.
-run Plan ./internal/api/389 pass, 0 skip.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: eabeaf1. 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