import type { ContentType as ContractContentType, Segment as ContractSegment, JsonObject } from "@umt/contracts"; import { type ContentType as DomainContentType, type Segment as DomainSegment, PARSER_VERSION, type ParsedRelease, } from "@umt/domain"; // 标题解析结果 ↔ source_release.parsed / parser_version 列;综艺内容类型与分段 ↔ content_unit 列。 /** ParsedRelease → source_release 的 parsed(jsonb)与 parser_version(text) */ export function toParsedColumns(p: ParsedRelease): { parsed: JsonObject; parserVersion: string } { return { parsed: JSON.parse(JSON.stringify(p)) as JsonObject, parserVersion: String(p.parserVersion) }; } const REQUIRED_ARRAYS = ["audio", "hdr", "variantTags", "explicitIds", "evidence"] as const; /** * source_release 列 → ParsedRelease。版本不是当前 PARSER_VERSION 或形状不对时返回 null, * 调用方应按原标题重新解析(规则变化后旧结果作废)。 */ export function fromParsedColumns(cols: { parsed: JsonObject; parserVersion: string | null }): ParsedRelease | null { if (cols.parserVersion !== String(PARSER_VERSION)) return null; const p = cols.parsed; if (p.parserVersion !== PARSER_VERSION || typeof p.raw !== "string" || typeof p.isEncode !== "boolean") return null; if (typeof p.contentType !== "string" || typeof p.confidence !== "string") return null; if (REQUIRED_ARRAYS.some((k) => !Array.isArray(p[k]))) return null; return p as unknown as ParsedRelease; } const CONTENT_TYPE: Record = { unknown: "unknown", main: "main", extra: "extra", behind_the_scenes: "behind_the_scenes", performance_only: "performance_only", preview: "preview", reaction: "reaction", }; const CONTENT_TYPE_BACK: Record = { main: "main", extra: "extra", behind_the_scenes: "behind_the_scenes", performance_only: "performance_only", preview: "preview", reaction: "reaction", unknown: "unknown", }; export const DOMAIN_CONTENT_TYPES = Object.keys(CONTENT_TYPE) as DomainContentType[]; export const toContractContentType = (t: DomainContentType): ContractContentType => CONTENT_TYPE[t]; export const toDomainContentType = (t: ContractContentType): DomainContentType => CONTENT_TYPE_BACK[t]; const SEGMENT: Record = { full: "full", upper: "upper", middle: "middle", lower: "lower", }; const SEGMENT_BACK: Record = { full: "full", upper: "upper", middle: "middle", lower: "lower", // domain 用"字段缺失"表示未知 unknown: undefined, }; export const DOMAIN_SEGMENTS = Object.keys(SEGMENT) as DomainSegment[]; /** 解析结果没有分段信息(undefined)时落为 unknown */ export const toContractSegment = (s: DomainSegment | undefined): ContractSegment => (s ? SEGMENT[s] : "unknown"); export const toDomainSegment = (s: ContractSegment): DomainSegment | undefined => SEGMENT_BACK[s];