feat(db): archive lifecycle schema and queries for missing media
Add the storage behind the archive-instead-of-delete lifecycle: - media_items.missing_scan_count (INT, default 0) and archived_at (TIMESTAMPTZ, partial index), both as idempotent ADD COLUMN IF NOT EXISTS backfills for existing installs. - MarkMediaItemMissing / ArchiveMediaItem / ClearMediaItemArchive plus PurgeExpiredArchivedMediaItems (retention cutoff) and PurgeAllArchivedMediaItems (manual bulk), with CountArchivedMediaItems for the admin UI. - Archived items are hidden from every user-facing listing: ListMediaItems, ListMediaItemsByLibrary, ListMediaItemsSorted, SearchMediaItems, SearchMediaItemsUnified, the next_books CTE, the library media counts, and the search autocomplete value lists. Detail lookups by id/path/sha are intentionally unfiltered, and a dedicated ListMediaItemsByLibraryIncludingArchived feeds the scanner so the lifecycle pass can see and restore archived rows.
This commit is contained in:
@@ -213,6 +213,13 @@ CREATE TABLE IF NOT EXISTS media_items (
|
||||
-- reset-to-scanned-defaults action clears them.
|
||||
metadata_overrides TEXT[] NOT NULL DEFAULT '{}',
|
||||
|
||||
-- Archive lifecycle: a file missing from disk for two consecutive scans
|
||||
-- gets archived_at set (hidden from all browsing, reading history kept).
|
||||
-- If the file returns, the row is un-archived. Archived rows are purged
|
||||
-- after ARCHIVE_RETENTION_DAYS (0 = manual purge only).
|
||||
missing_scan_count INT NOT NULL DEFAULT 0,
|
||||
archived_at TIMESTAMPTZ,
|
||||
|
||||
-- Chapter metadata for reader navigation and progress tracking
|
||||
-- Caches detected chapter structure to avoid re-parsing files
|
||||
-- Populated by ReaderService.DetectChapters() on first read
|
||||
@@ -243,6 +250,11 @@ ALTER TABLE media_items ADD COLUMN IF NOT EXISTS contributors_search TEXT[];
|
||||
-- definition above for fresh databases)
|
||||
ALTER TABLE media_items ADD COLUMN IF NOT EXISTS metadata_overrides TEXT[] NOT NULL DEFAULT '{}';
|
||||
|
||||
-- Archive lifecycle (idempotent backfill for existing installs)
|
||||
ALTER TABLE media_items ADD COLUMN IF NOT EXISTS missing_scan_count INT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE media_items ADD COLUMN IF NOT EXISTS archived_at TIMESTAMPTZ;
|
||||
CREATE INDEX IF NOT EXISTS idx_media_items_archived ON media_items (archived_at) WHERE archived_at IS NOT NULL;
|
||||
|
||||
-- Create GIN indexes for fast search field searches
|
||||
CREATE INDEX IF NOT EXISTS idx_media_items_tags_search ON media_items USING GIN (tags_search);
|
||||
CREATE INDEX IF NOT EXISTS idx_media_items_contributors_search ON media_items USING GIN (contributors_search);
|
||||
|
||||
Reference in New Issue
Block a user