- library: CRUD with root-path resolution (absolute, symlink-free, must be readable). A library name is unique; the root is validated at creation. - registry: media types declare their extensions; the core never imports a module. RegisterType is the extension point. - scanner: walks a root, reconciles media_items/media_files in one transaction, skips unchanged files by size+mtime, and marks vanished files missing rather than deleting them (progress is the one thing here that cannot be regenerated). A single unreadable file never fails a scan. - migration 0002: `missing` flags on items and files, plus indexes. - endpoints: media-types, library list/get/create/delete, per-library items, and scan. Library reads go through the same grant chokepoint as everything else; an unauthorised library 404s rather than 403s so its existence is not leaked.
13 lines
680 B
SQL
13 lines
680 B
SQL
-- 0002_missing.sql — track files that disappear from disk.
|
|
--
|
|
-- A rescan must not delete an item whose file is temporarily unavailable
|
|
-- (unmounted drive, NFS hiccup, user mid-reorganise). Deleting cascades into
|
|
-- progress, which is the one thing in this schema that cannot be regenerated.
|
|
-- Mark instead, and filter on read. A later pass can prune rows that have been
|
|
-- missing for a long time.
|
|
|
|
ALTER TABLE media_items ADD COLUMN missing INTEGER NOT NULL DEFAULT 0;
|
|
ALTER TABLE media_files ADD COLUMN missing INTEGER NOT NULL DEFAULT 0;
|
|
|
|
CREATE INDEX idx_items_library_missing ON media_items(library_id, missing);
|
|
CREATE INDEX idx_files_missing ON media_files(missing);
|