From c480ec173ad3545c4183860d559d37b6a48bf354 Mon Sep 17 00:00:00 2001 From: xiaocheny214 <187097481+xiaocheny214@users.noreply.github.com> Date: Fri, 31 Jul 2026 12:22:12 +0800 Subject: [PATCH] refactor(domain): rename generation to orchestrator, add domain boundary docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename server/generation/ to server/orchestrator/ (任务调度) - Update all import references (web/api/generation.py keeps its name) - Update module-split.md with 4-domain structure (foundation/workflow/pipeline/result) - Add domain boundary explanations and rationale - Update product-domains.svg with color coding and domain annotations - Remove unimplemented modules from documentation --- backend/docs/diagrams/product-domains.json | 270 ++++++++++++++++++ backend/docs/diagrams/product-domains.svg | 171 +++++++++++ backend/docs/module-split.md | 205 +++++++++++++ .../{generation => orchestrator}/__init__.py | 2 +- .../{generation => orchestrator}/interface.py | 2 +- .../{generation => orchestrator}/model.py | 0 .../app/src/windup_app/web/api/generation.py | 2 +- 7 files changed, 649 insertions(+), 3 deletions(-) create mode 100644 backend/docs/diagrams/product-domains.json create mode 100644 backend/docs/diagrams/product-domains.svg create mode 100644 backend/docs/module-split.md rename backend/packages/app/src/windup_app/server/{generation => orchestrator}/__init__.py (89%) rename backend/packages/app/src/windup_app/server/{generation => orchestrator}/interface.py (97%) rename backend/packages/app/src/windup_app/server/{generation => orchestrator}/model.py (100%) diff --git a/backend/docs/diagrams/product-domains.json b/backend/docs/diagrams/product-domains.json new file mode 100644 index 0000000..4f246ef --- /dev/null +++ b/backend/docs/diagrams/product-domains.json @@ -0,0 +1,270 @@ +{ + "schema_version": 1, + "mode": "architecture", + "template_type": "architecture", + "style": 1, + "quality_profile": "standard", + "width": 1200, + "height": 760, + "title": "Windup Product Domains", + "subtitle": "最终产品业务能力与核心依赖", + "containers": [ + { + "id": "foundation-domains", + "x": 40, + "y": 120, + "width": 1120, + "height": 120, + "label": "Foundation Domains", + "stroke": "#b9c6d8", + "fill": "#f4f8fc" + }, + { + "id": "workflow-domains", + "x": 40, + "y": 290, + "width": 700, + "height": 150, + "label": "Workflow Domains", + "stroke": "#c9b8d9", + "fill": "#faf5fc" + }, + { + "id": "ai-engine-domain", + "x": 780, + "y": 290, + "width": 380, + "height": 150, + "label": "AI Engine Domain", + "stroke": "#89c4a8", + "fill": "#f0f9f4" + }, + { + "id": "result-domains", + "x": 40, + "y": 490, + "width": 1120, + "height": 120, + "label": "Result Domains", + "stroke": "#b8d0c2", + "fill": "#f5fbf7" + } + ], + "nodes": [ + { + "id": "user", + "kind": "rect", + "x": 80, + "y": 155, + "width": 150, + "height": 55, + "label": "user", + "sublabel": "身份与会话", + "fill": "#e8f0fb", + "stroke": "#6685b2" + }, + { + "id": "quota", + "kind": "rect", + "x": 270, + "y": 155, + "width": 150, + "height": 55, + "label": "quota", + "sublabel": "订阅与积分", + "fill": "#fff2d9", + "stroke": "#c28a36" + }, + { + "id": "project", + "kind": "double_rect", + "x": 460, + "y": 155, + "width": 170, + "height": 55, + "label": "project", + "sublabel": "全局约束容器", + "fill": "#e8f0fb", + "stroke": "#6685b2" + }, + { + "id": "media", + "kind": "rect", + "x": 670, + "y": 155, + "width": 150, + "height": 55, + "label": "media", + "sublabel": "输入参考素材", + "fill": "#e8f0fb", + "stroke": "#6685b2" + }, + { + "id": "character", + "kind": "rect", + "x": 860, + "y": 155, + "width": 180, + "height": 55, + "label": "character / asset", + "sublabel": "角色与产物", + "fill": "#e8f0fb", + "stroke": "#6685b2" + }, + { + "id": "workflow", + "kind": "double_rect", + "x": 80, + "y": 330, + "width": 180, + "height": 70, + "label": "workflow", + "sublabel": "定义 / 节点 / 模板", + "fill": "#f2e9f8", + "stroke": "#89659e" + }, + { + "id": "execution", + "kind": "rect", + "x": 320, + "y": 330, + "width": 180, + "height": 70, + "label": "execution", + "sublabel": "调度 / 重试 / 缓存", + "fill": "#f2e9f8", + "stroke": "#89659e" + }, + { + "id": "generation", + "kind": "rect", + "x": 560, + "y": 330, + "width": 180, + "height": 70, + "label": "generation", + "sublabel": "生成业务编排", + "fill": "#fff2d9", + "stroke": "#c28a36" + }, + { + "id": "ai-engine", + "kind": "rect", + "x": 880, + "y": 330, + "width": 180, + "height": 70, + "label": "ai_engine", + "sublabel": "模型能力适配", + "fill": "#e4f2ea", + "stroke": "#5c9974" + }, + { + "id": "review", + "kind": "rect", + "x": 230, + "y": 525, + "width": 180, + "height": 55, + "label": "review", + "sublabel": "质检 + 人工审核", + "fill": "#e4f2ea", + "stroke": "#5c9974" + }, + { + "id": "playtest", + "kind": "rect", + "x": 510, + "y": 525, + "width": 180, + "height": 55, + "label": "playtest", + "sublabel": "预览与试玩", + "fill": "#e4f2ea", + "stroke": "#5c9974" + }, + { + "id": "export", + "kind": "rect", + "x": 790, + "y": 525, + "width": 180, + "height": 55, + "label": "export", + "sublabel": "格式转换与下载", + "fill": "#e4f2ea", + "stroke": "#5c9974" + } + ], + "arrows": [ + { + "id": "workflow-execution", + "source": "workflow", + "target": "execution", + "source_port": "right", + "target_port": "left", + "flow": "control", + "label": "定义", + "label_style": "offset" + }, + { + "id": "execution-generation", + "source": "execution", + "target": "generation", + "source_port": "right", + "target_port": "left", + "flow": "control", + "label": "节点调用", + "label_style": "offset" + }, + { + "id": "generation-ai", + "source": "generation", + "target": "ai-engine", + "source_port": "right", + "target_port": "left", + "flow": "control", + "label": "AI 能力", + "label_style": "offset" + }, + { + "id": "review-playtest", + "source": "review", + "target": "playtest", + "source_port": "right", + "target_port": "left", + "flow": "read", + "label": "正式资产", + "label_style": "offset" + }, + { + "id": "playtest-export", + "source": "playtest", + "target": "export", + "source_port": "right", + "target_port": "left", + "flow": "read", + "label": "导出数据", + "label_style": "offset" + } + ], + "legend_orientation": "horizontal", + "legend_x": 70, + "legend_y": 680, + "legend_locked": false, + "legend": [ + { + "flow": "control", + "label": "业务编排" + }, + { + "flow": "read", + "label": "读取 / 消费" + }, + { + "flow": "write", + "label": "产物 / 输入流" + } + ], + "footer": "Windup · Final Product Domain Map" +} diff --git a/backend/docs/diagrams/product-domains.svg b/backend/docs/diagrams/product-domains.svg new file mode 100644 index 0000000..b6872d8 --- /dev/null +++ b/backend/docs/diagrams/product-domains.svg @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Windup Product Domains + 最终产品业务能力与核心依赖 + + + FOUNDATION DOMAINS + 基础业务域:管理基础数据,被其他域消费 + + + + + WORKFLOW DOMAINS + 工作流域:任务调度与编排 + + + + + PIPELINE DOMAIN + 生成管线:提示词→出图→抠图→截帧 + + + + + RESULT DOMAINS + 结果域:处理生成产物(审核/预览/导出) + + + + + + + + + + user + 身份与会话 + + + + quota + 订阅与积分 + + + + + project + 全局约束容器 + + + + media + 输入参考素材 + + + + character / asset + 角色与产物 + + + + + workflow + 定义 / 节点 / 模板 + + + + execution + 调度 / 重试 / 缓存 + + + + orchestrator + 生成任务调度 + + + + ai_engine + 生成管线 + + + + review + 质检 + 人工审核 + + + + preview + 预览台 + + + + export + 格式转换与下载 + + + 定义 + + + 节点调用 + + + 调用管线 + + + 正式资产 + + + 导出数据 + + + + + 业务编排 + + 读取 / 消费 + + MVP 已实现 + + 部分实现 + + 待实现 + + + Windup · Final Product Domain Map + + diff --git a/backend/docs/module-split.md b/backend/docs/module-split.md new file mode 100644 index 0000000..956c7e0 --- /dev/null +++ b/backend/docs/module-split.md @@ -0,0 +1,205 @@ +# 后端模块拆分 + +> 当前阶段:MVP 已实现 project / media / character / orchestrator / ai_engine。 +> 按业务域拆分,每个域是一个完整的业务能力单元。 + +--- + +## 项目层级 + +``` +backend/ +├── packages/ +│ ├── common/ # 共享:Response、BizException、BizCode 枚举 +│ ├── framework/ # 基础设施:KodoStorage、ChatProvider、DB 配置 +│ ├── ai_engine/ # 生成管线(独立包) +│ └── app/ # 业务应用 +│ └── src/windup_app/ +│ ├── web/api/ # FastAPI 路由 +│ │ ├── generation.py # 生成 API(前端契约) +│ │ ├── media.py # 媒体 API +│ │ ├── project.py # 项目 API +│ │ └── character.py # 角色 API +│ ├── bootstrap/app.py # 组装入口(composition root) +│ └── server/ # 业务域(按域分组) +│ ├── media/ # [foundation] 用户素材上传 +│ ├── project/ # [foundation] 项目约束配置 +│ ├── character/ # [foundation] 角色资产数据 +│ └── orchestrator/ # [workflow] 生成任务调度 +``` + +> 注:`[foundation]` / `[workflow]` 标注所属业务域。 +> `ai_engine` 是独立包,不属于 server/ 目录。 + +--- + +## 业务域全景 + +![Windup 最终产品业务域图](diagrams/product-domains.svg) + +--- + +## 依赖方向 + +``` + common + ▲ + framework + ▲ + ┌──────┴──────┐ +ai_engine foundation + ▲ ▲ ▲ + │ ┌────┘ │ + │ workflow result + │ │ │ + └─────┘─────────┘ +``` + +**规则**: +- foundation → framework, common +- workflow → foundation, ai_engine, framework, common +- result → foundation, framework, common +- ai_engine → framework.providers(接口), common +- **禁止**:foundation → workflow / result / ai_engine +- **禁止**:ai_engine → foundation / workflow / result +- **禁止**:result → workflow + +--- + +## 域边界划分 + +### 为什么按这四个域拆分? + +每个域回答一个业务问题: + +| 域 | 回答的问题 | 包含什么 | +|---|---|---| +| foundation | 数据从哪来、存到哪 | 项目配置、角色数据、用户素材 | +| workflow | 何时生、为谁生、生完怎么办 | 任务调度、工作流编排 | +| pipeline | 怎么生 | 提示词 → 出图 → 抠图 → 截帧 | +| result | 生出来的东西怎么用 | 审核、预览、导出 | + +### 边界职责 + +**foundation(基础业务域)** +- 职责:管理基础数据,被其他域消费 +- 边界:各模块独立 CRUD,不包含生成、审核、导出逻辑 +- 禁止:依赖 workflow / result / ai_engine + +**workflow(工作流域)** +- 职责:编排调度,调用 foundation + ai_engine +- 边界:任务管理、约束加载、积分扣减、结果上传 +- 禁止:依赖 result 域;直接 import ai_engine 内部实现 + +**pipeline(生成管线域)** +- 职责:实际生成过程(提示词 → 出图 → 抠图 → 截帧) +- 边界:AI 调用、帧处理、像素化 +- 禁止:知道 project 约束、character 数据结构、图片存储位置 + +**result(结果域)** +- 职责:处理生成产物,提供预览和导出 +- 边界:读取正式资产,独立演进 +- 禁止:依赖 workflow 域;调用 ai_engine + +--- + +## 基础业务域(Foundation) + +### media — 用户素材上传 + +**对应表:** `windup_media` **接口:** `MediaService` + +| 方法 | 说明 | +|---|---| +| `upload(data, metadata)` | 上传文件到对象存储,返回 URL | + +**文件分类 `MediaCategory`**:`reference-image` / `outfit-preview` / `action-frame` / `general` + +### project — 项目约束配置 + +**对应表:** `windup_project` **接口:** `ProjectService` + +| 字段 | 用途 | +|---|---| +| `character_perspective` | 视角 → 生成朝向 | +| `directional_movement` | 方向数 → 生成方向变体 | +| `sprite_width` / `sprite_height` | 尺寸 → 输出帧大小 | +| `game_style` | 画风 → 提示词风格 | +| `sprite_sample_url` | 风格参考图 → 图生图模式 | + +| 方法 | 说明 | +|---|---| +| `create_project(project)` | 创建项目 | +| `get_project(id)` | 按 ID 查询 | +| `list_projects(page, page_size, user_id)` | 分页查询 | +| `delete_project(id)` | 删除 | + +### character — 角色资产数据 + +**对应表:** `windup_character` **接口:** `CharacterService` + +`character_data` JSONB 三层嵌套:outfit → action → frame + +| 方法 | 说明 | +|---|---| +| `create_character(session, **fields)` | 创建角色 | +| `get_character(session, character_id)` | 按 ID 查询 | +| `list_characters(session, *, project_id, page, page_size)` | 分页查询 | +| `update_character(session, character_id, **fields)` | 更新角色 | +| `delete_character(session, character_id)` | 删除角色(含媒体清理) | + +--- + +## 工作流域(Workflow) + +### orchestrator — 生成任务调度 + +**对应表:** `windup_generation_task` **接口:** `GenerationService` + +管理生成任务生命周期:创建任务 → 加载项目约束 → 调 ai_engine → 上传结果 → 回写状态。 + +| 方法 | 说明 | +|---|---| +| `generate_character_image(input)` | 提交角色图片生成任务 | +| `generate_character_action(input)` | 提交角色动作生成任务 | +| `get_task(project_id, task_id)` | 查询任务状态与结果 | + +--- + +## 生成管线域(Pipeline) + +### ai_engine — 生成管线 + +**接口:** `CharacterGeneratorPort` + +生成管线:提示词 → 出图 → 抠图 → 截帧 → 返回产物。 + +| 组件 | 职责 | +|---|---| +| `strategy/` | 策略分发(VIDEO_I2V / PER_FRAME / PROC_IDLE) | +| `prompt/` | 提示词构建(walk / jump / attack) | +| `slicing/` | 帧提取(imageio/pyav) | +| `postprocess/` | 像素化、脚线对齐、sprite sheet 打包 | +| `master_prep.py` | 母版预处理 | + +--- + +## 结果域(Result) + +| 模块 | 状态 | 职责 | +|---|---|---| +| review | 🟡 前端页面体现 | 质检 + 人工审核 | +| preview | 🟡 前端页面体现 | 预览台:组装可播放数据(帧 + 帧率 + 循环) | +| export | ⬜ 待实现 | GIF / 精灵图 / 引擎格式转换 | + +--- + +## MVP 已实现模块 + +| 模块 | 域 | 数据表 | API | +|---|---|---|---| +| media | foundation | windup_media | POST /media/upload | +| project | foundation | windup_project | POST/GET/DELETE /projects | +| character | foundation | windup_character | POST/GET/PATCH/DELETE /characters | +| orchestrator | workflow | windup_generation_task | POST /generation/image, POST /generation/action, GET /generation/tasks/{id} | +| ai_engine | pipeline | (无独立表) | (内部调用,不暴露 API) | diff --git a/backend/packages/app/src/windup_app/server/generation/__init__.py b/backend/packages/app/src/windup_app/server/orchestrator/__init__.py similarity index 89% rename from backend/packages/app/src/windup_app/server/generation/__init__.py rename to backend/packages/app/src/windup_app/server/orchestrator/__init__.py index a6701de..c21a7b8 100644 --- a/backend/packages/app/src/windup_app/server/generation/__init__.py +++ b/backend/packages/app/src/windup_app/server/orchestrator/__init__.py @@ -1,6 +1,6 @@ """生成任务领域。""" -from windup_app.server.generation.model import ( +from windup_app.server.orchestrator.model import ( ActionType, CharacterActionFrame, CharacterActionInput, diff --git a/backend/packages/app/src/windup_app/server/generation/interface.py b/backend/packages/app/src/windup_app/server/orchestrator/interface.py similarity index 97% rename from backend/packages/app/src/windup_app/server/generation/interface.py rename to backend/packages/app/src/windup_app/server/orchestrator/interface.py index b43bace..83e38aa 100644 --- a/backend/packages/app/src/windup_app/server/generation/interface.py +++ b/backend/packages/app/src/windup_app/server/orchestrator/interface.py @@ -22,7 +22,7 @@ from abc import ABC, abstractmethod -from windup_app.server.generation.model import ( +from windup_app.server.orchestrator.model import ( CharacterActionInput, CharacterImageInput, GenerationTask, diff --git a/backend/packages/app/src/windup_app/server/generation/model.py b/backend/packages/app/src/windup_app/server/orchestrator/model.py similarity index 100% rename from backend/packages/app/src/windup_app/server/generation/model.py rename to backend/packages/app/src/windup_app/server/orchestrator/model.py diff --git a/backend/packages/app/src/windup_app/web/api/generation.py b/backend/packages/app/src/windup_app/web/api/generation.py index be3a5e9..872c1c0 100644 --- a/backend/packages/app/src/windup_app/web/api/generation.py +++ b/backend/packages/app/src/windup_app/web/api/generation.py @@ -16,7 +16,7 @@ from windup_common.result import Response from windup_framework.db import get_session -from windup_app.server.generation.model import ( +from windup_app.server.orchestrator.model import ( ActionType, GenerationTask, )