60ecd8a13c
每任务抽1组函数(纯搬运)+cargo编译+测试验证+独立提交。通用6步流程统一。 Co-Authored-By: Claude <noreply@anthropic.com>
245 lines
13 KiB
Markdown
245 lines
13 KiB
Markdown
# workflow_ui.rs 拆分(8 子模块)实现计划
|
|
|
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
|
|
**Goal:** 把 `src/routes/workflow_ui.rs`(6181 行)按职责拆成 `src/routes/workflow_ui/` 目录 8 个子模块,纯机械移动、零逻辑改动,对外接口不变。
|
|
|
|
**Architecture:** 先建目录把原文件变 `mod.rs`,再逐个子模块把相关函数剪切出去(`pub(super)` 可见性 + 补 use),每步 cargo 编译验证。Rust 编译器是主安全网。
|
|
|
|
**Tech Stack:** Rust (axum, sqlx)。验证:`cargo build -j 2`、`cargo test -p boosapi --lib routes::workflow_ui`。
|
|
|
|
> **核心纪律:** 纯搬运,函数体一字不改;只改可见性 + use 路径。不优化、不改逻辑、不动路由路径。每抽完一组即编译+测试+提交。分支 `feat/comfy-cloud-adapter`。
|
|
|
|
> **验证基线(开工前先记录):** 跑 `cargo test -p boosapi --lib routes::workflow_ui 2>&1 | grep "test result"` 记下当前测试数(应 5 个),全程不得减少。
|
|
|
|
---
|
|
|
|
## 文件结构(目标)
|
|
|
|
```
|
|
src/routes/workflow_ui/
|
|
mod.rs — routes() + 共享类型(WorkflowCaller/各 Query/Payload struct)+ 跨模块小工具 + 子模块声明 + 测试入口
|
|
assets.rs — UI 静态资源服务/嵌入目录/index/static/serve_file/官方模板资源
|
|
auth.rs — caller 解析
|
|
node_defs.rs — 节点定义 + 工作流模板图
|
|
models.rs — 模型分类 + folder 模型
|
|
comfy_proxy.rs — ComfyUI API 代理 handler(settings/userdata/object_info/...)
|
|
validate.rs — 工作流校验
|
|
queue.rs — 队列/历史/prompt/view
|
|
```
|
|
|
|
> 当前 `src/routes/workflow_ui.rs`(单文件)→ 变为 `src/routes/workflow_ui/mod.rs` + 7 个兄弟文件。
|
|
> `src/routes/mod.rs` 的 `mod workflow_ui;` 声明无需改(目录模块同名,Rust 自动找 mod.rs)。
|
|
|
|
---
|
|
|
|
<!-- TASKS -->
|
|
|
|
## Task 0: 文件转目录模块(零拆分,先搭壳)
|
|
|
|
**Files:**
|
|
- Move: `src/routes/workflow_ui.rs` → `src/routes/workflow_ui/mod.rs`
|
|
|
|
- [ ] **Step 1: 记录验证基线**
|
|
|
|
Run: `cd /root/metapi && cargo test -p boosapi --lib routes::workflow_ui 2>&1 | grep "test result"`
|
|
Expected: 记下测试数(预期 `5 passed`)。后续每步此数不得减少。
|
|
|
|
- [ ] **Step 2: 把文件移成目录模块**
|
|
|
|
```bash
|
|
cd /root/metapi
|
|
mkdir -p src/routes/workflow_ui
|
|
git mv src/routes/workflow_ui.rs src/routes/workflow_ui/mod.rs
|
|
```
|
|
|
|
- [ ] **Step 3: 编译 + 测试验证(内容没动,应原样通过)**
|
|
|
|
Run: `cd /root/metapi && cargo build -j 2 2>&1 | tail -3 && cargo test -p boosapi --lib routes::workflow_ui 2>&1 | grep "test result"`
|
|
Expected: `Finished`;测试数与基线一致。
|
|
|
|
- [ ] **Step 4: Commit**
|
|
|
|
```bash
|
|
cd /root/metapi && git add src/routes/workflow_ui.rs src/routes/workflow_ui/mod.rs
|
|
git commit -m "refactor(workflow_ui): 文件转目录模块(mod.rs,内容不变)
|
|
|
|
Co-Authored-By: Claude <noreply@anthropic.com>"
|
|
```
|
|
|
|
<!-- T1 -->
|
|
|
|
## Task 1: 抽 auth.rs(最小、最低风险,先验证流程)
|
|
|
|
**Files:**
|
|
- Create: `src/routes/workflow_ui/auth.rs`
|
|
- Modify: `src/routes/workflow_ui/mod.rs`
|
|
|
|
要搬的函数(用 grep 定位,函数体一字不改):`caller_from_headers`、`auth_caller`、`caller_user_id`、`caller_is_admin`。它们依赖类型 `WorkflowCaller`(留在 mod.rs)。
|
|
|
|
- [ ] **Step 1: 在 mod.rs 顶部加子模块声明**
|
|
|
|
在 mod.rs 的 `use` 区之后(`pub fn routes()` 之前)加:
|
|
```rust
|
|
mod auth;
|
|
```
|
|
|
|
- [ ] **Step 2: 确认这 4 个函数的精确范围 + WorkflowCaller 可见性**
|
|
|
|
Run: `cd /root/metapi && rtk proxy grep -nE "fn caller_from_headers|fn auth_caller|fn caller_user_id|fn caller_is_admin|enum WorkflowCaller" src/routes/workflow_ui/mod.rs`
|
|
记录每个函数起止行。`WorkflowCaller` 留 mod.rs,改成 `pub(super) enum WorkflowCaller`(让子模块可用)。
|
|
|
|
- [ ] **Step 3: 新建 auth.rs,粘入 4 个函数(函数体不改,补 use + 改可见性)**
|
|
|
|
新建 `src/routes/workflow_ui/auth.rs`,结构:
|
|
```rust
|
|
use super::WorkflowCaller;
|
|
use crate::error::AppResult;
|
|
use crate::AppState;
|
|
use axum::http::HeaderMap;
|
|
// (按 4 个函数实际用到的依赖补齐 use:validate_jwt、find_downstream_key_by_token 等——
|
|
// 从 mod.rs 顶部现有 use 里照抄它们需要的那几条)
|
|
|
|
pub(super) fn caller_from_headers(state: &AppState, headers: &HeaderMap) -> AppResult<WorkflowCaller> {
|
|
// ←原函数体一字不改粘进来
|
|
}
|
|
pub(super) fn caller_user_id(caller: &WorkflowCaller) -> Option<i64> {
|
|
// ←原体
|
|
}
|
|
pub(super) fn caller_is_admin(caller: &WorkflowCaller) -> bool {
|
|
// ←原体
|
|
}
|
|
pub(super) async fn auth_caller(state: &AppState, headers: &HeaderMap) -> AppResult<WorkflowCaller> {
|
|
// ←原体
|
|
}
|
|
```
|
|
> 关键:这 4 个函数从 mod.rs **删除**;其在 mod.rs/其他子模块的调用点改成 `auth::caller_from_headers(...)` 等(mod.rs 内加 `use auth::{caller_from_headers, auth_caller, caller_user_id, caller_is_admin};` 即可不改调用点写法)。
|
|
|
|
- [ ] **Step 4: mod.rs 加 use 引回,删除原 4 函数**
|
|
|
|
mod.rs 顶部子模块声明后加:
|
|
```rust
|
|
use auth::{auth_caller, caller_from_headers, caller_is_admin, caller_user_id};
|
|
```
|
|
并从 mod.rs 删掉这 4 个函数的原定义。
|
|
|
|
- [ ] **Step 5: 编译 + 测试**
|
|
|
|
Run: `cd /root/metapi && cargo build -j 2 2>&1 | tail -3 && cargo test -p boosapi --lib routes::workflow_ui 2>&1 | grep "test result"`
|
|
Expected: `Finished`;测试数 == 基线。若编译报「未使用的 use」「私有」「未解析」,按提示补 use / 调可见性(纯机械修),不改逻辑。
|
|
|
|
- [ ] **Step 6: Commit**
|
|
|
|
```bash
|
|
cd /root/metapi && git add src/routes/workflow_ui/mod.rs src/routes/workflow_ui/auth.rs
|
|
git commit -m "refactor(workflow_ui): 抽出 auth 子模块
|
|
|
|
Co-Authored-By: Claude <noreply@anthropic.com>"
|
|
```
|
|
|
|
<!-- T2 -->
|
|
|
|
## 通用抽取流程(每个子模块任务都按这 6 步)
|
|
|
|
每个抽取任务对一组函数执行:
|
|
1. mod.rs 顶部加 `mod <name>;` 声明。
|
|
2. grep 定位本组函数精确范围;凡被本组函数引用、但定义留在别处的类型/函数,把那些定义改 `pub(super)`。
|
|
3. 新建 `<name>.rs`,粘入本组函数(**函数体一字不改**),顶部按实际依赖补 `use`(从 mod.rs 现有 use 照抄需要的;跨模块的用 `use super::...` 或 `use super::<other_mod>::...`),函数可见性改 `pub(super)`。
|
|
4. 从 mod.rs 删掉这些函数原定义;mod.rs 顶部加 `use <name>::{...};` 把它们引回(调用点写法不变)。
|
|
5. `cargo build -j 2` + `cargo test -p boosapi --lib routes::workflow_ui`。编译报错按提示机械修(补 use / 调可见性),不改逻辑。测试数不得低于基线。
|
|
6. 提交:`git add src/routes/workflow_ui/mod.rs src/routes/workflow_ui/<name>.rs && git commit -m "refactor(workflow_ui): 抽出 <name> 子模块"`(带 Co-Authored-By)。
|
|
|
|
> 注:若某函数同时被多个子模块用,保留在 mod.rs 顶层并 `pub(super)`,各子模块 `use super::该函数`。
|
|
> 共用小工具(guess_mime_from_path / parse_boolish / safe_view_path / user_home / default_history_limit
|
|
> / workspace_kind_from_mime)统一留 mod.rs 顶层 `pub(super)`,不下沉到子模块。
|
|
|
|
## Task 2: 抽 node_defs.rs(节点定义 + 工作流模板图)
|
|
|
|
**Files:** Create `src/routes/workflow_ui/node_defs.rs`;Modify `src/routes/workflow_ui/mod.rs`
|
|
|
|
要搬的函数(grep 定位):`known_output_ports`、`core_node_definitions`、`workflow_template_payload`、`core_workflow_template_index`、`inject_boosapi_workflow_template_payload`、`default_boosapi_workflow_graph`、`text_to_video_workflow_graph`、`port_name`、`source_node_type`、`normalize_prompt_payload`、`prompt_link`、`node_type_def_to_comfy`、`input_spec_to_comfy`、`output_specs`、`output_is_list_specs`。
|
|
|
|
- [ ] **Step 1-6: 按「通用抽取流程」执行**,`<name>` = `node_defs`。
|
|
注意:这些函数用到 `WorkflowGraph` / `NodeTypeDefinition` 类型——确认它们的定义位置(可能在 crate::workflow 或 mod.rs),mod.rs 内的留存定义改 `pub(super)`,node_defs.rs 用 `use super::...` 或 `use crate::...` 引入。
|
|
验证命令:`cd /root/metapi && cargo build -j 2 2>&1 | tail -3 && cargo test -p boosapi --lib routes::workflow_ui 2>&1 | grep "test result"`,期望 Finished + 测试数≥基线。
|
|
提交 message:`refactor(workflow_ui): 抽出 node_defs 子模块`。
|
|
|
|
<!-- T3 -->
|
|
|
|
## Task 3: 抽 models.rs(模型分类 + folder 模型)
|
|
|
|
**Files:** Create `src/routes/workflow_ui/models.rs`;Modify `src/routes/workflow_ui/mod.rs`
|
|
|
|
要搬的函数:`is_exact_workflow_model`、`is_image_workflow_model`、`is_video_workflow_model`、`is_audio_workflow_model`、`is_embedding_workflow_model`、`is_3d_workflow_model`、`is_vision_workflow_model`、`is_chat_workflow_model`、`workflow_route_models`、`image_model_choices`、`workflow_folder_models`、`workflow_folder_is_api_only`、`workflow_folder_has_route_models`、`workflow_folder_route_model_items`、`combo_choices_from_node_input`、`combo_fields_from_node`、`native_folder_models_from_object_info`。
|
|
|
|
- [ ] **Step 1-6: 按「通用抽取流程」执行**,`<name>` = `models`。
|
|
注意:`workflow_route_models` 是 `async fn` 且用 `state.db`,补 `use crate::AppState;` 等。
|
|
验证命令同上,提交 message:`refactor(workflow_ui): 抽出 models 子模块`。
|
|
|
|
<!-- T4 -->
|
|
|
|
## Task 4: 抽 assets.rs(UI 静态资源服务)
|
|
|
|
**Files:** Create `src/routes/workflow_ui/assets.rs`;Modify `src/routes/workflow_ui/mod.rs`
|
|
|
|
要搬的函数:`workflow_ui_root_for_config`、`resolve_workflow_ui_dir`、`embedded_workflow_ui_for_config`、`workflow_ui_dir_is_usable`、`embedded_workflow_ui_is_usable`、`workflow_ui_index_is_placeholder`、`workflow_ui_runtime`、`workflow_ui_build_metadata`、`workflow_cloud_api_key`、`workflow_ui_index`、`workflow_ui_static`、`official_workflow_template_asset`、`serve_file`。
|
|
|
|
- [ ] **Step 1-6: 按「通用抽取流程」执行**,`<name>` = `assets`。
|
|
注意:用到 `include_dir::Dir`、`PathBuf`、`Html`、`Response` 等,按实际补 use。`serve_file` 若被 queue/view 模块也用到,则保留 mod.rs 顶层 `pub(super)`(实现时看引用)。
|
|
验证命令同上,提交 message:`refactor(workflow_ui): 抽出 assets 子模块`。
|
|
|
|
<!-- T5 -->
|
|
|
|
## Task 5: 抽 comfy_proxy.rs(ComfyUI API 代理 handler)
|
|
|
|
**Files:** Create `src/routes/workflow_ui/comfy_proxy.rs`;Modify `src/routes/workflow_ui/mod.rs`
|
|
|
|
要搬的函数:`get_user_config`、`create_user`、`get_settings`、`get_setting`、`store_settings`、`store_setting`、`userdata_list`、`userdata_get`、`userdata_store`、`userdata_delete`、`move_userdata`、`extensions`、`workflow_templates`、`embeddings`、`object_info`、`system_stats`。
|
|
|
|
- [ ] **Step 1-6: 按「通用抽取流程」执行**,`<name>` = `comfy_proxy`。
|
|
注意:这些是路由 handler(多 `async fn ...(State, HeaderMap) -> AppResult<...>`),依赖 `auth_caller`(已在 auth.rs)→ 用 `use super::auth_caller;` 或 `super::auth::auth_caller`。补 axum extract / Json / Response use。
|
|
验证命令同上,提交 message:`refactor(workflow_ui): 抽出 comfy_proxy 子模块`。
|
|
|
|
<!-- T6 -->
|
|
|
|
## Task 6: 抽 validate.rs(工作流校验)
|
|
|
|
**Files:** Create `src/routes/workflow_ui/validate.rs`;Modify `src/routes/workflow_ui/mod.rs`
|
|
|
|
要搬的函数:`validate_workflow`、`validate_workflow_against_object_info`、`validate_workflow_input_file`。
|
|
|
|
- [ ] **Step 1-6: 按「通用抽取流程」执行**,`<name>` = `validate`。
|
|
注意:依赖 node_defs/models 的函数(如 normalize_prompt_payload、combo_fields_from_node)→ 用 `use super::node_defs::...` / `use super::models::...`(确保那些函数已 `pub(super)`)。WorkflowValidateQuery struct 留 mod.rs `pub(super)`。
|
|
验证命令同上,提交 message:`refactor(workflow_ui): 抽出 validate 子模块`。
|
|
|
|
<!-- T7 -->
|
|
|
|
## Task 7: 抽 queue.rs(队列/历史/prompt/view)+ 收尾
|
|
|
|
**Files:** Create `src/routes/workflow_ui/queue.rs`;Modify `src/routes/workflow_ui/mod.rs`
|
|
|
|
要搬的函数:`queue_status`、`queue`、`queue_mutate`、`history`、`history_mutate`、`history_by_id`、`queue_prompt`、`repair_native_prompt_payload`、`queue_boosapi_prompt`、`interrupt`、`view`、`internal_logs`、`internal_logs_raw`。
|
|
|
|
- [ ] **Step 1-6: 按「通用抽取流程」执行**,`<name>` = `queue`。
|
|
注意:`repair_native_prompt_payload` 很长(2814-3474),依赖 node_defs/models 多个函数;`view` 用 serve_file/safe_view_path。补 `use super::...`。PromptPayload/HistoryQuery/ViewQuery/QueueMutation/UserDataQuery/UploadQuery struct 留 mod.rs `pub(super)`(被多模块用)。
|
|
验证命令同上,提交 message:`refactor(workflow_ui): 抽出 queue 子模块`。
|
|
|
|
- [ ] **Step 7: 最终验收**
|
|
|
|
Run:
|
|
```bash
|
|
cd /root/metapi
|
|
cargo build -j 2 2>&1 | tail -3
|
|
cargo test -p boosapi --lib routes::workflow_ui 2>&1 | grep "test result"
|
|
for f in mod auth node_defs models assets comfy_proxy validate queue; do echo -n "$f.rs: "; wc -l < src/routes/workflow_ui/$f.rs; done
|
|
```
|
|
Expected: Finished;测试数≥基线;每个子文件行数显著小于原 6181(mod.rs 应只剩 routes()+共享类型+小工具,目标 <1500 行;无单文件超 ~2000)。
|
|
|
|
- [ ] **Step 8: 冒烟(手动)**
|
|
|
|
部署后打开工作流 UI、跑一个 prompt,确认行为与拆分前一致(路由路径、handler 行为不变)。
|
|
|
|
<!-- END -->
|
|
|
|
|