Add recording inventory and upload recovery to the room dashboard
Goal Let operators inspect recordings on a remote local-streamer and complete interrupted processing, uploads and missed external notifications from the existing cloud dashboard, without SSH or log reconstruction. Scope change User replaced the one-off Flå callback replay script with a recording inventory/recovery dashboard. No script was written or callbacks sent. Motivating incident: six completed main/hdmi uploads on 2026-11-05 for meetings 6a354217-c81e-4090-a465-4de3fdea2106, 18d21e92-b189-487b-8e6f-c5c35889b834 and 6614cd4a-fc35-429c-8a2a-1bcd27f99a0e were not delivered to https://app.kaukus.no/api/cloud_router_callbacks because callback configuration was missing. Exact URLs/bookmarks remain uncollected; Loki credential command was unavailable. That is not a blocker to local feature development. Proposed operator flow Add a Recordings tab to the existing room detail page. Inventory recording artifacts, grouped by meeting/output, including raw sessions/segments, final MP4/bookmarks and upload rows whose local files are missing. Include current and legacy layouts, removed output IDs and unqueued/orphan files. This is a recording-storage inventory, not arbitrary host filesystem access. Show local sizes/counts, presence, progress, acknowledged bytes, attempts, last error, timestamps, active recording and upload-disabled/paused conditions. Offer separate, deliberate actions to process/queue an unfinished recording, retry a failed upload and resend a completed upload callback using configured room destinations. Preserve original upload URL, recording identity and inline bookmarks; notification recovery must not upload video again. State integrity and safety Keep local processing, remote upload completion, per-destination HTTP notification results and downstream ingestion confirmation separate. A 2xx callback response is not proof of transcoding/ingestion. Historical callback delivery is unknown, not failed or delivered. Missing/disabled destinations and unsubscribed uploaded events must be visible. Reuse existing callback SSRF protections, credential storage and subscriptions; never expose upload credentials in ordinary lists or logs. Scope reads/writes through existing room authorization and outbound NATS connection. Bound inventories and work, preserve incomplete/offline/old-agent states, prevent duplicate/concurrent processing and reject recovery against active recordings. No deletion, automatic bulk resend, arbitrary paths, new dependencies or production deployment in the proposed first version. Verified reuse and implementation considerations - cloud-dashboard/src/views/RoomDetailView.vue already hosts Setup/Log tabs; CallbacksPanel.vue configures per-room destinations. - local-streamer/src/upload/store.rs has durable pending/hashing/uploading/done/failed_permanent rows, offsets, attempts, last_error and ingested_at; no inventory/list/retry API. - local-streamer/src/commands.rs has post-stop/boot recovery/transcode helpers; paths.rs enumerates current and legacy layouts. Refactor shared recovery scheduling rather than spawning competing transcodes. - cloud-router/src/event_sub.rs builds uploaded callback metadata; callback.rs uses bounded best-effort sends without durable delivery history. Factor metadata construction for replay and add focused per-recording/per-destination delivery visibility rather than duplicating payloads or treating uploaded as delivered. - streaming.req.<room> currently supports Status only. Existing per-room JWTs do not permit arbitrary _INBOX publication; inventory transport must respect existing ACLs or explicitly plan credential migration, not assume NATS request/reply works. Acceptance Operators can enumerate recording artifacts/queue state without box access, find the motivating uploaded-but-not-notified recordings and resend only their notification after destination setup. Failed/unprocessed files can be recovered without duplication, data loss or active-stream interference. Unknown delivery/ingestion, disabled uploads, offline/older agents and partial scans are honest. Authorization, path/symlink boundaries, duplicate/concurrent recovery, restart/resume, metadata/bookmarks, callback failures and UI flows have focused regression coverage; Rust fmt/check/tests and dashboard tests/build pass, with isolated real-browser acceptance. No production callbacks/deployment without separate authorization. Current stage Implemented on feature/recording-inventory-recovery. With user authorization, committed as 94a472f (feature: Add recording inventory and upload recovery) and pushed to origin. No production callback, deployment or recording deletion performed. Recording inventory covers current/legacy/orphan files, removed outputs, queued missing files, progress/errors/ingestion and partial/offline states. Shared bounded processing queue handles boot/stop/manual work, defers automatic overflow, waits for idle and blocks active/symlink/nonregular targets. Failed uploads use exact-path lookup and retain tus offsets. Disabled uploading still permits read-only queue history and completed-upload callback replay. Router migration 29 records per-destination attempt results; retained destination edits preserve history and in-flight exclusion. Notification replay reuses stored upload identity/URLs/bookmarks and normal SSRF/credential/subscription controls; historical/interrupted delivery remains unknown and HTTP acceptance does not alter ingestion status. Verified: cargo fmt/check and whitespace checks; cargo check --workspace; 313 targeted Rust unit tests plus one doc test (cloud-router 141, local-streamer 115, streaming-protocol 57); both isolated real-NATS tests explicitly run and passed, including existing restricted room permissions without arbitrary reply inbox publication; 40 dashboard tests and production build. Targeted all-target Clippy exits successfully with pre-existing repository warnings; strict -D warnings remains blocked by those existing lints. Chrome verified core inventory/actions, cancellation, role visibility, failure/disabled states, corrected notification wording, desktop/mobile layout, and successful-snapshot-to-offline retention with controls disabled through manual refresh and automatic polling. Browser geometry was visually reviewed, not numerically measured. No representative live box, production media transfer or downstream ingestion acceptance was performed. Review limitations and cost decision: initial static review found overflow deferral, capped recovery lookup, retained-destination history and scoped-test expectation defects; all were fixed with passing regressions. Follow-up had no verified findings but was partial because formatting changed during it, not a clean approval. An unnecessary additional review was aborted after user objected to its expense. Do not run further expensive reviews without asking. Delivery: local implementation/validation complete. Deploy coordinated cloud-router/dashboard/local-streamer versions and apply migration 29 to make this available remotely; no credential widening is needed. Inventory limits and missing/orphan manual-investigation cases are documented. Production rollout and recovery of the six original Flå callbacks were not performed. Pull request #153: https://git.kaukus.no/Kaukus/streaming-engines/pulls/153 Title: feature: Add recording inventory and upload recovery. Head feature/recording-inventory-recovery; base main. Open and ready for review. Complete branch comparison contains only the current session's 44 files in commit 94a472f, based directly on current origin/main. Working tree clean and upstream established. Existing validation was reused and format/whitespace checks were confirmed; no further feature review was run.
Checklist
4 of 4 complete- Provide bounded, authorized recording inventory including unqueued files, legacy layouts, missing local files and honest offline/partial-scan states.
- Implement safe shared processing/upload recovery with active-recording protection, deduplication and verified resume behavior.
- Expose per-destination notification results and deliberate callback resend without reuploading or losing original metadata/bookmarks; keep ingestion separate.
- Build room Recordings tab and verify focused backend/protocol/UI regressions, Rust validation, dashboard tests/build and isolated Chrome recovery flows.
- Area
- Streaming
- Project
- streaming-engines
- Kind
- Feature
- Task ID
tsk_jmtpbp9y6k- Updated