feat(organize): 整理时指定季集结构(临时剧集组 / 同时设为作品结构)
- 契约:FilesOrganizeRequest.episodeStructures(按作品 groupId / applyToEntity),组响应带 episodeStructure - 集数映射:createStructureEpisodeMapper 按指定结构的季表(剧集组带原季集对照)换算;作品规则先按作品结构命中,再经 TMDB 原季集换到指定结构 - 资产覆盖:指定结构季集 → TMDB 原季集 → 作品当前结构的单元,换不回不登记集覆盖;冻结计划记 episodeStructure 与 facts.structureEpisodes - 向导执行勾选「同时设为作品的季集结构」时先走 setEpisodeGroup 切换作品再整理 - 测试:organize-episode-structure(SPLIT_COUR_FIXTURE) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
1 parent
731336ccb1
commit
d55fa4b240
10 files changed
+637
-11
No files matched your search
@@ -381,6 +381,18 @@ export const FilesOrganizeItem = FileRef.extend({
|
||||
});
|
||||
export type FilesOrganizeItem = z.infer<typeof FilesOrganizeItem>;
|
||||
|
||||
/**
|
||||
* 整理时指定季集结构(对照 MP TransferInfo.episode_group):这次整理按 groupId 的季集换算与命名,不改作品设置;
|
||||
* groupId null = TMDB 默认季。applyToEntity = 同时设为作品的季集结构(执行时先切换作品,再按新结构整理;预览不切换)。
|
||||
* 与作品当前结构相同等同跟随作品。只对本地剧集作品生效
|
||||
*/
|
||||
export const FilesOrganizeEpisodeStructure = z.object({
|
||||
mediaEntityId: Id,
|
||||
groupId: z.string().trim().min(1).max(64).nullable(),
|
||||
applyToEntity: z.boolean().optional(),
|
||||
});
|
||||
export type FilesOrganizeEpisodeStructure = z.infer<typeof FilesOrganizeEpisodeStructure>;
|
||||
|
||||
export const FilesOrganizeRequest = z.object({
|
||||
sourceConfigId: Id.optional(),
|
||||
idempotencyKey: IdempotencyKey,
|
||||
@@ -402,6 +414,8 @@ export const FilesOrganizeRequest = z.object({
|
||||
skipSuccessfulRecords: z.boolean().optional(),
|
||||
/** 本次入库后写 NFO/图片;缺省沿用已有设置,Local 保留自动补全行为。 */
|
||||
scrapeAfterImport: z.boolean().optional(),
|
||||
/** 整理时指定季集结构(按作品,缺省跟随作品),见 FilesOrganizeEpisodeStructure */
|
||||
episodeStructures: z.array(FilesOrganizeEpisodeStructure).max(50).optional(),
|
||||
});
|
||||
export type FilesOrganizeRequest = z.infer<typeof FilesOrganizeRequest>;
|
||||
|
||||
@@ -463,6 +477,15 @@ export const FilesOrganizeGroup = z.object({
|
||||
targetSegments: z
|
||||
.array(z.object({ text: z.string(), role: z.enum(["root", "season", "dir"]), bound: z.boolean() }))
|
||||
.optional(),
|
||||
/** 本组按哪套季集结构整理(请求指定了季集结构时才有);temporary = 与作品结构不同、只这次使用 */
|
||||
episodeStructure: z
|
||||
.object({
|
||||
groupId: z.string().nullable(),
|
||||
name: z.string(),
|
||||
temporary: z.boolean(),
|
||||
appliedToEntity: z.boolean().optional(),
|
||||
})
|
||||
.optional(),
|
||||
/** W9-H(G5):执行后排的元数据刷新 run id(refreshMetadata=true 且该组已提交) */
|
||||
refreshTaskId: z.string().nullable().optional(),
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user