feat(downloads): 多下载器路由:默认下载器、站点指定下载器、别名
照 MP(chain/download/submission.py:明确指定 or 站点下载器 or 默认): - 迁移 0063:downloader_instance.is_default(至多一个,唯一索引)、site.downloader_instance_id - pickInstance:明确指定 > 站点指定 > 默认 > 第一个可用;自动下载(gates)与手动下载共用 - 设置:下载器名称改称别名,新增「设为默认下载器」;站点编辑新增「下载器」选择 - 测试 downloader-routing.test.ts Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
64e1dfb1d2
commit
135c50048f
12 files changed
+196
-11
No files matched your search
@@ -68,6 +68,8 @@ export const DownloaderInstance = EntityBase.extend({
|
||||
/** 共享缓存卷标识:多 qB 共用同一卷时按此汇总水位 */
|
||||
cacheVolumeKey: z.string().nullable(),
|
||||
enabled: z.boolean(),
|
||||
/** 默认下载器(至多一个):订阅 / 手动没指定、站点也没指定时用它 */
|
||||
isDefault: z.boolean(),
|
||||
healthStatus: InstanceHealth,
|
||||
lastSeenAt: Timestamp.nullable(),
|
||||
versionInfo: JsonObject,
|
||||
@@ -82,9 +84,18 @@ export const DownloaderInstanceCreate = DownloaderInstance.pick({
|
||||
managedTag: true,
|
||||
cacheVolumeKey: true,
|
||||
enabled: true,
|
||||
isDefault: true,
|
||||
settings: true,
|
||||
})
|
||||
.partial({ kind: true, username: true, managedTag: true, cacheVolumeKey: true, enabled: true, settings: true })
|
||||
.partial({
|
||||
kind: true,
|
||||
username: true,
|
||||
managedTag: true,
|
||||
cacheVolumeKey: true,
|
||||
enabled: true,
|
||||
isDefault: true,
|
||||
settings: true,
|
||||
})
|
||||
.extend({
|
||||
credential: Credential.optional(),
|
||||
/** 认证方式,写入 settings.authKind;缺省按"有用户名 → 账密,否则有凭证 → API Key,否则无认证"推断 */
|
||||
|
||||
@@ -185,6 +185,8 @@ export const Site = EntityBase.extend({
|
||||
proxy: z.boolean(),
|
||||
/** 默认参与资源搜索(站点选择弹层的"默认"集合) */
|
||||
searchDefault: z.boolean(),
|
||||
/** 该站资源用的下载器;null = 默认下载器(订阅 / 手动明确指定时以指定为准) */
|
||||
downloaderInstanceId: Id.nullable(),
|
||||
});
|
||||
export type Site = z.infer<typeof Site>;
|
||||
export const SiteCreate = Site.pick({
|
||||
@@ -200,6 +202,7 @@ export const SiteCreate = Site.pick({
|
||||
snapshotIntervalSec: true,
|
||||
proxy: true,
|
||||
searchDefault: true,
|
||||
downloaderInstanceId: true,
|
||||
})
|
||||
.partial({
|
||||
key: true,
|
||||
@@ -211,6 +214,7 @@ export const SiteCreate = Site.pick({
|
||||
snapshotIntervalSec: true,
|
||||
proxy: true,
|
||||
searchDefault: true,
|
||||
downloaderInstanceId: true,
|
||||
})
|
||||
.extend({
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { Kysely } from "kysely";
|
||||
import { execDdl } from "../src/migration-helpers.ts";
|
||||
|
||||
// 多下载器路由(照 MP):下载器选择 = 明确指定(订阅 / 手动)> 站点指定 > 默认下载器 > 第一个可用。
|
||||
// 默认下载器至多一个;站点指定的下载器被删时回落默认。
|
||||
// biome-ignore lint/suspicious/noExplicitAny: 迁移不依赖应用表类型
|
||||
export async function up(db: Kysely<any>): Promise<void> {
|
||||
await execDdl(
|
||||
db,
|
||||
`alter table downloader_instance add column if not exists is_default boolean not null default false;
|
||||
create unique index if not exists downloader_instance_one_default on downloader_instance ((true)) where is_default;
|
||||
alter table site add column if not exists downloader_instance_id uuid references downloader_instance (id) on delete set null;`,
|
||||
);
|
||||
}
|
||||
// biome-ignore lint/suspicious/noExplicitAny: 同上
|
||||
export async function down(db: Kysely<any>): Promise<void> {
|
||||
await execDdl(
|
||||
db,
|
||||
`alter table site drop column if exists downloader_instance_id;
|
||||
drop index if exists downloader_instance_one_default;
|
||||
alter table downloader_instance drop column if exists is_default;`,
|
||||
);
|
||||
}
|
||||
@@ -730,6 +730,7 @@ export interface DownloaderInstanceTable {
|
||||
settings: Generated<Json>;
|
||||
created_at: GeneratedTimestamptz;
|
||||
updated_at: GeneratedTimestamptz;
|
||||
is_default: Generated<boolean>;
|
||||
}
|
||||
|
||||
export interface ExternalIdentityTable {
|
||||
@@ -1429,6 +1430,7 @@ export interface SiteTable {
|
||||
deleted_at: Timestamptz | null;
|
||||
search_default: Generated<boolean>;
|
||||
kind: Generated<SiteKind>;
|
||||
downloader_instance_id: string | null;
|
||||
}
|
||||
|
||||
export interface SiteAccountTable {
|
||||
|
||||
Reference in new issue
Block a user