Skip to content

feat(insurance): fetch one recommendation's Archera comparison - #1063

Merged
cristim merged 2 commits into
feat/799-archera-recommendation-dtofrom
feat/799-archera-recommendation-fetch
Oct 17, 2026
Merged

cristim merged 2 commits into
feat/799-archera-recommendation-dtofrom
feat/799-archera-recommendation-fetch

Conversation

@cristim

@cristim cristim commented Oct 17, 2026

Copy link
Copy Markdown
Member

What and why

First half of the per-recommendation Archera comparison (split from #1061 to stay under 400 added lines).

  • Extracts h.insuranceClient(ctx) from the plan comparison handler and shares it (no behaviour change; the plan handler is its caller).
  • Adds the local lineItemClient interface (QuoteClient plus LineItems).
  • Adds exported Handler.FetchRecommendationComparison, called by the route PR (PR3b, feat(insurance): compare one stored recommendation with its Archera line item #1061 rebuilt on this): under a 20s child context covering secret resolution, it reads all LineItems, runs SelectLineItem, and only on a single match calls Comparison with LineItemIDs=[selected] and all three payment options. None or ambiguous returns an empty comparison with no Comparison call. A deadline is a fixed 504; other errors use the existing mapInsuranceError (Retry-After kept); an unsupported client is a fixed 503. No partial results; no vendor text in errors.

Tests and mutations (synthetic fixtures)

Direct tests of the fetch function: selected ID and payment options, none/ambiguous skip Comparison, LineItems and Comparison failures, 429 with Retry-After, unsupported client, deadline. Hand mutation probes, each reverted and each failing a named test: payment options, selected line item ID, none/ambiguous skip, deadline mapping, comparison error swallowed, partial result returned.

Refs #799

Stack: based on #1058 (DTO), which is on #1056 and #1054. Followed by PR3b (route and handler).

🤖 Generated with Claude Code

…ine item

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

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: LeanerCloud/cloud-commitments-platform/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 730b77a5-ef4a-42c3-bdd4-b28df4542809

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@cristim cristim added effort/l Weeks priority/p3 Polish / idea / may never ship severity/low Minor harm urgency/eventually No deadline impact/few Limited audience type/feat New capability triaged Item has been triaged labels Oct 17, 2026
@cristim

cristim commented Oct 17, 2026

Copy link
Copy Markdown
Member Author

Independent review verdict: CLEAN at a8d6be3

Reviewer: fresh cold-briefed agent (non-author), dispatched by claude-cc-pr-merge-2.

Findings (none blocking)

  1. Test gap: handler_insurance_recommendation_fetch.go:48 correctly passes the child ctx to h.insuranceClient(ctx), but the test provider ignores ctx, so swapping it to context.Background() stays green. To cover the "budget covers secret resolution" claim, make recProvider.Client block on ctx.Done() and add a deadline case.
  2. fetch.go:30 maps a parent cancel (client disconnect) to 504 "timed out". Harmless and fail-closed; the route PR may want to handle context.Canceled separately.
  3. For the route PR (feat(insurance): compare one stored recommendation with its Archera line item #1061 rebuilt): the function trusts rec. Account scoping rests on rec.SourceAccountID matching item.SourceAccountID (internal/archera/recommendation_match.go:173-175). The route must build rec from the stored recommendation row after tenant/account authorization, never from request input. The plan ID comes from server config. There is no gap in this PR.

Source of truth checked

  • The refactor has no behaviour change: handler_insurance_comparison.go:28-33, 51-68. insuranceClient keeps the same order and messages (nil, !Configured, ErrNotConfigured, fixed 503), and the existing comparison tests pass.
  • Single match: SelectLineItem (recommendation_match.go:114-132). fetch.go:62 returns an empty comparison with no Comparison call unless SelectOne. LineItemIDs=[selected] and three payment options are at fetch.go:65-66.
  • Budget: context.WithTimeout(ctx, ...) at fetch.go:24. The child ctx goes to insuranceClient, LineItems and Comparison.
  • Errors: mapInsuranceError (handler_insurance_comparison.go:77-101) returns fixed strings only and keeps Retry-After. No vendor text and no partial results (nil, nil on every error path).

What I attacked

Probe (reverted) Result
drop the single-match check / allow ambiguous killed (NoneOrAmbiguousSkipsComparison)
remove the timeout killed (deadline case hangs)
secret resolution on context.Background() survived (finding 1)
LineItems on context.Background() killed
swallow the Comparison error killed (FailuresReturnNoPartialResult)
504 changed to 503 killed
raw err instead of mapInsuranceError killed (code and leak assertions)

Local (macOS): go vet ./internal/api/... is clean. Insurance/Comparison/Recommendation tests pass 221, and the full go test ./internal/api/... passes. Worktree cleaned: yes.

@cristim

cristim commented Oct 17, 2026

Copy link
Copy Markdown
Member Author

Triggering CI (claude-cc-pr-merge-2): no 'CI - Build & Test' or pre-commit run exists for a8d6be3. Reopening now.

…on fetch

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cristim
cristim merged commit 59a4fb2 into feat/799-archera-recommendation-dto Oct 17, 2026
2 checks passed
cristim added a commit that referenced this pull request Oct 17, 2026
* feat(insurance): compare one stored recommendation with its Archera line item

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

* fix(insurance): return the checked client error from the recommendation fetch

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
cristim added a commit that referenced this pull request Oct 18, 2026
…t decimals and null currency (#1058)

* feat(archera): build the recommendation comparison response with exact decimals and null currency

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

* fix(archera): satisfy lint in the recommendation DTO and alternatives

Preallocate vendor alternatives, avoid shadowed test variables and
escape the bidi control character in the sanitizer test.

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

* feat(insurance): fetch one recommendation's Archera comparison (#1063)

* feat(insurance): compare one stored recommendation with its Archera line item

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

* fix(insurance): return the checked client error from the recommendation fetch

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

---------

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

* perf(archera): preallocate vendor alternatives in vendorEntries

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/l Weeks impact/few Limited audience priority/p3 Polish / idea / may never ship severity/low Minor harm triaged Item has been triaged type/feat New capability urgency/eventually No deadline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant