Skip to content

feat(api): add GET /api/recommendations/:id/detail for the Recommendations drawer #44

@cristim

Description

@cristim

Summary

The Recommendations row-click detail drawer (shipped in b66abc4d8) renders only the columns already present in the listing payload — there's no usage-history drill-down or confidence bucket. The frontend partially closed the gap with a heuristic client-side confidence badge and a provenance line from /api/recommendations/freshness, but the full "why this recommendation" drawer needs a new backend endpoint.

Captured in: known_issues/28_recommendations_detail_endpoint.md

Current behaviour

Opening a row in the Recommendations detail drawer today shows:

  • Service, current type, recommended type, monthly savings (from the list row).
  • Client-side confidence badge (high/medium/low, heuristic on savings × count).
  • Provenance line (last-collected timestamp + provider name, derived from /api/recommendations/freshness).

No time-series usage data, no per-recommendation confidence metadata from the collector.

Steps to reproduce

  1. Log in to the deployed dashboard.
  2. Navigate to Recommendations.
  3. Click any row to expand the detail drawer.
  4. Observe the drawer content: only the columns from the listing row + the heuristic client-side confidence badge + the freshness-derived provenance line. No usage_history time-series. No collector-supplied confidence.
  5. Open DevTools → Network. Confirm no /api/recommendations/<id>/detail call fires (the endpoint doesn't exist; the frontend has a TODO at frontend/src/recommendations.ts:351 referencing the missing contract).

Expected behaviour

The UX audit (Priority 6) asked for usage history over the collection window, a confidence bucket backed by collector-side data, and a provenance note naming the collector + sampling period.

Stuffing this into the list payload would bloat the common case (drawer never opens). A per-id GET is the right shape.

Proposed fix

Add:

GET /api/recommendations/:id/detail

Response shape:

{
  "id": "rec-abc123",
  "usage_history": [
    { "timestamp": "2026-03-20T00:00:00Z", "cpu_pct": 12.4, "mem_pct": 34.2 }
  ],
  "confidence_bucket": "high",
  "provenance_note": "AWS Cost Explorer · 30-day window · sampled hourly"
}

The detail data is already computed server-side during recommendation generation — this is surfacing it on a per-id GET rather than a new analytics pipeline.

Frontend integration

Once the endpoint lands:

  • frontend/src/recommendations.ts detail drawer calls api.getRecommendationDetail(id) on first expand, memoised for the drawer lifetime.
  • Drawer renders a small sparkline of usage_history + the (backend-supplied) confidence badge + provenance note.
  • Existing row-click + drawer chrome stay untouched; only the content changes.

Out of scope

  • Cross-recommendation comparison UI.
  • Per-provider confidence tuning.
  • Streaming detail updates as new collection runs land — re-fetch on drawer expand is fine.

References

Severity

Medium — drawer is functional with the client-side shim; this upgrade makes the drawer trustworthy (collector-reported confidence beats a heuristic).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions