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]>
This commit is contained in:
1 parent
da8e53bbca
commit
42ecc93fa5
16 files changed
+1282
-1
No files matched your search
@@ -0,0 +1,44 @@
|
||||
import type { PathBinding as ContractPathBinding, PathBindingCreate } from "@umt/contracts";
|
||||
import type { PathBinding as DomainPathBinding, NewBinding } from "@umt/domain";
|
||||
|
||||
// 路径绑定:domain {entityId, scope, season, templateVersion:number, active}
|
||||
// ↔ contracts / path_binding {mediaEntityId, bindingKind, seasonNumber, templateVersion:string|null, status}
|
||||
|
||||
export type { DomainPathBinding };
|
||||
|
||||
/** 模板版本:库里是文本(可能是 "3" 或历史导入的任意串),domain 用整数;无法解析按 0(未知)处理 */
|
||||
export function parseTemplateVersion(v: string | null): number {
|
||||
return v !== null && /^\d+$/.test(v) ? Number(v) : 0;
|
||||
}
|
||||
|
||||
/** path_binding 行 → domain;只有 status=active 的绑定参与目标目录决策 */
|
||||
export function toDomainPathBinding(b: ContractPathBinding): DomainPathBinding {
|
||||
return {
|
||||
id: b.id,
|
||||
entityId: b.mediaEntityId,
|
||||
scope: b.bindingKind,
|
||||
...(b.seasonNumber !== null ? { season: b.seasonNumber } : {}),
|
||||
libraryRootId: b.libraryRootId,
|
||||
relativePath: b.relativePath,
|
||||
templateVersion: parseTemplateVersion(b.templateVersion),
|
||||
active: b.status === "active",
|
||||
};
|
||||
}
|
||||
|
||||
/** domain 决策里的新绑定 → path_binding 新建输入(status=active) */
|
||||
export function toPathBindingCreate(
|
||||
nb: NewBinding,
|
||||
target: { mediaEntityId: string; contentUnitId?: string | null; note?: string | null },
|
||||
): PathBindingCreate {
|
||||
return {
|
||||
mediaEntityId: target.mediaEntityId,
|
||||
...(target.contentUnitId !== undefined ? { contentUnitId: target.contentUnitId } : {}),
|
||||
bindingKind: nb.scope,
|
||||
...(nb.scope === "season" ? { seasonNumber: nb.season ?? null } : {}),
|
||||
libraryRootId: nb.libraryRootId,
|
||||
relativePath: nb.relativePath,
|
||||
templateVersion: String(nb.templateVersion),
|
||||
status: "active",
|
||||
...(target.note !== undefined ? { note: target.note } : {}),
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user