Files
tuliprox/backend/core
DarkBreakpoint 76acd7be03 fix(dvr): resolve recordings through one owner-independent layout
Playback could not find any recording. Two independent path computations
existed and disagreed:

  writer  RecordingTask::new  -> <root>[/<subdir>]/<filename>
  reader  resolve_for_open    -> <root>/users/<owner>/<filename>

resolve_recording_dir invented a users/<owner>/ or shared/ prefix that
nothing ever wrote, and relative_path stored only the bare filename while
the organised subdirectory lived in file_dir. Nothing covered the round
trip, so the mismatch survived.

recording_path.rs is now the only layout. It is pure, and deliberately
owner-independent: one physical file is shared by every user who requested
it, so keying its directory on an owner is wrong the moment a second user
attaches and would force the file to move when the first detaches.
resolve_recording_dir and its RecordingVisibility are deleted rather than
left as a second answer.

relative_path is now root-relative and carries the full layout, so the
writer's path and the reader's resolution are the same expression. Series
recordings gain the Season NN level they were documented to have but never
produced.

Component sanitisation is one function with a table test: separators,
control characters and the Windows-forbidden set collapse to _, leading and
trailing dots are stripped so a name cannot be hidden or silently aliased,
Windows device names fall back to a placeholder, and components are capped
at 255 bytes on a character boundary so a multi-byte title truncates to
valid UTF-8 rather than to a split character. A property test asserts that
no input the builder accepts can produce a path the containment check
rejects.

Collision suffixes now apply to the file component only, so reserving a
name no longer flattens the directory it belongs to.
2026-09-01 08:24:20 -05:00
..
2026-08-27 15:36:23 +02:00