---
key: spa.playback-troubleshoot-poll
title: '2026-07-09 — Playback-troubleshooting completion feedback: poll status, no push channel'
status: active
since: '2026-07-09'
supersedes: none
superseded-by: none
rule: The playback-troubleshooting screen reports FFmpeg completion by polling `GET /api/troubleshoot/playback/status` (~2s) rather than a server push channel.
signals: '`PlaybackTroubleshootingScreen.tsx`, `ICourier`/`ISnackbar` parity · paths: `web/src/screens/PlaybackTroubleshootingScreen.tsx` · issues: #145'
mechanics: '`GET /api/troubleshoot/playback/status`'
---

The SPA playback-troubleshooting screen (`PlaybackTroubleshootingScreen.tsx`, #145) reports FFmpeg
completion by **polling `GET /api/troubleshoot/playback/status` every ~2s** while a session is
running (plus one poll on mount so a session started elsewhere still gates Play), rather than a
server push. The status endpoint returns `{ state, exitCode, speed, logs }`; the screen captures the
running→completed/failed transition in local component state and surfaces a completion notice
(success on exit 0, warning otherwise) — the SPA equivalent of the Blazor page's MediatR
`ICourier`/`ISnackbar` `PlaybackTroubleshootingCompletedNotification`. Chosen over SignalR/SSE
because the SPA has **no push channel** and troubleshooting sessions are short and user-initiated, so
a lightweight poll (started on Play, stopped on settle/unmount) is simpler than standing up a new
real-time transport. Speed thresholds and the "(Speed: Nx)" badge colors are copied verbatim from the
Blazor `GetSpeedClass` (red <0.9, green >1.1, amber otherwise).
