Repository navigation
Add whole-title blocks and recoverable streamed-file cleanup - #16
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6ce28bc1c6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (aliases.Count == 0 || !aliases.All(x => TitleBlockPolicy.Matches(identity, x) && ImportInventory.CompatibleIdentity(aliases[0], x))) | ||
| { outcomes.Add(new { Identity = identity, Status = "identity_requires_review" }); continue; } | ||
| if (!await db.IsBlockedAsync(imdb, null, null)) | ||
| await db.UpsertBlockedItemAsync(imdb, null, null, coverage.Title, |
There was a problem hiding this comment.
Persist every validated alias in the title block
When a validated catalogue row exposes the requested IMDb ID only through UniqueIdsJson while retaining a provider-native AioId, this stores only the IMDb ID in blocked_items. ImportReconciliationService.IsAuthorizedAsync later checks only each row's AioId and TmdbId, so Marvin can republish the archived title even though this endpoint returned blocked; persist the validated catalogue identifiers or make the publication guard check all provider IDs.
AGENTS.md reference: AGENTS.md:L13-L14
Useful? React with 👍 / 👎.
| WHERE NOT EXISTS (SELECT 1 FROM blocked_items WHERE unblocked_at IS NULL | ||
| AND ((@aio_id IS NOT NULL AND lower(aio_id)=lower(@aio_id)) | ||
| OR (@tmdb_id IS NOT NULL AND lower(tmdb_id)=lower(@tmdb_id)) | ||
| OR (@anilist_id IS NOT NULL AND lower(anilist_id)=lower(@anilist_id))))"; |
There was a problem hiding this comment.
Merge newly supplied identifiers into active blocks
When an already-blocked item is upserted after another provider ID is learned—for example, the active row matches aio_id but has no tmdb_id—this predicate suppresses the write instead of enriching the active block. An item later presented only under that TMDB identity will not match IsBlockedAsync; update missing identifiers on the existing active row or retain an equivalent matching row.
AGENTS.md reference: AGENTS.md:L13-L14
Useful? React with 👍 / 👎.
| MediaType = identity.StartsWith("series:", StringComparison.Ordinal) ? "series" : "movie" }); | ||
| coverage = new ImportCoverage { Identity = identity, Title = aliases.FirstOrDefault()?.Title ?? imdb }; | ||
| } | ||
| if (aliases.Count == 0 || !aliases.All(x => TitleBlockPolicy.Matches(identity, x) && ImportInventory.CompatibleIdentity(aliases[0], x))) |
There was a problem hiding this comment.
Compare all aliases before permitting cleanup
When aliases[0] contains only the shared IMDb ID and two later aliases contain conflicting TMDB IDs, both calls to CompatibleIdentity(aliases[0], x) return true because that predicate checks only providers present on its left operand. The request is therefore considered safe and may archive streams despite contradictory provider identities; perform a pairwise or accumulated-provider conflict check here and in the live recheck.
Useful? React with 👍 / 👎.
Marvin currently exposes retained failures but has no safe whole-title action for large unwanted series. The legacy removal endpoint also clears saved selections. This adds administrator-only title blocks for up to 25 confirmed IMDb identities, including future titles with no catalogue row, and an optional recoverable archive of verified managed STRMs.
Cleanup refuses unknown-size, changed, outside-root, symlinked, owned/retired and disputed files, and waits for idle playback. Native block checks stop later/in-flight publication. Coverage, retries, acquisition/watch/save state and the attempt ledger are preserved. Repeated concurrent blocks create one active record; native unblocking retains history. The candidate is versioned 0.42.13 and is not deployed to production.
Validation: repository hygiene and pinned Emby 4.10.0.40 ABI publish; 240/240 tests. A separate synthetic native Emby verified initialization, admin capability, anonymous refusal, future/idempotent/unprocessed-title blocking, exact archive recovery, unknown/changed/owned preservation, conflicting identity refusal, and unchanged coverage/backoff/attempt rows. The QA container was removed; production and frozen beta were untouched. The Vault UI/collector are maintained separately; their controls check the installed endpoint before enabling writes. No playback claim.