feat(analysis): live SSE updates in the admin coverage dashboard

The Analysis section now reflects worker progress in real time:

- Opens an EventSource on the live stream while mounted; a "Live" pill
  reflects connection state and reconnects on drop (probes after repeated
  failures so a lost session logs out).
- Applies events incrementally: enqueued marks in-scope loaded pages
  queued; started flips a chip to a pulsing "analyzing"; completed flips
  it green and live-bumps the manga + chapter coverage badges (guarded so
  no double count); failed flips it red. A compact activity ticker shows
  the last few events.
- Server numbers stay authoritative: re-loading the overview or a page
  grid clears the matching live overrides.

API client: analysisStatusStreamUrl() + AnalysisEvent type.

Tests: vitest for the stream URL; Playwright asserts SSE frames flow into
the ticker (existing coverage/drill/queue specs get a default quiet
stream). svelte-check + build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-13 21:12:56 +02:00
parent d0cd31c9a7
commit 8b5bd99446
4 changed files with 334 additions and 9 deletions

View File

@@ -32,7 +32,8 @@ import {
getAnalysisMangaCoverage,
getAnalysisChapterCoverage,
getAnalysisChapterPages,
getAnalysisPageDetail
getAnalysisPageDetail,
analysisStatusStreamUrl
} from './admin';
function ok(body: unknown, status = 200): Response {
@@ -580,4 +581,10 @@ describe('admin crawler api client', () => {
expect(url).toMatch(/\/v1\/admin\/analysis\/pages\/p1$/);
expect(d.status).toBe('none');
});
it('analysisStatusStreamUrl points at the SSE endpoint', () => {
expect(analysisStatusStreamUrl()).toMatch(
/\/v1\/admin\/analysis\/status\/stream$/
);
});
});