refactor(core): migrate to Bun and converge acquisition policies and Agent boundaries
This commit is contained in:
1 parent
3f1c6d02f6
commit
27c0f27434
268 files changed
+7468
-7852
No files matched your search
@@ -1,6 +1,6 @@
|
||||
# @umt/mapping
|
||||
|
||||
domain ↔ contracts 的集中映射(W1 审查 B5)。只依赖 `@umt/domain` 与 `@umt/contracts`,不依赖 db / adapters。server 各模块需要在两套取值之间转换时一律走这里,不要在模块里各写一份。
|
||||
domain ↔ contracts 的语义映射。只依赖 `@umt/domain` 与 `@umt/contracts`,不依赖 db / adapters。server 各模块需要在两套取值之间转换时一律走这里,不要在模块里各写一份。
|
||||
|
||||
db 行(snake_case)↔ contracts(camelCase)的转换不在本包;adapters 的 `SiteRelease` 以结构类型 `SiteReleaseLike` 接入(兼容性由 `apps/server/test/mapping-compat.test.ts` 在类型层保证)。
|
||||
|
||||
@@ -10,12 +10,14 @@ db 行(snake_case)↔ contracts(camelCase)的转换不在本包;adapters 的 `Si
|
||||
| `evidence.ts` | `toContractEvidenceLevel` / `toDomainConfidence` / `toDomainMediaType` / `toContractMediaKind` / `toDomainEntityType` / `toContractEntityType` | `needs_confirm ↔ needs_review`,`manual → rule_confirmed`,`rejected → null`;`tv ↔ series/variety` |
|
||||
| `identity.ts` | `toContractResolveStatus` / `toReleaseResolutionStatus` / `rankedToIdentityCreate` / `localIdentityCandidate` | `auto/ambiguous/no_match → resolved|proposed/ambiguous/unidentifiable → source_release.resolution_status`;排名候选 → `ExternalIdentityCreate`;本地作品 → 本地优先候选 |
|
||||
| `slot.ts` | `toContractSlotStatus` / `toDomainSlotStatus` / `slotSpecFromRow` / `slotSpecToColumns` / `toContractSlotEvaluation` | Slot 状态;规则 JSON 列 ↔ `SlotSpec`;评估结果 → `{ decision, acceptable, rejected[] }` |
|
||||
| `release.ts` | `toParsedColumns` / `fromParsedColumns` / `toContractContentType` / `toDomainContentType` / `toContractSegment` / `toDomainSegment` | `ParsedRelease ↔ source_release.parsed + parser_version`(版本不符返回 null,重解析) |
|
||||
| `release.ts` | `toParsedColumns` / `fromParsedColumns` / `toContractSegment` / `toDomainSegment` | `ParsedRelease ↔ source_release.parsed + parser_version`(版本不符返回 null,重解析) |
|
||||
| `site-release.ts` | `siteReleaseToSourceRelease` / `sourceReleaseToSiteRelease` / `SiteReleaseLike` | 站点资源 ↔ `SourceReleaseCreate` / `SourceRelease`;downloadUrl 不入库 |
|
||||
| `path-binding.ts` | `toDomainPathBinding` / `toPathBindingCreate` / `parseTemplateVersion` | `entityId/scope/season/templateVersion:number/active ↔ mediaEntityId/bindingKind/seasonNumber/templateVersion:string/status` |
|
||||
| `organize.ts` | `organizePlanToRecord` / `organizePlanToFileResults` / `organizePlanToCapabilityOutput` / `organizationStatusFromFiles` / `toOrganizationAction` / `toOrganizeOperation` / `toFileRole` | `OrganizePlan →` organization_record / organization_file_result 草稿 / organize.plan 输出 |
|
||||
|
||||
## 规则
|
||||
|
||||
- 同一语义的类型直接共用,不维护同值枚举的双向转换表。只在取值或含义存在实际差异时添加映射。
|
||||
|
||||
- 映射表一律写成 `Record<一侧的联合类型, …>`:domain 增删取值时 typecheck 失败;contracts 侧在 `test/enums.test.ts` 按 `z.enum(...).options` 逐个断言,新增取值时测试失败。
|
||||
- 新增映射先写测试(往返、schema 合法)。输出给 contracts 的对象都用对应 zod schema 在测试里 `safeParse` 一遍。
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"name": "@umt/mapping",
|
||||
"version": "0.3.44",
|
||||
"exports": { ".": "./src/index.ts" },
|
||||
"tasks": {
|
||||
"test": "deno run -A npm:vitest run",
|
||||
"typecheck": "deno run -A npm:typescript/tsc --noEmit -p tsconfig.json"
|
||||
}
|
||||
}
|
||||
@@ -4,5 +4,14 @@
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"version": "0.3.44",
|
||||
"scripts": {
|
||||
"test": "bun x --bun vitest run",
|
||||
"typecheck": "bun x --bun tsc --noEmit -p tsconfig.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@umt/contracts": "workspace:*",
|
||||
"@umt/domain": "workspace:*"
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,5 @@
|
||||
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";
|
||||
import type { Segment as ContractSegment, JsonObject } from "@umt/contracts";
|
||||
import { type Segment as DomainSegment, PARSER_VERSION, type ParsedRelease } from "@umt/domain";
|
||||
|
||||
// 标题解析结果 ↔ source_release.parsed / parser_version 列;综艺内容类型与分段 ↔ content_unit 列。
|
||||
|
||||
@@ -28,29 +23,6 @@ export function fromParsedColumns(cols: { parsed: JsonObject; parserVersion: str
|
||||
return p as unknown as ParsedRelease;
|
||||
}
|
||||
|
||||
const CONTENT_TYPE: Record<DomainContentType, ContractContentType> = {
|
||||
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<ContractContentType, DomainContentType> = {
|
||||
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<DomainSegment, ContractSegment> = {
|
||||
full: "full",
|
||||
upper: "upper",
|
||||
|
||||
@@ -117,15 +117,13 @@ describe("身份解析状态", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Slot / 内容类型 / 分段 / 整理动作", () => {
|
||||
describe("Slot / 分段 / 整理动作", () => {
|
||||
it("Slot 状态两侧一一对应", () => {
|
||||
expect(sorted(M.DOMAIN_SLOT_STATUSES)).toEqual(sorted(C.SlotStatus.options));
|
||||
for (const s of C.SlotStatus.options) expect(M.toContractSlotStatus(M.toDomainSlotStatus(s))).toBe(s);
|
||||
});
|
||||
|
||||
it("综艺内容类型两侧一一对应;分段 unknown ↔ 缺失", () => {
|
||||
expect(sorted(M.DOMAIN_CONTENT_TYPES)).toEqual(sorted(C.ContentType.options));
|
||||
for (const t of C.ContentType.options) expect(M.toContractContentType(M.toDomainContentType(t))).toBe(t);
|
||||
it("分段 unknown ↔ 缺失", () => {
|
||||
expect(sorted([...M.DOMAIN_SEGMENTS, "unknown"])).toEqual(sorted(C.Segment.options));
|
||||
for (const s of C.Segment.options) expect(M.toContractSegment(M.toDomainSegment(s))).toBe(s);
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user