Part of #645 (approval-outcome prediction epic — read it first for the big picture).
Goal
Show the prediction to reviewers: a compact badge on review-queue rows and a small panel on the query detail page. Neutral, advisory wording only.
Depends on the backend read-side sub-issue.
Steps
- Types —
frontend/src/types/api.ts: ApprovalPredictionDetail interface (mirror the backend response: id, probability, skipped, skipped_reason, failed, created_at); extend the query-detail type and the pending-review item type (approval_probability?: number | null). frontend/src/types/ws.ts: add the query.prediction_complete event type.
- WS invalidation —
frontend/src/realtime/websocketManager.ts: on query.prediction_complete, invalidate ['queries', queryId] and ['reviews', 'queue'] (follow the query.estimate_complete handler).
frontend/src/components/review/ApprovalPredictionBadge.tsx — compact display for queue rows: probability as a percentage with an info Tooltip. States: value present → "78%" badge; skipped → muted "—" with the reason in the tooltip ("Not enough review history yet"); failed/absent → render nothing. Use Ant Design components and the existing badge conventions in components/common/ — no hardcoded hex colors (theme tokens only), and don't reuse risk colors: this is not a risk level.
- Query detail — on
QueryDetailPage, render a small panel/stat next to CostEstimatePanel with the same loading/absent fallbacks that panel uses.
- Wording (important): strictly neutral — "Historical approval likelihood: 78%", tooltip: "Statistical estimate based on this organization's past review decisions. Advisory only — it never approves or rejects anything." Never phrase it as a recommendation to approve/reject.
- i18n — all strings via
t(): add approval_prediction.* keys to frontend/src/locales/en.json and every other registered locale file (the locale-parity test fails CI otherwise).
Acceptance criteria
ApprovalPredictionBadge.test.tsx (React Testing Library, query by role/label): renders percentage, skipped tooltip reason, and the absent/failed → nothing branch.
- Extended
QueryDetailPage / review-queue page tests for the new panel/column.
npm run lint && npm run typecheck && npm run test:coverage && npm run build all green (locale parity included).
- E2E: no new Playwright spec for v1 — the model needs 50+ decided queries to activate, so only the cold-start "skipped" state would be observable; per the CLAUDE.md e2e rule, state this explicitly in the PR description. Ensure no existing spec's selectors break.
Part of #645 (approval-outcome prediction epic — read it first for the big picture).
Goal
Show the prediction to reviewers: a compact badge on review-queue rows and a small panel on the query detail page. Neutral, advisory wording only.
Depends on the backend read-side sub-issue.
Steps
frontend/src/types/api.ts:ApprovalPredictionDetailinterface (mirror the backend response:id,probability,skipped,skipped_reason,failed,created_at); extend the query-detail type and the pending-review item type (approval_probability?: number | null).frontend/src/types/ws.ts: add thequery.prediction_completeevent type.frontend/src/realtime/websocketManager.ts: onquery.prediction_complete, invalidate['queries', queryId]and['reviews', 'queue'](follow thequery.estimate_completehandler).frontend/src/components/review/ApprovalPredictionBadge.tsx— compact display for queue rows: probability as a percentage with an infoTooltip. States: value present → "78%" badge;skipped→ muted "—" with the reason in the tooltip ("Not enough review history yet");failed/absent → render nothing. Use Ant Design components and the existing badge conventions incomponents/common/— no hardcoded hex colors (theme tokens only), and don't reuse risk colors: this is not a risk level.QueryDetailPage, render a small panel/stat next toCostEstimatePanelwith the same loading/absent fallbacks that panel uses.t(): addapproval_prediction.*keys tofrontend/src/locales/en.jsonand every other registered locale file (the locale-parity test fails CI otherwise).Acceptance criteria
ApprovalPredictionBadge.test.tsx(React Testing Library, query by role/label): renders percentage, skipped tooltip reason, and the absent/failed → nothing branch.QueryDetailPage/ review-queue page tests for the new panel/column.npm run lint && npm run typecheck && npm run test:coverage && npm run buildall green (locale parity included).