fix(identity): 合并事项按年份与类型分组,组内不相容的资源不随组锁定;复查耗尽 / 相关无结果的资源开待处理(H3、M4、M5)

分组键 = 归一化标题 + 年份 + 剧集线索(解析有才带);选择后组内年份 / 类型与所选作品不相容的
资源不指定、留在事项里(事项保持打开,代表资源换成留下的那条)。
TMDB 查询失败复查耗尽的资源不论是否命中本地作品都开 identity_unresolved;命中本地作品却无结果的
资源带站点 ID 也开(升级链推迟中仍不开),不再静默留池。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-03 23:31:12 +08:00
1 parent dca3012227
commit fa18015354
5 files changed
+88 -19

No files matched your search

@@ -147,7 +147,7 @@ describe.skipIf(!up)("resolveObservation / 身份与元数据", () => {
expect(pool.next_review_at!.getTime()).toBeGreaterThan(Date.now());
const d = await h.db.selectFrom("decision").selectAll().where("id", "=", res.decisionId!).executeTakeFirstOrThrow();
expect(d).toMatchObject({ kind: "identity_ambiguous", status: "open", subject_id: r.id, severity: "warning" });
expect(d.dedupe_key).toBe(`identity-group:${siteId}:twins`);
expect(d.dedupe_key).toBe(`identity-group:${siteId}:twins:1988`);
expect((d.options as { key: string }[]).map((o) => o.key)).toEqual([
"c0",
"c1",
@@ -178,7 +178,7 @@ describe.skipIf(!up)("resolveObservation / 身份与元数据", () => {
await h.db
.selectFrom("decision")
.select("id")
.where("dedupe_key", "=", `identity-group:${siteId}:twins`)
.where("dedupe_key", "=", `identity-group:${siteId}:twins:1988`)
.execute(),
).toHaveLength(1);
});