每任务抽1组函数(纯搬运)+cargo编译+测试验证+独立提交。通用6步流程统一。 Co-Authored-By: Claude <noreply@anthropic.com>
13 KiB
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)。
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: 把文件移成目录模块
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
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>"
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() 之前)加:
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,结构:
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 顶部子模块声明后加:
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
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>"
通用抽取流程(每个子模块任务都按这 6 步)
每个抽取任务对一组函数执行:
- mod.rs 顶部加
mod <name>;声明。 - grep 定位本组函数精确范围;凡被本组函数引用、但定义留在别处的类型/函数,把那些定义改
pub(super)。 - 新建
<name>.rs,粘入本组函数(函数体一字不改),顶部按实际依赖补use(从 mod.rs 现有 use 照抄需要的;跨模块的用use super::...或use super::<other_mod>::...),函数可见性改pub(super)。 - 从 mod.rs 删掉这些函数原定义;mod.rs 顶部加
use <name>::{...};把它们引回(调用点写法不变)。 cargo build -j 2+cargo test -p boosapi --lib routes::workflow_ui。编译报错按提示机械修(补 use / 调可见性),不改逻辑。测试数不得低于基线。- 提交:
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 子模块。
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 子模块。
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 子模块。
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 子模块。
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.rspub(super)。 验证命令同上,提交 message:refactor(workflow_ui): 抽出 validate 子模块。
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.rspub(super)(被多模块用)。 验证命令同上,提交 message:refactor(workflow_ui): 抽出 queue 子模块。 -
Step 7: 最终验收
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"
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 行为不变)。