feat(organize): expose recovery facts and retain original request on retries
This commit is contained in:
1 parent
80151077a9
commit
b7883eaf4f
2 files changed
+47
-1
No files matched your search
@@ -3,7 +3,7 @@ import { Id, JsonObject, NonNegInt, Timestamp } from "./common.ts";
|
|||||||
import { MediaKind } from "./content.ts";
|
import { MediaKind } from "./content.ts";
|
||||||
import { DownloadStatus } from "./execution.ts";
|
import { DownloadStatus } from "./execution.ts";
|
||||||
import { InstanceHealth, LibraryMediaKind } from "./instances.ts";
|
import { InstanceHealth, LibraryMediaKind } from "./instances.ts";
|
||||||
import { OrganizationStatus, PublicOrganizationRecord } from "./organization.ts";
|
import { OrganizationRecovery, OrganizationStatus, PublicOrganizationRecord } from "./organization.ts";
|
||||||
import { SlotStatus } from "./policy.ts";
|
import { SlotStatus } from "./policy.ts";
|
||||||
import { ScrapeMode, ScrapeRecord } from "./scrape.ts";
|
import { ScrapeMode, ScrapeRecord } from "./scrape.ts";
|
||||||
|
|
||||||
@@ -400,6 +400,8 @@ export const FilesOrganizeEpisodeStructure = z.object({
|
|||||||
export type FilesOrganizeEpisodeStructure = z.infer<typeof FilesOrganizeEpisodeStructure>;
|
export type FilesOrganizeEpisodeStructure = z.infer<typeof FilesOrganizeEpisodeStructure>;
|
||||||
|
|
||||||
export const FilesOrganizeRequest = z.object({
|
export const FilesOrganizeRequest = z.object({
|
||||||
|
/** 重新整理沿用此记录的已知业务选项,表单明确选择覆盖它们。 */
|
||||||
|
recoveryRecordId: Id.optional(),
|
||||||
sourceConfigId: Id.optional(),
|
sourceConfigId: Id.optional(),
|
||||||
idempotencyKey: IdempotencyKey,
|
idempotencyKey: IdempotencyKey,
|
||||||
items: z.array(FilesOrganizeItem).min(1).max(500),
|
items: z.array(FilesOrganizeItem).min(1).max(500),
|
||||||
@@ -970,6 +972,9 @@ export type FilesTreeResult = z.infer<typeof FilesTreeResult>;
|
|||||||
export const FilesRecordSourcesQuery = z.object({ recordId: Id });
|
export const FilesRecordSourcesQuery = z.object({ recordId: Id });
|
||||||
export type FilesRecordSourcesQuery = z.infer<typeof FilesRecordSourcesQuery>;
|
export type FilesRecordSourcesQuery = z.infer<typeof FilesRecordSourcesQuery>;
|
||||||
export const FilesRecordSourcesResult = z.object({
|
export const FilesRecordSourcesResult = z.object({
|
||||||
|
recovery: OrganizationRecovery.optional(),
|
||||||
|
/** 已核对登记库根和目录边界的原目标,前端无需从本机绝对路径推算。 */
|
||||||
|
targetDir: FileRef.optional(),
|
||||||
/** 原整理计划保存的来源策略;不存在时由当前入口重新匹配。 */
|
/** 原整理计划保存的来源策略;不存在时由当前入口重新匹配。 */
|
||||||
sourceConfigId: Id.optional(),
|
sourceConfigId: Id.optional(),
|
||||||
recordId: Id,
|
recordId: Id,
|
||||||
|
|||||||
@@ -239,7 +239,48 @@ export const RecordAttention = z.object({
|
|||||||
});
|
});
|
||||||
export type RecordAttention = z.infer<typeof RecordAttention>;
|
export type RecordAttention = z.infer<typeof RecordAttention>;
|
||||||
|
|
||||||
|
/** 历史整理可以沿用的事实与需补齐的设置;只在详情和重新整理入口返回。 */
|
||||||
|
export const OrganizationRecoveryRequest = z.object({
|
||||||
|
downloadTaskId: Id.optional(),
|
||||||
|
sourcePaths: z.array(z.string()).optional(),
|
||||||
|
mediaEntityId: Id.optional(),
|
||||||
|
contentUnitId: Id.optional(),
|
||||||
|
action: z.enum(["copy", "move", "in_place"]).optional(),
|
||||||
|
targetLibraryRootId: Id.optional(),
|
||||||
|
targetDir: z.string().optional(),
|
||||||
|
sourceConfigId: Id.optional(),
|
||||||
|
slotId: Id.optional(),
|
||||||
|
onExisting: z.enum(["skip", "conflict", "replace_with_verify"]).optional(),
|
||||||
|
namingMode: z.enum(["template", "keep"]).optional(),
|
||||||
|
minSizeBytes: NonNegInt.optional(),
|
||||||
|
scrapeAfterImport: z.boolean().optional(),
|
||||||
|
skipSuccessfulRecords: z.boolean().optional(),
|
||||||
|
keepBoth: z.boolean().optional(),
|
||||||
|
importMode: z.enum(["normal", "replace"]).optional(),
|
||||||
|
replacementAssetIds: z.array(Id).optional(),
|
||||||
|
fileOverrides: z
|
||||||
|
.record(
|
||||||
|
z.string(),
|
||||||
|
z.object({
|
||||||
|
season: NonNegInt.optional(),
|
||||||
|
episodes: z.object({ start: NonNegInt, end: NonNegInt }).optional(),
|
||||||
|
contentUnitIds: z.array(Id).optional(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.optional(),
|
||||||
|
episodeStructure: z.object({ groupId: z.string().nullable(), appliedToEntity: z.boolean().optional() }).optional(),
|
||||||
|
});
|
||||||
|
export type OrganizationRecoveryRequest = z.infer<typeof OrganizationRecoveryRequest>;
|
||||||
|
export const OrganizationRecovery = z.object({
|
||||||
|
ready: z.boolean(),
|
||||||
|
source: z.enum(["request", "task", "plan", "record"]),
|
||||||
|
missing: z.array(z.enum(["sourcePaths", "options", "episodeStructure"])),
|
||||||
|
request: OrganizationRecoveryRequest,
|
||||||
|
});
|
||||||
|
export type OrganizationRecovery = z.infer<typeof OrganizationRecovery>;
|
||||||
|
|
||||||
export const PublicOrganizationRecord = z.object({
|
export const PublicOrganizationRecord = z.object({
|
||||||
|
recovery: OrganizationRecovery.optional(),
|
||||||
/** 稳定记录 ID */
|
/** 稳定记录 ID */
|
||||||
id: Id,
|
id: Id,
|
||||||
taskId: Id.nullable(),
|
taskId: Id.nullable(),
|
||||||
|
|||||||
Reference in new issue
Block a user