docs(design): 设置页分类方案与旧锚点映射,runbook 改到新位置

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-06 18:01:27 +08:00
1 parent 8071ad33f9
commit 7c0b30ee37
8 files changed
+60 -53

No files matched your search

+46 -39
View File
@@ -147,33 +147,32 @@
重定向统一写在各自路由模块的 `clientLoader` 里(或新增 `routes/console/redirects.ts` 集中表),`nav.test.ts` 增加"旧链接都能落到新路由"的用例。
### 3.4 设置页分区(按接入对象)
### 3.4 设置页分区(2026-10-06 重排,替换 IA-2 方案)
| 分区 `section` | 字段 | 来自现有 | 存储 |
| --- | --- | --- | --- |
| 自动化 `automation` | 总开关、只读对账;**缓存**:硬阈值/恢复/清理目标/检查间隔;**每日预算**:新作品数、下载量、并发;**保留**:做种保留天数、日志保留天数 | 自动化 + 缓存与入库(①③ + 保留) | `automation` `cache` `budget.下载三项` `retention` |
| 站点与账号 `sites` | 站点登记(名称、类型、地址、启用)、账号凭证(标签/类型/登录名/凭证)、浏览器服务(provider、能力 supported/verified 只读) | 站点凭证 + **新增站点表单**(C1)+ `browser.ts` | sites / secrets / browser API |
| 下载器 `downloaders` | qB 实例全字段 + 健康 + 测试 | 下载器 | instances |
| 媒体库与目录 `library` | 锚点 `#roots` 库根;`#mappings` 路径映射(下挂在库根下展示);`#organize` 整理默认:默认 Copy/Move、跨卷 Move | 库根 + 路径映射 + 缓存与入库② | instances + `organize` |
| 媒体服务器 `media-servers` | Emby/Jellyfin 实例 | 媒体服务器 | instances |
| 元数据 `metadata` | TMDB Key(只写)、TMDB Base URL、状态(已配置 / 回退环境变量 / 未配置) | **新增 UI**(C5) | `metadata` |
| Agent `agent` | `#upstream` 上游与模型(provider/model/baseUrl/Key/思考/上下文/压缩/子代理);`#budget` 每日次数/费用 + 单次上限;`#investigate` 自动调查开关/模式/次数/核实时长/工具上限;`#advanced` 目标轮询、会话目录、fake 脚本 | Pi 上游(3 卡) | `pi` `agent` `budget.agent*` |
| API Key `api-keys` | 签发给外部程序的 Key(scope、撤销);页首说明"浏览器自用 token 在右上角账户菜单"(C9) | API Key | api-keys |
| 账户与安全 `account` | 修改密码、会话注销、本机 token | 账户菜单(菜单保留快捷入口) | auth |
沿用 MP 的两条逻辑:**按「接入对象 / 业务环节」分区**,**对象管理与参数设定分开**;不照抄它「系统」Tab 过载的做法(下载器、媒体服务器、AI、TMDB 全塞一页再套子 Tab)。左栏三组,组内按用户找东西的顺序排;每个分区一句说明;接入对象类分区第一节是对象列表(实例 / 目录 / 模型服务),之后才是全局参数。分区、节、字段归属登记在 `packages/contracts/src/settings.ts` 的 `SETTINGS_SECTIONS`,测试断言每个在用的存储字段恰好归属一个分区、且出现在该分区页面上。
| 组 | 分区 `id` | 一句说明 | 节(锚点) | 存储 / 对象 |
| --- | --- | --- | --- | --- |
| 接入 | 下载器 `downloaders` | qBittorrent 实例与路径映射;下载盘水位和保种天数的缺省值,实例里可以单独改 | instances 实例 · cache 下载盘 · seeding 保种 | 实例(含路径映射、单实例暂停线 / 恢复线 / 清理目标 / 保种天数 / H&R 未知也可清理);`cache` 水位四项;`retention.seedRetentionDays` |
| 接入 | 媒体服务器 `media-servers` | Emby / Jellyfin 实例与路径映射,只用来查作品有没有 | instances | 实例 |
| 接入 | 站点与网络 `sites` | 站点缺省值、User-Agent 与代理、浏览器服务;站点、凭证和 Cloudflare 在站点页 | defaults 站点缺省值 · network UA 与代理 · browser 浏览器服务 | `sites.*`;浏览器服务 |
| 接入 | 元数据 `metadata` | TMDB 接入、语言回退与特别篇 | tmdb · language 语言与季集 | `metadata.*` |
| 流程 | 获取 `acquire` | 每日下载预算、搜索站点、资源识别;订阅和规则在各自页面 | budget 每日预算 · search 搜索站点 · identity 资源识别 | `budget.*`、`search.*`、`identity.*` |
| 流程 | 媒体库与目录 `library` | 媒体库目录、整理来源、分类规则、命名模板 | roots · sources · classification · naming · naming-roots | 媒体库目录;`organize.classificationYaml / sources`;`naming.*` |
| 流程 | 整理与刮削 `organize` | 整理方式、最小视频体积、整理后自动刮削和已有文件的覆盖方式 | mode 整理方式 · scrape 刮削 | `organize.defaultMode / allowCrossVolumeMove / minSizeBytes / scrape*`(覆盖方式:更新 / 只补缺失 / 全部覆盖) |
| 流程 | 智能体 `agent` | 模型服务、用量与防跑飞限制、自动处理、网页搜索、MCP | upstream · budget 用量与限制 · investigate 自动处理 · runtime 上下文与子会话 · websearch · mcp · capabilities · advanced | 模型服务;`pi.*`;`agent.*`(不设预算,只有单次工具调用次数与时长两个上限 + 花费统计;识别失败自动派智能体在「自动处理」) |
| 系统 | 系统 `system` | 自动化总开关、只读对账、后台任务并发、存储预算、数据保留 | switches 自动化 · readonly · worker-lanes · storage · storage-retention | `automation.*`、`storage.budgets / retentionDays` |
| 系统 | 缓存 `cache` | 各类缓存的条数、占用和有效期,可以按区清空 | regions 缓存区 · tmdb-cache · images · ttl 缓存有效期 | kv_cache 各区 + 图片缓存(`GET /cache/regions`、`POST /cache/regions/{region}/clear`、`/cache/tmdb*`、`/cache/images*`);`cache.tmdbMaxSize / globalImageCache*`;`storage.cacheTtl` |
| 系统 | 账户与安全 `account` | 密码、二次验证、通行密钥、会话与本机 Token、API Key | password · totp · passkeys · session · api-keys | auth;API Key |
| 系统 | 界面 `interface` | 只影响当前浏览器 | display · shortcuts | 浏览器本地偏好 |
说明:
- "上游列表 / 默认上游"目前 contracts 只有单一 `pi.provider`,本次只把它放进 Agent 分区,多上游等 Agent 侧需求确定再做。
- 备份与系统信息(版本、数据目录、备份/恢复入口)暂无后端,先不建空分区;只读对账已在"自动化"。
- "预算"按**消耗谁**归属:下载预算归自动化,Agent 预算归 Agent,不再跨 Tab 拆半。
### 3.5 `contracts/settings.ts` 调整建议
**不改存储 key**(8 个 key 已在线上 settings 表,PATCH 语义按 key 合并)。改动只在"展示分区":
1. 新增 `SETTINGS_SECTIONS` 常量(UI 与服务端共用):`{ id, label, description, legacyTab[], fields: ["cache.hardThresholdPercent", …] }`,前端表单和重定向都读它,测试断言 8 个 key 的每个字段恰好归属一个分区。
2. `budget` 保留单 key,但在 `SETTINGS_SECTIONS` 里按前缀拆成两处展示(`maxNewTitlesPerDay/maxDownloadBytesPerDay/maxConcurrentDownloads` → 自动化;`agentMax*` → Agent)。
3. 若后续确要把 `budget.agentMax*` 挪到 `agent.daily.*`:加一次读时迁移(`{...DEFAULT, ...stored}` 之前把旧字段搬过去并写回),`GlobalSettingsUpdate` 两个版本各保留一个发行周期,审计里记一条 `settings.migrated`。本次**不做**。
4. `pi` 在 UI 文案一律叫"Agent 上游",key 名不变(避免 secret 引用与 PATCH 兼容问题)。
- **对象 vs 参数**:实例上可覆盖的项(下载盘水位、保种天数)的缺省值放在同一分区的对象列表下面,两处用同一组名字(暂停线、恢复线、清理目标、保种天数)。
- **预算按消耗谁归属**:下载预算归「获取」;智能体不设预算,只有防跑飞限制,归「智能体」。
- **不进设置页**:站点凭证与 Cloudflare 处理(站点页)、订阅与规则(各自页面)、主密钥(部署环境变量)、通知(暂无渠道设置,不建空分区)。
- **废弃字段**(`DEPRECATED_SETTINGS_FIELDS`)不显示:`pi` 旧上游字段、`cache.tmdbTtlHours / emptyResultTtlSec`、`identity.poolArchiveDays`、`retention.logRetentionDays`、智能体四个预算字段。
- **搜索**:左栏顶部(窄屏在下拉上方)的搜索框按分区名、节名、节别名(`anchors[].keywords`,如「H&R」「Cloudflare」「Passkey」)和表单字段名定位;选中字段时滚到该字段并聚焦。
- **旧锚点**:`SETTINGS_HASH_ALIASES` 把重排前的 hash 换到新位置(地址栏 replace,不留历史),见 §6。
### 3.6 页面内布局规范
@@ -270,24 +269,32 @@
- `components/agent/quick-goals.ts` 里的"待识别池"文案(W7-B 范围)。
- 原站视图仍是占位。
## 6. 设置分区已实施对照(IA-2,2026-09-28)
## 6. 设置分区已实施对照(2026-10-06 重排;替换 IA-2)
路由保持 `/console/settings`(routes.ts 归 IA-1),分区用 URL hash 定位:`#<分区>` 或 `#<分区>/<节>`;旧 `?tab=` 由设置页 `clientLoader` 跳到对应 hash。
分区定义在 `packages/contracts/src/settings.ts` 的 `SETTINGS_SECTIONS`(label、说明、锚点、字段、`legacyTabs`),测试断言 8 个存储 key 的每个字段恰好归属一个分区。组件在 `apps/web/app/components/settings/`。
路由仍是 `/console/settings`,分区用 URL hash 定位:`#<分区>` 或 `#<分区>/<节>`;旧 `?tab=` 由设置页 `clientLoader` 跳到对应 hash,旧 hash 由 `resolveSettingsHash` 换到新位置。分区与说明见 §3.4;组件在 `apps/web/app/components/settings/`(每个分区一个文件:`downloaders` `instances`(媒体服务器)`sites` `metadata` `acquire` `library` `organize` `agent` `system` `cache` `account` `interface`),搜索索引在 `search-index.ts`。
| 分区 | 节(锚点) | 实际内容 | 与 §3.4 的差异 |
| --- | --- | --- | --- |
| 自动化 `automation` | switches / cache / budget / retention | 总开关、只读对账(切换即生效);缓存水位 4 项;每日新作品数、下载量、并发;源文件保留天数、日志保留天数 | 无 |
| 站点与账号 `sites` | sites / accounts | 站点列表(启停开关、快照周期与新鲜度、账号数、健康);抽屉改地址、定时快照、快照周期、限流三项,并录入本站凭证;从内置站点定义登记新站点;账号列表(启停、删除)+ 录入凭证抽屉 | 浏览器服务能力未放进来(无对应写接口) |
| 下载器 `downloaders` | instances | qB 实例 CRUD + 连通测试;路径映射并入实例抽屉(只列本实例的映射,可加、校验、删) | §3.4 把映射放在"媒体库与目录",按 IA-2 任务改为挂在实例抽屉;`?tab=path-mappings` → `#downloaders` |
| 媒体库与目录 `library` | roots / organize | 库根 CRUD + 哨兵检查;默认整理方式(复制/移动)、允许跨卷移动 | 没有命名模板字段,"整理默认"只有这两项 |
| 媒体服务器 `media-servers` | instances | Emby/Jellyfin CRUD + 测试;抽屉里同样挂本实例的路径映射 | 无 |
| 元数据 `metadata` | tmdb | TMDB API Key(只写,显示已保存/清除)、Base URL | 语言、刷新周期在 contracts 里没有字段,未做 |
| Agent `agent` | upstream / runtime / budget / investigate / advanced | 上游列表(名称、provider、认证、模型、状态、默认)+ 新建向导(选 provider → 凭据与模型 → 登录/测试/设默认)+ 编辑抽屉(改配置、登录/重新登录/退出、测试、设默认、删除);上下文预算、压缩、子代理;每日与单次预算;自动调查;高级(轮询、等待、会话目录、fake 脚本) | 多上游已由 W7-A 落地,§3.4 说明里"多上游等 Agent 侧需求"作废;旧 `pi.provider/model/baseUrl/apiKey` 字段不再展示 |
| API Key `api-keys` | keys | 列表、创建(明文只显示一次)、撤销、scope 说明 | 无 |
| 账户与安全 `account` | password / totp / session / shortcuts | 改密、TOTP 开启/关闭、当前会话到期与退出、本机 Token、Agent 快捷键 | 后端没有会话列表/吊销接口,只能看当前会话;改密会注销其它会话 |
页面:宽屏左栏 = 搜索框 + 三组分区(当前分区展开节列表),右侧分区标题 + 一句说明 + 各节;窄屏 = 搜索框 + 分组下拉 + 一句说明 + 节的横排胶囊。每节有标题与说明;全局设置类的节有「未保存」标记、节尾保存条(还原 / 保存),保存后提示「已保存「节名」」;实例、站点、模型服务类在抽屉里保存;危险操作(清空缓存、删除)二次确认。
每节独立保存:全局设置类的节有"未保存"标记、保存/还原按钮,保存后 sonner 一句;实例、站点、上游类在抽屉里保存。窄屏左栏折叠为顶部下拉。
旧锚点映射(`SETTINGS_HASH_ALIASES`;同名的 `#downloaders`、`#agent/*`、`#sites/*`、`#library/{roots,sources,classification,naming}`、`#metadata/tmdb` 不变):
| 旧 | 新 |
| --- | --- |
| `#automation`、`#automation/switches` | `#system`、`#system/switches` |
| `#automation/cache`(`?tab=storage`) | `#downloaders/cache` |
| `#automation/budget` | `#acquire/budget` |
| `#automation/retention` | `#downloaders/seeding`(日志保留天数已废弃) |
| `#automation/advanced`、`#automation/readonly` | `#system/readonly` |
| `#automation/{worker-lanes,storage,storage-retention}` | `#system/` 同名节 |
| `#automation/storage-ttl` | `#cache/ttl` |
| `#automation/<其它>` | `#system` |
| `#library/organize`、`#library/scrape` | `#organize/mode`、`#organize/scrape` |
| `#metadata/identity` | `#acquire/identity` |
| `#metadata/tmdb-cache`、`#metadata/images` | `#cache/tmdb-cache`、`#cache/images` |
| `#api-keys`、`#api-keys/keys`(`?tab=api-keys`) | `#account/api-keys` |
| `#account/shortcuts` | `#interface/shortcuts` |
| `#sites/accounts` | `#sites` |
遗留:`components/console/nav.ts` 的 `SettingsSection` 类型仍是旧分区名(`automation`、`api-keys` 靠别名跳转可用),新分区 `acquire / organize / system / cache / interface` 要等 nav.ts 的 owner 补进类型后才能用 `settingsPath()` 直接深链。
## 7. IA-3 已实施对照(FE-1,2026-09-28)