Files
tuliprox/backend/app
DarkBreakpoint 64c7b2333a feat(dvr)!: split persistence into materializations and library entries
First step of the shared-recording model. A recording is now stored as two
records: a PersistedMaterialization, which is the file on disk and the work
that produces it, and a PersistedLibraryEntry, which is one principal's link
to it. The materialization carries no owner and no visibility, because a
file that several users have asked for cannot belong to any one of them.

The mapping is still one entry per file, so no behaviour changes yet. What
changes is where the truth lives: reference_count is now a stored field with
one owner, and read_records() refuses any state where it disagrees with the
links pointing at the file, or where a link names a file that is not there.
A file deleted while still reachable, or kept forever after its last
reference went away, is not something a later pass can work out by guessing.

The DVR still works in whole tasks; split() and join() are the repository's
job precisely so the count has a single place to be maintained. join() is
lossless, and the link is authoritative for owner, visibility and quota
while the file is authoritative for everything physical.

Entry ids and materialization ids are separate namespaces from the start
(mat-<uuid>), so they cannot be used interchangeably in the interval before
one file legitimately serves several entries.

The schema name and database file change to recording_library, because the
previous shape stored the owner inside the task and cannot be expressed as a
one-to-one value migration into two records. The queue does not migrate — as
already documented — so the old database and history are left untouched
beside the new pair rather than failing the open.

The startup tests now discover the repository's artefacts instead of naming
them; hardcoding the filenames would have silently stopped testing the
fail-closed path the moment they changed, which is exactly what happened
here.
2026-09-01 09:39:00 -05:00
..
2026-08-27 15:36:23 +02:00
2026-08-27 15:36:23 +02:00
2026-08-27 15:36:23 +02:00