feat: merge opus comfyui and login updates

This commit is contained in:
boos
2026-05-21 16:32:04 +02:00
parent c16479da7c
commit 9c84759498
105 changed files with 20160 additions and 1034 deletions
@@ -0,0 +1,82 @@
## ADDED Requirements
### Requirement: 启动时确保内置 ComfyUI Agent key 存在
服务启动序列 SHALL 在数据库迁移完成之后、HTTP 路由对外提供之前,调用 `ensure_comfyui_agent_key`,确保 `downstream_api_keys` 表中存在唯一一行 `name='comfyui-agent' AND user_id IS NULL`,且其明文 key 同步保存在 `settings` 表的 `builtin_key.comfyui_agent.secret` 键。该流程 MUST 幂等。
#### Scenario: 全新数据库首次启动
- **WHEN** 启动时数据库无任何 `name='comfyui-agent'` 行,且 settings 表无 `builtin_key.comfyui_agent.secret`
- **THEN** 启动结束后两处都存在;密钥形如 `sk-comfyui-<32 位十六进制或等价 uuid>`;`enabled=1`
#### Scenario: 已有 settings 但缺少表记录(崩溃恢复)
- **WHEN** settings 表存在 `builtin_key.comfyui_agent.secret = "sk-comfyui-xxx"`,但 `downstream_api_keys` 中没有对应行
- **THEN** 引导逻辑用 settings 中的明文回填一行 `downstream_api_keys`,不重新生成密钥
#### Scenario: 已有表记录但缺少 settings
- **WHEN** `downstream_api_keys` 中存在 `name='comfyui-agent' AND user_id IS NULL` 行 key=`sk-comfyui-yyy`,但 settings 中无 `builtin_key.comfyui_agent.secret`
- **THEN** 引导逻辑把表中的明文写回 settings;密钥保持原值
#### Scenario: 重复启动不变更密钥
- **WHEN** 同一数据库连续启动两次
- **THEN** 第二次启动后 settings 与表中的 key 与第一次完全一致
#### Scenario: 引导期间发现 enabled=0 自动恢复
- **WHEN** 启动时发现已有行 `enabled=0`
- **THEN** 引导逻辑把该行 `enabled` 设为 1,并通过 `tracing::warn!` 输出一条提示
### Requirement: 系统级 key 在管理 API 中受保护
任何 admin 接口 SHALL 拒绝对 `name='comfyui-agent' AND user_id IS NULL` 的下游 key 执行删除(`DELETE`)或将 `enabled` 设为 false。list / get 类响应 MUST 把这一行标记为 `system: true`,并 mask 明文 key(仅暴露后 4 位)。
#### Scenario: DELETE 被拒
- **WHEN** admin 调用 `DELETE` 删除该 key 对应 id
- **THEN** 返回 403 / 409 类错误(取实现选择),message 含 `system key` 关键字;数据库中的行不变
#### Scenario: 禁用被拒
- **WHEN** admin PATCH/PUT 设 `enabled=false`
- **THEN** 返回拒绝错误,行 `enabled` 保持 1
#### Scenario: 列表响应打码
- **WHEN** admin GET 列出下游 key
- **THEN** 该行字段 `key` 形如 `••••••••<后4位>`,并附 `system: true`
#### Scenario: 普通 key 不受影响
- **WHEN** admin 操作其他普通 user_id 非空的 key
- **THEN** DELETE / PATCH / list 行为不受系统 key 保护逻辑影响
### Requirement: settings 中的内置密钥不暴露给 admin 列表
如果存在 admin 接口列出 `settings` 表内容,该接口 SHALL 过滤所有以 `builtin_key.` 为前缀的 key;按 key 单独读取时,对该前缀返回 404 或带占位符 `"••••"`,不返回实际明文。
#### Scenario: 列表过滤前缀
- **WHEN** admin GET `/api/admin/settings`(若存在)
- **THEN** 响应中不出现任何 key 以 `builtin_key.` 开头的条目
#### Scenario: 单读返回占位
- **WHEN** admin GET `/api/admin/settings/builtin_key.comfyui_agent.secret`(若存在)
- **THEN** 返回 404 或 `value: "••••"`,不返回真实明文
### Requirement: 内置 key 用 user_id IS NULL 与普通 key 区分
内置下游 key 在 `downstream_api_keys` 表中 SHALL 满足 `user_id IS NULL`;任何普通用户创建的 key MUST 写入非空 `user_id`,确保 `name='comfyui-agent' AND user_id IS NULL` 的查询能稳定匹配仅一行。
#### Scenario: 普通用户不能创建同名 key 占用系统标识
- **WHEN** 普通用户调用创建 key 接口,name 设为 `comfyui-agent`
- **THEN** 该 key 仍写入非空 user_id;系统级查询不会返回该行
#### Scenario: 引导查询仅匹配系统行
- **WHEN** 数据库中同时存在 user_id=5 且 name='comfyui-agent' 的普通 key 与 user_id IS NULL 的系统 key
- **THEN** `ensure_comfyui_agent_key` 仅作用于 user_id IS NULL 的那一行