Files
netfelix-audio-fix/docs/superpowers/specs/2026-04-15-drop-verify-and-jobs-page-design.md
2026-04-15 06:43:52 +02:00

6.6 KiB
Raw Blame History

Drop verify/checkmarks, merge jobs view into item details

Date: 2026-04-15

Summary

Remove the post-job Jellyfin verification path and its associated verified flag entirely. Delete the standalone /execute jobs page. Surface per-item job info (status, command, log, run/cancel actions) on the item details page instead. Batch queue controls (Run all / Clear) move into the Pipeline column headers.

Rescan becomes the sole source of truth for "is this file still done?" — if a file drifts off-noop, the next scan flips its plan back to pending and the card reappears in Review.

Motivation

The verify feature tried to promote done cards from ✓ to ✓✓ after ffprobe/Jellyfin cross-checked the on-disk file. In practice the Jellyfin refresh path is fragile (times out silently), the ✓/✓✓ distinction adds UI noise without user value, and rescan already catches drift. The separate Jobs page duplicates info that belongs on the item details page and forces users to jump between views to answer "what happened to this file?".

Backend changes

Remove verification path

  • Delete handOffToJellyfin() in server/api/execute.ts (≈lines 3898) and both callers at :492 and :609. Post-job handling is now just the existing jobs.status update.
  • Delete emitPlanUpdate() and the plan_update SSE event emission.
  • Delete POST /api/execute/verify-unverified (≈lines 357389).

Drop verified column

  • Add idempotent migration in server/db/index.ts following the existing try/catch alter() pattern:
    alter("ALTER TABLE review_plans DROP COLUMN verified");
    
    Supported on Bun's bundled SQLite (≥3.35).
  • Remove verified from server/db/schema.ts:77 in the review_plans CREATE TABLE.
  • In server/services/rescan.ts, remove verified from the INSERT column list and the verified = CASE ... branch in the ON CONFLICT DO UPDATE clause.
  • In server/api/review.ts:
    • Remove rp.verified from the pipeline SELECT (≈line 330).
    • Remove verified = 0 from the unapprove UPDATE (≈line 773).

Remove jobs-list endpoint

  • Delete GET /api/execute (the filtered list used only by the Execute page).
  • Keep: /start, /clear, /clear-completed, /job/:id/run, /job/:id/cancel, /stop, /events, SSE events job_update, job_progress, queue_status.

Enrich item details endpoint

  • Extend GET /api/review/:id to include the latest job row for this item (if any):
    job: {
      id: number;
      status: Job["status"];
      job_type: "copy" | "transcode";
      command: string | null;
      output: string | null;
      exit_code: number | null;
      started_at: string | null;
      completed_at: string | null;
    } | null
    
  • "Latest" = most recent by jobs.created_at DESC LIMIT 1 for the item. A single additional prepared statement.

Frontend changes

Deletions

  • src/features/execute/ExecutePage.tsx
  • src/routes/execute.tsx
  • Nav link to /execute in src/routes/__root.tsx
  • plan_update SSE listener in src/features/pipeline/PipelinePage.tsx:70-72
  • Verify button, verifyUnverified(), unverifiedCount, and the /✓✓ glyph span in src/features/pipeline/DoneColumn.tsx
  • The verified field on PipelineJobItem in src/shared/lib/types.ts:161

DoneColumn simplification

Each card keeps its title link, ← Back to review hover button, and status <Badge> (done or error). The mark glyph and its title attribute go away. Column actions stay: Clear when items exist.

Pipeline column headers (batch controls)

ColumnShell already accepts an actions: ColumnAction[] array. Move existing batch controls off the /execute page into the headers:

  • Queued columnRun all (primary, when at least one pending) + Clear queue (when items exist)
  • Done columnClear (existing)
  • Processing column — no batch controls

Wire these to the existing endpoints: /api/execute/start, /api/execute/clear, /api/execute/clear-completed.

AudioDetailPage job section

New section rendered only when data.job is non-null. Placement: between the FFmpeg command textarea and the Approve/Skip button row.

Contents:

  • Header row: status <Badge>, job-type badge (Audio Remux/Audio Transcode), started/completed timestamps, exit code badge (only when non-zero)
  • Cmd toggle button — reveals the job's recorded command (the jobs.command column)
  • Log toggle button — reveals jobs.output; auto-expanded when status === "error"
  • Action buttons based on job.status:
    • pending▶ Run (calls POST /api/execute/job/:id/run), ✕ Cancel (calls POST /api/execute/job/:id/cancel)
    • running✕ Stop (calls POST /api/execute/stop)
    • done / error → no actions

Live updates on details page

The details page gets its own scoped EventSource subscription to /api/execute/events, filtering for events where id === data.job?.id:

  • job_update → merge into local state, re-fetch details on terminal (done/error) to pick up the refreshed jobs row
  • job_progress → update a progress bar for the active job
  • Close on unmount

Data flow after the change

  1. User approves plan in Review → plan.status = approved
  2. User clicks Run all in Queued column header → queued jobs start
  3. Processing column shows the running job with live progress (unchanged)
  4. Job finishes → jobs.status = done, review_plans.status = done. No Jellyfin refresh, no verified flip.
  5. Card lands in Done column with a done badge. No ✓/✓✓ glyph.
  6. Next scan (automatic or manual) re-analyzes the file. If still is_noop = 1, plan stays done; if not, plan returns to pending and the card reappears in Review.

Testing

  • Delete server/services/__tests__/webhook.test.ts:186-240 — the "webhook_verified flag" describe block. The remaining webhook tests (status transitions, upserts) stay.
  • No new tests required: this spec removes features, does not add behavior.

Guided Gates

  • GG-1: After deploy, confirm the Done column shows cards with only a done/error badge — no ✓ or ✓✓ glyph.
  • GG-2: Click an item in Done → details page shows the job section below the FFmpeg command box, with Cmd and Log toggles.
  • GG-3: Click an item in Queued → details page shows a pending job with working ▶ Run and ✕ Cancel buttons; running the job updates the badge live.
  • GG-4: /execute in the browser returns a 404 (route is gone).
  • GG-5: Run all and Clear queue buttons appear in the Queued column header; Clear stays in the Done column header.
  • GG-6: PRAGMA table_info(review_plans); in the SQLite DB no longer lists a verified column.