Files
BoosAPI/docs/superpowers/plans/2026-06-18-workflow-ui-split.md
T
boos 60ecd8a13c docs: workflow_ui.rs 拆分实现计划(Task0转目录 + 7子模块抽取)
每任务抽1组函数(纯搬运)+cargo编译+测试验证+独立提交。通用6步流程统一。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 13:52:26 +08:00

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 步)

每个抽取任务对一组函数执行:

  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 子模块。

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.rs pub(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.rs pub(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 行为不变)。