Skip to content

fix(azure): land Advisor field derivation and Synapse collection (recovers #378, #382) - #400

Merged
cristim merged 9 commits into
mainfrom
fix/292-azure-advisor-recover
Oct 13, 2026
Merged

cristim merged 9 commits into
mainfrom
fix/292-azure-advisor-recover

Conversation

@cristim

@cristim cristim commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Closes #292
Refs #47 (wires Synapse only; Search and Managed Redis stay unwired, reasons in the issue comment).
Refs #252 (Advisor page cap only; the subscription cap and other uncapped pagers stay open)

This recovers content that was approved at 462df7e (#378) and 87db9c8 (#382) but was merged into stacked branches by mistake instead of main. #366 and #373 are already on main; this branch is origin/fix/292-azure-advisor-derive-fields with origin/main merged in. The only conflicts were against the squashed #366, resolved to its content plus the follow-up changes from #378/#382.

Contents

  • Advisor conversion derives commitment type, term, currency, SKU and quantity from the payload; resize/shutdown and unmapped reservation types are ignored; unknown or missing values are recorded skips surfaced via PartialResultError; page cap and page errors surface the same way.
  • Advisor Savings Plan rows use ServiceSavingsPlansAll and are dropped when the Benefit Recommendations client returned an SP row for the same (account, term).
  • Synapse is collected under ServiceDataWarehouse. Search (no valid Consumption type, no retail rows) and Managed Redis (same RedisCache type as the cache client, would duplicate rows) are deliberately not wired.

Verification (fixture-based)

GOWORK=off go vet ./... && go test ./... in providers/azure pass; GOWORK=off go build ./... of pkg, providers/aws, providers/gcp and providers/azure pass; pre-commit gocyclo passes. git diff origin/main...HEAD touches only: providers/azure/internal/recommendations/consumption.go, pagination_cap_test.go, recommendations.go, recommendations_advisor_test.go, recommendations_test.go.

🤖 Generated with Claude Code

cristim and others added 8 commits October 13, 2026 20:49
…rtial-result error

A non-USD billing currency or an unpriceable SKU was dropped with only a
log line, so an EUR or GBP account looked like it had no savings. The
skips are now recorded on a context-carried SkipLog and returned from
GetRecommendations as *PartialResultError alongside the recommendations
that did succeed.

Closes #362

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… fail loud on truncation

Only subscription-scoped reservation and Savings Plan Advisor
recommendations are converted; resize and shutdown recommendations are no
longer emitted as RI purchases with count 0. Commitment type, term, SKU
and quantity come from the extended properties and a missing or unknown
value is skipped with a recorded reason instead of defaulting. A page cap
or page error now surfaces as a PartialResultError rather than a
silently partial list.

Refs #292
Refs #252

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s client covers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… partial result

PartialResultError was only reachable from the internal package and the
multi-subscription merge counted any error as a failed subscription,
dropping its recommendations. Export the type and AsPartialResult, give it
a Partial() method, and aggregate skips across subscriptions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…visor converter

Advisor routinely returns reservations for services this collector does not
price; recording them as skips made nearly every subscription partial.
Savings Plan rows now use ServiceSavingsPlansAll, the savings amount guard
tests are restored, and the now-unused extractServiceType is removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…382)

* fix(azure): collect Synapse recommendations in the provider fan-out

The Synapse client was complete and tested but never called from
GetRecommendations. Search and Managed Redis stay out: Search has no valid
Consumption resource type and no reservation prices (#197), and Managed
Redis queries the same RedisCache resource type as the cache client, so
wiring it would emit the same recommendations twice.

Refs #47

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(azure): repair merge of the Synapse wiring onto the Advisor branch

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(azure): stub the Synapse client in the adapter fan-out tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…-recover

# Conflicts:
#	providers/azure/internal/recommendations/consumption.go
#	providers/azure/recommendations.go
@cristim cristim added priority/p2 Backlog-worthy severity/high Significant harm urgency/this-quarter Within the quarter impact/many Affects most users effort/s Hours type/bug Defect labels Oct 13, 2026
@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

  • Run on-demand review

This review includes 5 billable files and costs up to $1.25.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Or wait 53 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 62 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: LeanerCloud/cloud-commitments-go/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: dd6bea67-38a2-4816-8ba3-82eeda4815d7
📥 Commits

Reviewing files that changed from the base of the PR and between a60dfce and 676b9e8.

📒 Files selected for processing: 5
  • providers/azure/internal/recommendations/consumption.go
  • providers/azure/pagination_cap_test.go
  • providers/azure/recommendations.go
  • providers/azure/recommendations_advisor_test.go
  • providers/azure/recommendations_test.go
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cristim

cristim commented Oct 13, 2026

Copy link
Copy Markdown
Member Author

Independent review (claude-opus-5-5) of 676b9e8: APPROVE

This PR recovers #378 + #382, which the gate merged into their stacked bases instead of main. Review only.

  1. The content matches the approved changes. In providers/azure outside services/savingsplans, main (a60dfce) is byte-identical to fix(azure): surface skipped consumption recommendations as a typed partial-result error #366's approved head 2de6006. At 080944e, git diff origin/main 080944e -- providers/azure was identical to git diff 2de6006 87db9c8 -- providers/azure, the union of my approved fix(azure): derive Advisor fields from the payload and fail loud on truncation #378 (462df7e) and fix(azure): collect Synapse recommendations in the provider fan-out #382 (87db9c8). The diff touches no file outside providers/azure, and services/savingsplans (feat(azure/savingsplans): implement Savings Plan recommendations from benefitRecommendations #373) is identical to main.
  2. Nothing from fix(azure): surface skipped consumption recommendations as a typed partial-result error #366 was reverted. The PartialResultError alias, AsPartialResult and the partial branch in mergeSubscriptionResults are present. TestMultiSubscriptionRecommendationsClient_PartialResultKeepsRecommendations and TestGetRecommendations_NonUSDSkipIsSurfaced pass.
  3. The lint-fix delta 080944e..676b9e8 is mechanical:
    • range-by-index in dropCoveredAdvisorSavingsPlans;
    • %v to %w for the page error (errors.Is(err, errAdvisorTruncated) still holds, so collectAdvisorOrSkip behaves the same);
    • the unused ctx dropped from advisorPurchaseKind.
  4. Local evidence (fresh clone, macOS): go vet and go test -count=1 ./... in providers/azure pass, and GOWORK=off go build ./... passes for pkg, providers/aws, providers/azure and providers/gcp.
  5. CI: every check on 676b9e8 is green, including Lint Code (providers/azure), Unit Tests and Integration Tests. The PR is mergeable.

The non-blocking notes from my #378/#382 reviews still apply: Advisor rows repeat per lookback period, and PropagatesContextCancellation still builds real clients on a canceled context.

@cristim
cristim merged commit 9b35837 into main Oct 13, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/s Hours impact/many Affects most users priority/p2 Backlog-worthy severity/high Significant harm type/bug Defect urgency/this-quarter Within the quarter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(azure): advisor rightsizing and shutdown recs emitted as ri purchase recs with count 0

1 participant