feat(identity): content unit data hygiene — specials, provisional promotion, duplicate merge (DH-1)
- metadata.includeSpecials (default true): full refresh and the language backfill fetch TMDB season 0 (specials) when present, like MP; season 0 stays out of the episode-total ledger - refreshMetadata promotes provisional season/episode units that match the TMDB season/episode layout to confirmed (source=tmdb), keeping ids and all references; non-matching units stay provisional - content_unit.source (migration 0053): release / file / tmdb / user - duplicate units (same entity/kind/season/episode/content type/segment) are merged as a refresh step and via `scripts/identity-cleanup.ts --merge-duplicates` (dry-run by default); keeper = most referenced, then confirmed, then earliest; references auto-discovered via FKs and repointed - ensureUnits takes a per-unit advisory xact lock to stop concurrent lazy creation from producing duplicates - runbooks updated; user DB read-only dry-run: 征途 S01E09/E10 4 units each -> 1 each (6 removed), not applied Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
2847512501
commit
044e718ec6
21 files changed
+734
-111
No files matched your search
@@ -296,8 +296,9 @@ describe.skipIf(!hasPg)("E7 常规剧集纵切", () => {
|
||||
.where("season_number", "=", 1)
|
||||
.orderBy("episode_number")
|
||||
.execute();
|
||||
// DH-1:元数据刷新拉了 S1 季详情,对上 TMDB 的 E01 转正式;E02 不在 mock TMDB 的 S1 里,保持临时
|
||||
expect(eps).toEqual([
|
||||
{ episode_number: 1, status: "provisional" },
|
||||
{ episode_number: 1, status: "confirmed" },
|
||||
{ episode_number: 2, status: "provisional" },
|
||||
]);
|
||||
// 第三集没出现、总集数未知:Slot 不满足,订阅继续追踪
|
||||
|
||||
Reference in new issue
Block a user