Repository navigation
refactor(api): take handler_purchases.go functions off the gocyclo ceiling - #1469
Conversation
…iling Fifteen functions in handler_purchases.go sat at cyclomatic complexity 10, the pre-commit gate's limit, so a one-line fix to any of them (in the approve, cancel, revoke, retry and execute paths) forced an unplanned refactor first. Extract natural units instead: the token-authed tails of cancel and revoke, the execute-own branch of direct execute, the immediate-execute tails of both approve paths, the cancel transaction, the request-body parse, the plan-name lookup, the retry email/response tail, and a few shared lookups (pre-fire delay, grace-period config, execution load). Gates keep their order; each extracted authorization helper says which gates ran before it. No behaviour change: the internal/api unit and integration results are identical before and after. The highest complexity left in the file is 9. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Pushed 8e3c17d: one refactor commit taking the 15 functions at gocyclo 10 down to 9 or less, as described in the PR body. |
|
Warning Review limit reached
This review includes 1 billable file and costs up to $0.25. Or wait 59 minutes for your next included review. View limit details
Comment |
|
Independent review (IAmJSD's agent, fresh context, given only the diff, the issue and the PR text): VERDICT: APPROVE Blocking:
Ran: Reviewer: rE3. Bar while the maintainers are away (set by IAmJSD as acting owner): one approving independent review on the head, two for money, auth and security paths. |
|
Independent review (IAmJSD's agent, fresh context, given only the diff, the issue and the PR text): VERDICT: APPROVE Blocking:
Non-blocking:
Attacked: Proving no behaviour change was the main job. I sorted every whitespace-stripped line of the merge-base Body-stale:
Reviewer: rE5. Bar while the maintainers are away (set by IAmJSD as acting owner): one approving independent review on the head, two for money, auth and security paths. |
|
Local verification at |
|
Merged by IAmJSD's agent at IAmJSD's request (IAmJSD is acting owner while the maintainers are away), under the bar IAmJSD set: 2 approving independent review(s) on |
Closes #163
Root cause
gocyclo -over 9 internal/api/handler_purchases.goon main listed 15 functions at exactly 10, the pre-commit gate's ceiling:getPlannedPurchases,authorizeExecutionManagement,executeFailureError,cancelOrRecoverExecution,approveViaToken,approvePurchaseViaSession,authorizeSessionExecuteDirect,cancelPurchase,cancelPurchaseViaSession,revokeViaEmailToken,retryPurchase,getPurchaseDetails,validateExecutePurchaseRequest,executePurchaseandsendPurchaseApprovalEmail. The issue counted 8 to 10; the file has grown since. Any addedif,case,&&or||in one of them failed pre-commit. (cmd/multi_service.gofrom the issue's second comment is in cloud-commitments-cli now, not here.)Fix
One hygiene pass over the file. Each extraction is a natural unit, not a split at an arbitrary line:
authorizeExecuteOwnDirect: the execute-own branch, after admin, nil-auth and execute-any.cancelViaTokenandrevokeViaToken: the token-authed tails. The contact_email gate still runs first, then the token, then the status.executeTokenApproveandexecuteSessionApprove: the immediate-execute tails, which run after every approve gate.authorizeExecutionManagementnow uses the existingloadPlannedExecution, which has the same 404 and 500 mapping.cancelAndReleaseSuppressions: the cancel-plus-suppressions transaction.releaseCanceledSuppressions: the success branch ofcancelOrRecoverExecution. It sits above the hunk that fix(db): contract the canceled rename: normalize, narrow the status CHECKs, stop using cancelled_by #1253 rewrites.unclaimedExecuteError: thefinal == nilcases ofexecuteFailureError. ErrFourEyesDenied is still checked first.parseExecutePurchaseBody: decode, the 1..1000 bound and capacity normalization, still after the permission check and before the scope check.purchasePlanName,plannedPurchasesInScopeandsendRetryApprovalAndFinalize.purchaseDelay(still fails closed on a config error),gracePeriodConfig,approvalRecommendationSummariesandapprovalSendFailure.No behaviour change. After this,
gocyclo -over 9 internal/api/handler_purchases.goprints nothing. Functions now at 9 areauthorizeApprovalAction,executePurchase,authorizeSessionRetry,writeRetrySuccessorTx,loadAndValidateRetryRequest,requireDifferentApprover,authorizeSessionApprove,approvePurchaseViaSession,cancelOrRecoverExecution(8 once #1253 lands),deletePlannedPurchase,runPlannedPurchaseandauthorizeExecutionManagement.Overlap with open PRs: #1253, #1241 and #1239 each touch one hunk of this file. #1241 and #1239 change functions this PR doesn't touch. #1253 changes the lower half of
cancelOrRecoverExecution, and this PR only touches its first branch.Verification
internal/apisuite on the merge base and on this branch and diffed the sorted--- PASS/FAIL/SKIPlines.go test -race -short -v: 4590 lines, identical.go test -race -tags integration -v(testcontainers Postgres): 4958 lines, identical, run on the final commit.gocyclo -over 10and-over 9on the file: none.internal/api, with and withoutintegration: 0 issues.go build ./...,go vet ./...(plain, integration, e2e): pass.scripts/test-git-secrets-allowlist.sh: 183 PASS.There is no new test. This is a pure refactor, so the evidence is the gocyclo output (15 functions before, 0 after) and the identical test results.
🤖 Generated with Claude Code