fix(identity): 季范围资源只建第一季;刷新时退役空的临时季;v0.3.42
药屋少女的呢喃:一条「S01-S24 季度全24集」的资源按季范围建出 S04–S24 二十一个空季。 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
1 parent
1ade49fe8e
commit
12f8fc59c3
17 files changed
+136
-20
No files matched your search
@@ -235,6 +235,36 @@ describe.skipIf(!up)("DH-1 内容单元数据治理", () => {
|
||||
expect((await units()).filter((u) => label(u) === "S1E20")).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("季范围资源(把全 24 集写成 S01-S24)只建第一季、挂已有的季;刷新时退役空的临时季", async () => {
|
||||
const seasonsNow = async () =>
|
||||
(
|
||||
await h.db
|
||||
.selectFrom("content_unit")
|
||||
.select(["id", "season_number", "status"])
|
||||
.where("media_entity_id", "=", id)
|
||||
.where("kind", "=", "season")
|
||||
.where("status", "<>", "retired")
|
||||
.orderBy("season_number")
|
||||
.execute()
|
||||
).map((s) => s.season_number);
|
||||
const before = await seasonsNow();
|
||||
const parsed = { season: 1, seasonEnd: 24 } as ParsedRelease;
|
||||
const r = await h.db.transaction().execute((trx) => ensureUnits(trx, id, "series", parsed));
|
||||
expect(await seasonsNow()).toEqual(before);
|
||||
expect(r.unitIds.length).toBe(before.filter((n) => n !== null && n >= 1).length);
|
||||
|
||||
// 空的临时季:S7 没人引用 → 退役;S8 被资源引用 → 留着;S3 下面有集 → 留着
|
||||
const s7 = await unit("season", 7, null);
|
||||
const s8 = await unit("season", 8, null);
|
||||
await release("s8-pack", s8);
|
||||
await refreshMetadata(h.rt, id);
|
||||
const status = async (uid: string) =>
|
||||
(await h.db.selectFrom("content_unit").select("status").where("id", "=", uid).executeTakeFirstOrThrow()).status;
|
||||
expect(await status(s7)).toBe("retired");
|
||||
expect(await status(s8)).toBe("provisional");
|
||||
expect(await status(ids.s3!)).toBe("provisional");
|
||||
});
|
||||
|
||||
it("identity-cleanup --merge-duplicates:默认 dry-run 列清单不改库,--apply 只合并重复、不删孤立单元", async () => {
|
||||
const schema = (await sql<{ s: string }>`select current_schema() as s`.execute(h.db)).rows[0]!.s;
|
||||
const u = new URL(PG_URL);
|
||||
|
||||
@@ -305,10 +305,10 @@ describe.skipIf(!pg)("剧集组", () => {
|
||||
const u14 = await unit(unitE14);
|
||||
expect(u14).toMatchObject({ season_number: 1, episode_number: 14, status: "confirmed" });
|
||||
expect(u14.metadata).not.toHaveProperty("tmdbSeason");
|
||||
// 组里的第 2 季在默认结构里没有,切回后成了没有集、没被引用的空季:随刷新退役,不再挂着临时季
|
||||
expect(await seasonTotals()).toEqual([
|
||||
[0, null, "confirmed"],
|
||||
[1, 25, "confirmed"],
|
||||
[2, null, "provisional"],
|
||||
]);
|
||||
expect((await loadSeasonTable(h.db, entityId)).origins).toBeUndefined();
|
||||
expect((await release(abs13)).episode_resolution).toMatchObject({
|
||||
|
||||
Reference in new issue
Block a user