Files
UHD_Media_Tool/packages/db/migrations/0024_trash.ts
T
rootandClaude Opus 5.5 09f6e3a3e5 feat(db,contracts): trash_item migration and file manager contract refinements
- 0024_trash: trash_item table + unique idempotency index on artifact(files_idem)
- files.ts: TrashItemRow, delete planId/planExpiresAt, organize group warnings,
  scrape returns refreshMetadata taskId
- registry tests list the new table/row schema

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 23:02:14 +08:00

42 lines
1.6 KiB
TypeScript

import type { Kysely } from "kysely";
import { dropTables, entityTable, execDdl } from "../src/migration-helpers.ts";
// W5-A 文件管理(docs/plan/06-file-manager-spec.md §2.3.3):
// - trash_item:删除进回收站的记录(原根/原相对路径/回收站内路径/到期时间/关联资产快照);
// 还原或清除后删行(历史留在 audit_event)。root_id 为文件管理的根 id(lib:<uuid> / dl:<uuid>:<n>)。
// - artifact_files_idem_key:文件管理写操作的幂等键(artifact title='files_idem',content.key)唯一。
// biome-ignore lint/suspicious/noExplicitAny: 迁移不依赖应用表类型
export async function up(db: Kysely<any>): Promise<void> {
await execDdl(
db,
`
${entityTable(
"trash_item",
`
root_id text not null,
library_root_id uuid references library_root (id) on delete set null,
root_host_path text not null,
original_path text not null,
trash_path text not null,
is_dir boolean not null default false,
size_bytes bigint not null default 0,
actor text,
deleted_at timestamptz not null default now(),
expires_at timestamptz not null,
asset_snapshot jsonb,
constraint trash_item_trash_path_key unique (trash_path)`,
)}
create index trash_item_expires_idx on trash_item (expires_at);
create index trash_item_root_idx on trash_item (root_id, deleted_at desc);
create unique index artifact_files_idem_key on artifact ((content->>'key')) where title = 'files_idem';
`,
);
}
// biome-ignore lint/suspicious/noExplicitAny: 同上
export async function down(db: Kysely<any>): Promise<void> {
await execDdl(db, `drop index if exists artifact_files_idem_key;\n${dropTables(["trash_item"])}`);
}