- P1: Fix cancel race in pipeline, fix VideoToolbox quality mapping - P2: SSRF protection, batch cancel N+1, archived filter fixes, metadata persistence, reverse proxy hardening, reprobe logging - TD: Remove AlchemistEvent legacy bridge, fix silent .ok() on DB writes, optimize sort-by-size query, split db.rs (3400 LOC) into 8 focused submodules under src/db/ - UX: Add queue position display for queued jobs - Docs: Update API docs, engine modes, library doctor, config ref - Plans: Add plans.md for remaining open items (UX-2/3, FG-4, RG-2) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6.5 KiB
Open Item Plans
[UX-2] Single File Enqueue
Goal
POST /api/jobs/enqueue + "Add file" button in JobsToolbar.
Backend
New handler in src/server/jobs.rs:
#[derive(Deserialize)]
struct EnqueueFilePayload {
input_path: String,
source_root: Option<String>,
}
async fn enqueue_file_handler(State(state), Json(payload)) -> impl IntoResponse
Logic:
- Validate
input_pathexists on disk, is a file - Read
mtimefrom filesystem metadata - Build
DiscoveredMedia { path, mtime, source_root } - Call
enqueue_discovered_with_db(&db, discovered)— reuses all existing skip checks, output path computation, file settings - If
Ok(true)→ fetch job viadb.get_job_by_input_path(), return it - If
Ok(false)→ 409 "already tracked / output exists" - If
Err→ 400 with error
Route: Add .route("/api/jobs/enqueue", post(enqueue_file_handler)) in src/server/mod.rs
Frontend
web/src/components/jobs/JobsToolbar.tsx:
- Add "Add File" button next to refresh
- Opens small modal/dialog with text input for path
- POST to
/api/jobs/enqueue, toast result - SSE handles job appearing in table automatically
Files to modify
src/server/jobs.rs— new handler + payload structsrc/server/mod.rs— route registrationweb/src/components/jobs/JobsToolbar.tsx— button + dialogweb/src/components/jobs/— optional: newEnqueueDialog.tsxcomponent
Verification
cargo check && cargo test && cargo clippy- Manual: POST valid path → job appears queued
- POST nonexistent path → 400
- POST already-tracked path → 409
- Frontend: click Add File, enter path, see job in table
[UX-3] Workers-Blocked Reason
Goal
Surface why queued jobs aren't being processed. Extend /api/engine/status → show reason in JobDetailModal.
Backend
Extend engine_status_handler response (or create new endpoint) to include blocking state:
struct EngineStatusResponse {
// existing fields...
blocked_reason: Option<String>, // "paused", "scheduled", "draining", "boot_analysis", "slots_full", null
schedule_resume: Option<String>, // next window open time if scheduler_paused
}
Derive from Agent state:
agent.is_manual_paused()→"paused"agent.is_scheduler_paused()→"scheduled"agent.is_draining()→"draining"agent.is_boot_analyzing()→"boot_analysis"agent.in_flight_jobs >= agent.concurrent_jobs_limit()→"slots_full"- else →
null(processing normally)
Frontend
web/src/components/jobs/JobDetailModal.tsx:
- Below queue position display, show blocked reason if present
- Fetch from engine status (already available via SSE
EngineStatusChangedevents, or poll/api/engine/status) - Color-coded: yellow for schedule/pause, blue for boot analysis, gray for slots full
Files to modify
src/server/jobs.rsor whereverengine_status_handlerlives — extend responseweb/src/components/jobs/JobDetailModal.tsx— display blocked reasonweb/src/components/jobs/useJobSSE.ts— optionally track engine status via SSE
Verification
- Pause engine → queued job detail shows "Engine paused"
- Set schedule window outside current time → shows "Outside schedule window"
- Fill all slots → shows "All worker slots occupied"
- Resume → reason disappears
[FG-4] Intelligence Page Actions
Goal
Add actionable buttons to LibraryIntelligence.tsx: delete duplicates, queue remux opportunities.
Duplicate Group Actions
"Keep Latest, Delete Rest" button per group:
- Each duplicate group card gets a "Clean Up" button
- Selects all jobs except the one with latest
updated_at - Calls
POST /api/jobs/batchwith{ action: "delete", ids: [...] } - Confirmation modal: "Archive N duplicate jobs?"
"Clean All Duplicates" bulk button:
- Top-level button in duplicates section header
- Same logic across all groups
- Shows total count in confirmation
Recommendation Actions
"Queue All Remux" button:
- Gathers IDs of all remux opportunity jobs
- Calls
POST /api/jobs/batchwith{ action: "restart", ids: [...] } - Jobs re-enter queue for remux processing
Per-recommendation "Queue" button:
- Individual restart for single recommendation items
Backend
No new endpoints needed — existing POST /api/jobs/batch handles all actions (cancel/delete/restart).
Frontend
web/src/components/LibraryIntelligence.tsx:
- Add "Clean Up" button to each duplicate group card
- Add "Clean All Duplicates" button to section header
- Add "Queue All" button to remux opportunities section
- Add confirmation modal component
- Add toast notifications for success/error
- Refresh data after action completes
Files to modify
web/src/components/LibraryIntelligence.tsx— buttons, modals, action handlers
Verification
- Click "Clean Up" on duplicate group → archives all but latest
- Click "Queue All Remux" → remux jobs reset to queued
- Confirm counts in modal match actual
- Data refreshes after action
[RG-2] AMD VAAPI/AMF Validation
Goal
Verify AMD hardware encoder paths produce correct FFmpeg commands on real AMD hardware.
Problem
src/media/ffmpeg/vaapi.rs and src/media/ffmpeg/amf.rs were implemented without real hardware validation. Flag mappings, device paths, and quality controls may be incorrect.
Validation checklist
VAAPI (Linux):
- Device path
/dev/dri/renderD128detection works hevc_vaapi/h264_vaapiencoder selection- CRF/quality mapping →
-rc_mode CQP -qp Nor-rc_mode ICQ -quality N - HDR passthrough flags (if applicable)
- Container compatibility (MKV/MP4)
AMF (Windows):
hevc_amf/h264_amfencoder selection- Quality mapping →
-quality quality -qp_i N -qp_p N - B-frame support detection
- HDR passthrough
Approach
- Write unit tests for
build_args()output — verify flag strings without hardware - Gate integration tests on
AMD_GPU_AVAILABLEenv var - Document known-good flag sets from AMD documentation
- Add
EncoderCapabilitiesdetection for AMF/VAAPI (similar to existing NVENC/QSV detection)
Files to modify
src/media/ffmpeg/vaapi.rs— flag corrections if neededsrc/media/ffmpeg/amf.rs— flag corrections if neededtests/— new integration test file gated on hardware
Verification
- Unit tests pass on CI (no hardware needed)
- Integration tests pass on AMD hardware (manual)
- Generated FFmpeg commands reviewed against AMD documentation