Files
UHD_Media_Tool/packages/mapping/src/evidence.ts
T
rootandClaude Opus 5.5 42ecc93fa5 feat(mapping): centralize domain <-> contracts mappings (B5)
New @umt/mapping (depends on domain + contracts only): download status + pause reason,
evidence level / media kind, identity resolution status, slot status / spec columns /
evaluation, ParsedRelease <-> source_release.parsed, SiteRelease <-> source_release,
PathBinding, OrganizePlan -> organization_record / file results / organize.plan output.
Tables are Record<union, ...> so adding a value on either side fails typecheck or tests.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 19:20:30 +08:00

74 lines
2.4 KiB
TypeScript

import type { EvidenceLevel as ContractEvidenceLevel, ExternalEntityType, MediaKind } from "@umt/contracts";
import type { Confidence, EvidenceLevel as DomainMatchLevel } from "@umt/domain";
// 证据等级:domain 的 EvidenceLevel 实为"匹配等级"(含 rejected),这里以 DomainMatchLevel 称呼;
// contracts 的 EvidenceLevel 是落库/展示用的证据等级(含 manual、needs_review)。
export type { DomainMatchLevel };
const LEVEL_TO_CONTRACT: Record<DomainMatchLevel, ContractEvidenceLevel | null> = {
rule_confirmed: "rule_confirmed",
multi_evidence: "multi_evidence",
needs_confirm: "needs_review",
// 被否决的候选不形成证据记录
rejected: null,
};
const LEVEL_TO_DOMAIN: Record<ContractEvidenceLevel, Confidence> = {
// 人工确认按最强规则证据参与排序
manual: "rule_confirmed",
rule_confirmed: "rule_confirmed",
multi_evidence: "multi_evidence",
needs_review: "needs_confirm",
};
export const DOMAIN_MATCH_LEVELS = Object.keys(LEVEL_TO_CONTRACT) as DomainMatchLevel[];
/** domain 匹配等级 / 解析置信度 → contracts 证据等级;rejected 返回 null */
export function toContractEvidenceLevel(level: DomainMatchLevel): ContractEvidenceLevel | null {
return LEVEL_TO_CONTRACT[level];
}
export function toDomainConfidence(level: ContractEvidenceLevel): Confidence {
return LEVEL_TO_DOMAIN[level];
}
// ── 媒体类型:domain 只分 movie / tv ──
export type DomainMediaType = "movie" | "tv";
const MEDIA_TO_DOMAIN: Record<MediaKind, DomainMediaType | null> = {
movie: "movie",
series: "tv",
// 综艺按剧集规则(季/期)处理
variety: "tv",
collection: null,
other: null,
};
export function toDomainMediaType(kind: MediaKind): DomainMediaType | null {
return MEDIA_TO_DOMAIN[kind];
}
/** domain → contracts 媒体类型;tv 默认落为 series,综艺由调用方按来源分类显式指定 */
export function toContractMediaKind(t: DomainMediaType, opts: { variety?: boolean } = {}): MediaKind {
return t === "movie" ? "movie" : opts.variety ? "variety" : "series";
}
const ENTITY_TYPE_TO_DOMAIN: Record<ExternalEntityType, DomainMediaType | null> = {
movie: "movie",
tv: "tv",
season: null,
episode: null,
collection: null,
person: null,
};
export function toDomainEntityType(t: ExternalEntityType): DomainMediaType | null {
return ENTITY_TYPE_TO_DOMAIN[t];
}
export function toContractEntityType(t: DomainMediaType): ExternalEntityType {
return t;
}