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
- Log in to the deployed dashboard.
- Navigate to Recommendations.
- Click any row to expand the detail drawer.
- 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.
- 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).
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.mdCurrent behaviour
Opening a row in the Recommendations detail drawer today shows:
/api/recommendations/freshness).No time-series usage data, no per-recommendation confidence metadata from the collector.
Steps to reproduce
usage_historytime-series. No collector-supplied confidence./api/recommendations/<id>/detailcall fires (the endpoint doesn't exist; the frontend has a TODO atfrontend/src/recommendations.ts:351referencing 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:
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.tsdetail drawer callsapi.getRecommendationDetail(id)on first expand, memoised for the drawer lifetime.usage_history+ the (backend-supplied) confidence badge + provenance note.Out of scope
References
b66abc4d8(Phase-1 + Phase-2 UX work).known_issues/28_recommendations_detail_endpoint.md.Severity
Medium — drawer is functional with the client-side shim; this upgrade makes the drawer trustworthy (collector-reported confidence beats a heuristic).