From 74f2c7649e481a17e8fe648eece993359a607baf Mon Sep 17 00:00:00 2001 From: root Date: Sat, 3 Oct 2026 23:20:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(db):=20=E5=BE=85=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E3=80=8C=E4=B8=8B=E8=BD=BD=E5=99=A8=E8=BF=9E?= =?UTF-8?q?=E4=B8=8D=E4=B8=8A=E3=80=8D=E3=80=8C=E4=B8=8B=E8=BD=BD=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E8=AF=BB=E4=B8=8D=E5=88=B0=E5=AE=B9=E9=87=8F=E3=80=8D?= =?UTF-8?q?=E4=B8=A4=E7=B1=BB=EF=BC=88=E8=BF=81=E7=A7=BB=200073=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit decision.kind 增加 downloader_offline / cache_volume_unknown,契约、原因文案与界面标签同步; volume_state_unknown 的原因文案改为「下载目录读不到容量」并指向路径映射与容器挂载。 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei --- apps/web/app/components/library/labels.ts | 2 + apps/web/app/lib/labels.ts | 2 + packages/contracts/src/agent.ts | 4 ++ packages/contracts/src/reasons.ts | 4 +- .../migrations/0073_downloader_visibility.ts | 40 +++++++++++++++++++ packages/db/src/types.ts | 4 +- 6 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 packages/db/migrations/0073_downloader_visibility.ts diff --git a/apps/web/app/components/library/labels.ts b/apps/web/app/components/library/labels.ts index 043b9afe..08c20617 100644 --- a/apps/web/app/components/library/labels.ts +++ b/apps/web/app/components/library/labels.ts @@ -142,6 +142,8 @@ export const DECISION_KIND: Record = { approval_required: "需要审批", metadata_conflict: "元数据冲突", source_unreachable: "来源不可达", + downloader_offline: "下载器连不上", + cache_volume_unknown: "下载目录读不到容量", other: "其他", }; diff --git a/apps/web/app/lib/labels.ts b/apps/web/app/lib/labels.ts index 931e24bf..d5ceae79 100644 --- a/apps/web/app/lib/labels.ts +++ b/apps/web/app/lib/labels.ts @@ -49,6 +49,8 @@ const DECISION_KIND: Record = { approval_required: "待审批", metadata_conflict: "元数据冲突", source_unreachable: "来源不可达", + downloader_offline: "下载器连不上", + cache_volume_unknown: "下载目录读不到容量", other: "其它", }; export const decisionKindLabel = (v: string) => DECISION_KIND[v] ?? v; diff --git a/packages/contracts/src/agent.ts b/packages/contracts/src/agent.ts index 9148237f..423578e2 100644 --- a/packages/contracts/src/agent.ts +++ b/packages/contracts/src/agent.ts @@ -149,6 +149,10 @@ export const DecisionKind = z.enum([ "identity_unresolved", /** 资源已绑定作品但集数待确认(无法换算 / 映射规则失效):按作品 + 来源季 + 发布组合并,附建议规则 */ "episode_mapping", + /** 下载器连续不可达超过一段时间(按实例去重,恢复后自动关闭) */ + "downloader_offline", + /** 下载目录读不到容量(路径映射 / 挂载问题,按卷去重,恢复后自动关闭) */ + "cache_volume_unknown", ]); export type DecisionKind = z.infer; export const DecisionStatus = z.enum(["open", "investigating", "awaiting_user", "resolved", "dismissed", "expired"]); diff --git a/packages/contracts/src/reasons.ts b/packages/contracts/src/reasons.ts index fd624f6c..505f4897 100644 --- a/packages/contracts/src/reasons.ts +++ b/packages/contracts/src/reasons.ts @@ -66,7 +66,7 @@ const REASONS: Record = { not_found: { text: "没找到" }, precondition: { text: "前置条件不满足" }, internal: { text: "内部错误" }, - volume_state_unknown: { text: "下载盘用量未知", action: "在下载面板检查下载盘" }, + volume_state_unknown: { text: "下载目录读不到容量", action: "检查下载器的路径映射和容器挂载" }, hard_threshold_reached: { text: "下载盘已到暂停线" }, projected_over_threshold: { text: "下完会超过下载盘暂停线" }, awaiting_resume_watermark: { text: "等下载盘降到恢复线" }, @@ -85,6 +85,8 @@ const REASONS: Record = { download_failed: { text: "下载失败" }, download_stalled: { text: "下载无进展" }, space_insufficient: { text: "空间不足" }, + downloader_offline: { text: "下载器连不上" }, + cache_volume_unknown: { text: "下载目录读不到容量" }, unidentifiable: { text: "没识别出作品" }, user_deleted: { text: "已删除" }, // DL-3:还没提交就结束或在等的下载(计划的 statusReason、提交任务的延后原因) diff --git a/packages/db/migrations/0073_downloader_visibility.ts b/packages/db/migrations/0073_downloader_visibility.ts new file mode 100644 index 00000000..518d55e9 --- /dev/null +++ b/packages/db/migrations/0073_downloader_visibility.ts @@ -0,0 +1,40 @@ +import type { Kysely } from "kysely"; +import { execDdl, oneOf } from "../src/migration-helpers.ts"; + +// 下载侧可见性:decision.kind 增加 +// - downloader_offline:下载器连续不可达超过一段时间(按实例去重,恢复后自动关闭) +// - cache_volume_unknown:下载目录读不到容量(路径映射 / 挂载问题,按卷去重,恢复后自动关闭) + +const OLD_DECISION_KINDS = [ + "identity_ambiguous", + "download_stalled", + "download_failed", + "path_conflict", + "space_insufficient", + "approval_required", + "metadata_conflict", + "source_unreachable", + "other", + "identity_unresolved", + "episode_mapping", +]; +const NEW_DECISION_KINDS = [...OLD_DECISION_KINDS, "downloader_offline", "cache_volume_unknown"]; + +const swapDecisionKinds = (values: readonly string[]) => ` +alter table decision drop constraint decision_kind_check; +alter table decision add constraint decision_kind_check ${oneOf("kind", values)}; +`; + +// biome-ignore lint/suspicious/noExplicitAny: 迁移不依赖应用表类型 +export async function up(db: Kysely): Promise { + await execDdl(db, swapDecisionKinds(NEW_DECISION_KINDS)); +} + +// biome-ignore lint/suspicious/noExplicitAny: 同上 +export async function down(db: Kysely): Promise { + await execDdl( + db, + `update decision set kind = 'other' where kind in ('downloader_offline', 'cache_volume_unknown'); + ${swapDecisionKinds(OLD_DECISION_KINDS)}`, + ); +} diff --git a/packages/db/src/types.ts b/packages/db/src/types.ts index fd96bd81..b9801dfc 100644 --- a/packages/db/src/types.ts +++ b/packages/db/src/types.ts @@ -112,7 +112,9 @@ export type DecisionKind = | "source_unreachable" | "other" | "identity_unresolved" - | "episode_mapping"; + | "episode_mapping" + | "downloader_offline" + | "cache_volume_unknown"; export type DecisionStatus = "open" | "investigating" | "awaiting_user" | "resolved" | "dismissed" | "expired"; export type DecisionSeverity = "info" | "warning" | "critical"; export type DownloadTaskOrigin = "submitted" | "adopted";