POST /assets/batch-trim creates jobs table row with wrong job_type — no matching pg_enum value
Fix Plan — #70 batch-trim creates jobs row with wrong job_type
Root cause: batch-trim creates a jobs row with type 'trim' and status 'queued'. The in-database jobs row for trim jobs has…
POST /assets/:id/mark-empty requires status=live — but capture shutdown may pass wrong assetId
Fix Plan — #66 mark-empty requires status=live but capture may crash first
Root cause: Two scenarios: (1) capture container crashes before calling mark-empty, asset stays status=live…
GET /upload route missing — upload.js has no list endpoint, frontend may 404
Fix Plan — #68 GET /upload route missing
Root cause: upload.js defines POST routes but no GET / route. Frontend calling GET /api/v1/upload gets 404.
Fix — add list endpoint:
…POST /assets with status=live asset already existing: captures registered as processing overwrite the live asset
Fix Plan — #63 POST /assets race: processing overwrites live asset
Root cause: Two simultaneous captures for same projectId + clipName can both find the same live row and both UPDATE it.…
POST /assets body param sourceType, needsProxy documented but unused
Fix Plan — #64 sourceType, needsProxy params documented but unused
Root cause: POST /assets destructures only projectId, binId, clipName, hiresKey, proxyKey, duration, capturedAt. Any…
Fix Plan — #61 S3 proxy client export breaks on rebuild
Root cause: s3/client.js exports s3Client as a Proxy (correct) BUT S3_BUCKET is a plain let export. Code that does `import {…
Fix Plan — #60 Asset copy duplicates S3 refs
Root cause: POST /:id/copy in assets.js copies proxy_s3_key and thumbnail_s3_key from source to new asset row, but does NOT copy actual S3…
Fix Plan — #56 NLE Editor React SPA Polish Phases 1-3
Status: Implementation complete.
Phase 1: Core NLE editor React SPA rewrite — sets up timeline component, clip manipulation,…
Fix Plan — #55 Recorder polling spams 401s on unauthenticated tabs
Root cause: Frontend polls GET /api/v1/recorders every ~10s even when tab is unauthenticated. 47 log entries of 401s…
Fix Plan — #126 Icon-only buttons missing aria-label
Root cause: Icon-only <button className="icon-btn"> elements have no aria-label or title. Screen readers announce "button" with…
Fix Plan — #124 Typo setPgMclips should be setPgmClips
Root cause: screens-editor.jsx:621 — reader is pgmClips, setter is setPgMclips. Capitalization mismatch.
**Fix —…
Fix Plan — #125 Hardcoded Premiere panel version 1.0.1 in download links
Root cause: screens-editor.jsx:400-405 hardcodes /downloads/dragonflight-premiere-panel-1.0.1.zxp. v1.1.0 ZXP…
Fix Plan — #123 Stray console.error/warn in production JSX
Root cause: 13 console.error/console.warn calls left in production JSX. Leak internal details to browser console.
**Locatio…
Fix Plan — #111 setTimeout/setInterval leaks across screens
Root cause: Multiple screens fire setTimeout/setInterval outside useEffect or without cleanup. On unmount → setState…
Fix Plan — #113 Sidebar shows hardcoded "3" badge on Jobs
Root cause: shell.jsx:19 — badge text is literal "3" sentinel value. Never changes.
Fix — poll for real counts:
Fix Plan — #115 Hardcoded /api/v1 paths in upload module
Root cause: screens-ingest.jsx:36,56 — _xhrPost uses literal /api/v1/upload/simple and /api/v1/upload/part. If API…
Fix Plan — #122 Production ships React dev builds + in-browser Babel
Root cause: index.html loads react.development.js, react-dom.development.js, @babel/standalone. JSX compiled…
Fix Plan — #112 Hard page reload on project delete wipes state
Root cause: screens-library.jsx:590 — delete handler calls window.location.reload() after successful DELETE. Wipes…
Fix Plan — #110 index.html missing bmd-card.js
Status: Fixed in commit 1535bba. Documenting for completeness.
Root cause: screens-admin.jsx referenced window.BMDCards but…
Fix Plan — #119 Assets list endpoint has no LIMIT cap
Root cause: assets.js:92-93 passes req.query.limit directly into SQL LIMIT without max cap. ?limit=999999999 → PG…