Files
MiragenFlow/develop.md
T

73 KiB
Raw Blame History

MiragenFlow 一期开发规划

本文是产品、前台、后台和服务端网关的一期设计基线。实现按本文分阶段落地,未完成部分必须在验收记录中明确,不得用演示数据冒充完成。

参考产品:https://holopix.cn/。参考重点是它的功能理念和工作流组织方式,不复制其品牌、文案、素材或内部实现。

0. 一期目标与已知约束

0.1 一期目标

把 MiragenFlow 从“浏览器直连模型的本地画布工具”升级为一个具备完整商业化基础链路的 AI 游戏美术创作产品:

注册/登录
  -> 获取公开模型产品目录
  -> 选择模型档位、分辨率和创作参数
  -> 提交图片/文本/音频/图片工具任务
  -> 服务端鉴权、校验、预扣余额
  -> 按模型产品绑定的渠道分组顺序路由
  -> 单渠道失败自动切换后续渠道
  -> 返回任务进度和结果
  -> 成功扣除实际消耗,失败释放预扣余额
  -> 结果进入画布、资产库和历史记录

0.2 本文直接采用的设计原则

  1. 前台用户只看到产品能力,不看到供应商内部信息。 用户看到“基础模型 / 高级模型 / 旗舰模型”和后台配置的分辨率、数量、价格,不直接看到供应商 API Key、渠道地址或原始 provider model ID。
  2. 模型产品和供应商渠道解耦。 用户选择的是 modelProduct,后台把它绑定到一个有顺序的 channelGroup;组内可以放多个供应商账号和多个内部模型 ID。
  3. 组内按顺序故障切换。 第一个渠道超时、限流、网关错误或被管理员禁用时,自动尝试下一个渠道;不会因为单个供应商故障直接中断用户任务。
  4. 不做静默降档。 一个旗舰模型组全部不可用时,任务明确失败并建议用户切换到其他旗舰模型;除非管理员显式配置,不自动把旗舰请求降级为高级或基础模型。
  5. 余额制计费。 充值增加余额,任务按公开价格和当前余额单位扣减;所有扣款、预扣、释放、退款均进入不可变账本。
  6. 现有 OpenAI 图片协议优先迁移。 无限画布项目已有的图片生成、图片编辑、响应解析和错误归一化逻辑迁移到服务端网关/供应商适配层,前台不再保存外部 API Key 并直连供应商。
  7. WebDAV 继续保留。 它用于用户保存画布、资产和生成文件;一期不把 WebDAV 误写成平台自带云盘,也不强制把全部大图永久存放在平台服务器。
  8. 视频和动画先不开发。 Holopix 的视频、首尾帧、图生视频、文生视频和动画能力作为参考差距记录,但不进入当前一期开发清单。音频生成保留。
  9. V1 认证增强可配置。 不接第三方登录;用户邮箱/手机号验证、图形验证码或等价人机校验、登录风控和两步验证都保留为可配置能力,普通用户默认关闭,后台开启后才生效。管理员保持独立认证域,邮箱+密码为默认登录链路;管理员 MFA、管理员人机验证码等增强策略也由后台开关控制,默认关闭,开启/关闭均记录审计。
  10. V1 统一使用可配置余额单位。 用户界面显示“金币”或后台配置的文字/图标单位,不出现“积分”概念。充值货币通过后台发布的换算比例转成余额单位,账本使用最小整数单位记录。
  11. V1 强制异步任务和 WebSocket。 生图、音频、反推、拆分、多角度等耗时操作统一进入队列;WebSocket 是长任务进度的主通道,轮询只作为断线或兼容降级。
  12. V1 存储为浏览器本地 + WebDAV。 平台对象存储只实现接口和适配器边界,不作为一期默认持久化目标;服务端临时 staging 文件必须隔离于静态目录并按 TTL 清理。
  13. 真正的图生 3D/文生 3D 延后。 在没有确认可稳定生成、导出和预览的模型前,V1 不开放 3D 生成入口;只保留能力矩阵、adapter 接口和后台开关。

0.3 当前技术基线

  • 前台:Vite、React、TypeScript、React Router、TDesign、Tailwind、Zustand。
  • 画布:现有 DOM/SVG 无限画布、节点 registry、图片工具和 ZIP/WebDAV 数据能力继续复用。
  • 后台:现有 TDesign React Starter 继续作为管理台壳,替换模板 mock 页面和示例业务。
  • 本地/容器同源:Nginx 将 /api/* 和 /api/v1/ws/* 反代到 server:3100;开发环境由 Vite 代理到同一服务。生产密钥仅通过运行环境注入。
  • 服务端建议基线:Node.js + TypeScript、HTTP API、WebSocket 网关、PostgreSQL、Redis、任务队列、隔离的本地 staging、邮件/SMS/支付适配器。对象存储 adapter 预留但 V1 默认关闭。具体框架可以在技术评审时确定,但领域边界和接口契约先按本文执行。
  • 外部模型规范:一期统一使用 OpenAI 兼容图片接口作为规范化入口;其他供应商通过服务端 adapter 转换,不向前台暴露差异。
  • 用户端模板:docs/design-reference/MiragenFlow-front/ 只作为设计和组件输入;不得让运行代码从该参考目录跨层引用。

1. 前台产品范围

前台用户只负责创作、查看自己的任务和余额、管理自己的资产/存储。渠道、供应商账号、价格表、路由优先级和健康状态全部由后台控制。

1.1 首页和工作台入口

  • 保留网站首页,展示元境幻生定位、游戏美术/艺术资产/多视图工作流;3D 生成仅作为后续能力说明,不提供 V1 入口。
  • 首页入口至少包括:开始创作、打开画布、查看资产、登录/注册、余额状态。
  • 登录前可以浏览首页和公开能力说明;未登录提交生成任务时跳转登录/注册。
  • 首页不展示供应商名、内部模型 ID、API Key 配置和渠道状态。

1.2 用户注册、登录和账户中心

一期用户端必须支持:

  • 邮箱注册和邮箱验证码验证。
  • 手机号注册和短信验证码验证;是否强制手机号由后台策略控制。
  • V1 不接入 Google、Apple、微信等第三方 OAuth/社交登录。
  • 密码登录、验证码登录(是否开放由后台策略控制)。
  • Access Token + Refresh Token 会话。
  • 用户两步验证默认关闭;后台开启后才要求用户完成 MFA,启用/关闭必须记录操作者、原因和生效时间。
  • 退出登录、刷新会话、修改密码、忘记密码、重新发送验证邮件/短信。
  • 账户状态:正常、待验证、冻结、注销中。
  • 基本账户页:昵称、邮箱/手机号脱敏、余额、消费记录、任务历史、登录设备。
  • 风险控制:验证码发送频率限制、图形验证码/人机校验、登录失败次数限制、IP/设备限流、异常会话注销;普通用户默认不展示验证挑战,开关开启后才执行。

认证安全基线固定如下:

  • 生产环境使用同源会话;短期 Access Token 只保存在前端内存,Refresh Token 只通过 HttpOnly、Secure、SameSite=Lax/Strict Cookie 传输,不写入 localStorage 或画布导出文件。
  • Access Token 必须包含明确的 aud、sub、scope 和过期时间;Refresh Token 采用轮换、哈希存储和复用检测,检测到旧 Token 重放时撤销同一设备会话链。
  • Cookie 会话启用 CSRF 防护;跨域开发请求必须经过本地反向代理,不允许前端直接把凭证交给第三方域名。
  • 邮箱和手机号先做规范化再建立唯一索引;验证码发送、消费和失败次数使用原子更新,验证码仅保存哈希。未完成验证的账户可以浏览公开页面,但不能调用会产生费用的任务接口。
  • 密码使用成熟密码哈希算法(优先 Argon2id),记录算法版本;重置 Token 单次消费并在修改密码后撤销其他会话。账户注销通过 POST /api/v1/me/close 进入 注销中,由异步清理任务完成匿名化/删除。
  • 前端在刷新会话时只允许一个刷新请求,其余请求等待同一结果;刷新失败后清空内存身份并回到登录页。

前台不再使用当前“浏览器本地空 user store”作为商业认证。useUserStore 改为服务端会话状态;登录成功后所有需要计费的 API 都必须携带用户身份。

1.3 公开模型产品目录

用户看到的是后台发布的产品目录,而不是渠道配置。

建议公开结构:

用户看到的选项 后台控制内容
基础模型 公开模型 ID、绑定的渠道分组、内部模型 ID、默认参数、单次价格、可用任务类型
高级模型 公开模型 ID、绑定的渠道分组、内部模型 ID、质量策略、单次价格、并发限制
旗舰模型 公开模型 ID、绑定的渠道分组、内部模型 ID、最高质量策略、单次价格、失败提示文案
分辨率 低/中/高/超高或后台自定义名称、实际像素尺寸、价格倍率、模型支持范围
生成数量 后台设置最大数量和阶梯价格
功能模式 文生图、图生图、局部编辑、反推提示词、多角度、抠图、拆分等 V1 能力开关;3D capability 仅保留禁用的预留开关

模型 ID 可见性决策

一期固定采用“显示公开模型 ID,不显示 provider 信息”方案:

  • 前台请求只携带公开的 modelProductId、resolutionPresetId、业务参数和幂等键。
  • 前台最多显示后台配置的稳定公共模型 ID,例如 basic-image-v1;该 ID 与 provider 无关。
  • 后台保存多个渠道的 providerModelId,用于调用、审计和故障排查;同一公开模型 ID 可以映射多个 provider 的不同内部 ID。
  • 前台、用户导出文件和公开 API 均不得返回 provider 名称、Base URL、API Key、渠道顺序或 provider model ID。
  • 管理员可以查看精确内部 ID;客服排障使用任务 ID 和 attempt ID,不要求用户知道供应商信息。

如果后续确认必须让专业用户看到模型信息,应只增加“公开别名/能力说明”,不要暴露渠道地址、Key、供应商账号或未经抽象的内部 ID。

1.4 无限画布工作台

保留并升级当前 /canvas/:id:

  • 图片、文本、音频、生成配置、分组节点。
  • 平移、缩放、框选、拖拽、调整尺寸、连线、分组、复制、删除、撤销/重做、小地图。
  • 画布背景、节点标题、节点 JSON/信息查看、批量图片组。
  • 画布项目创建、重命名、导入、导出、删除;项目级复制作为后续补充,当前不假设已实现。
  • 画布内直接插入资产、上传图片/音频、粘贴剪贴板图片/文本。
  • 任务节点展示排队、运行、成功、失败、取消、部分成功状态。
  • 生成结果可以继续作为下一个节点的提示词、参考图或编辑输入。

一期要把当前“节点生成直接调用浏览器 API”改成“节点生成调用平台任务 API”,但保留当前节点数据结构和工作流表达方式,避免一次性重写画布交互。

1.5 游戏资产和艺术资产工作流

参考 Holopix 的功能理念,一期前台应提供以下产品能力入口。每项能力都应能从普通工具页或画布节点触发,并生成可回到画布/资产库的结果。

通用生成和编辑

  • 文生图、图生图、参考图编辑。
  • 风格转换、构图参考、风格参考、主体参考。
  • 万能渲染:统一承载构图、风格、参考和质量参数,而不是暴露供应商 API 差异。
  • 局部细化、局部替换、擦除/重绘。
  • 智能扩图/扩展画布。
  • 相似图裂变/变体生成。
  • 一键成稿、丰富细节、重绘放大。
  • 反推提示词:从图片生成结构化、可再次执行的提示词结果。

游戏资产专项

  • 游戏角色、场景、道具、武器、ICON、UI 素材生成。
  • 透明背景和前景抠图。
  • Sprite Sheet/规则网格切分。
  • 全能拆分:自动识别角色、道具、ICON、背景和可分离区域,输出透明子图、边界框、命名和关联组。
  • 图层拆补:从一张合成图中恢复或重建局部图层。
  • 线稿提取、材质/颜色参考和调色板生成。
  • 像素图转换和像素风格变体。
  • 表情生成或角色表情变体。
  • 统一尺寸、命名、透明边缘和导出规格校验。

多视图和 3D 化(V1 仅保留 2D 能力)

  • 正视图、斜侧图、侧视图、俯视图、仰视图、背视图。
  • 一键三视图、一键六视图,结果作为关联视图组。
  • 自由视角:输入参考图后,使用水平角、俯仰角、相机距离、镜头范围控制视角。
  • V1 不开放真正的单图/多图转 3D、文生 3D、图生 3D、3D 预览和模型导出;这些入口由 feature flag 关闭。
  • V1 只实现多视图/自由视角的 2D 参考图任务,结果为关联图片组。
  • 服务端保留 3D adapter、GLB/GLTF、OBJ、纹理和缩略图字段,待确认有稳定模型并通过生成、预览、导出验收后再启用。

当前画布可以复用为 2D 编排层;后续真正的 3D 节点和自由摄像机需要新增 Three.js/WebGL 视口,不能把当前“角度 prompt 重绘”包装成真实 3D。

1.6 音频能力

音频按既定范围保留:

  • 文本生成语音。
  • voice、格式、速度、instructions 参数。
  • 音频任务进度、取消、失败重试、下载和画布节点引用。
  • 音频文件进入统一媒体结果和 WebDAV 同步链路。

视频、首尾帧视频、图生视频、文生视频和动画时间轴不进入一期。

所有前台能力通过目录能力矩阵发布:每个 modelProduct 返回 capabilities[]、参数 schema、输入类型/大小、是否异步、结果类型和失败码映射。前台只渲染当前产品声明的控件;当能力未配置或版本失效时显示“暂不可用”,不自行猜测 provider 参数。图片、音频和 V1 多视图结果统一关联 taskId、outputId、资产/画布引用和保留期;3D 结果字段只做接口预留。

1.7 资产、历史和存储

  • 我的资产:图片、文本,后续可扩展音频、3D、Sprite、序列帧和模型。
  • 搜索、标签、类型筛选、预览、编辑、复制、下载、删除、画布插入。
  • 作品/任务历史:按项目、任务类型、模型产品、时间、状态筛选。
  • 生成结果版本:保留输入参数、公开模型产品、分辨率、任务 ID 和输出关联,不暴露供应商凭证。
  • 本地:画布、节点、资产索引和已保存媒体默认写入浏览器 IndexedDB/localForage,按用户命名空间隔离;认证 Refresh Token、API Key 和 WebDAV 密码不得进入本地业务存储。
  • WebDAV:用户配置并同步画布、资产、图片、音频及后续 3D/序列文件。同步使用每用户命名空间、manifest 版本、校验和和软删除标记;同一资源发生双向修改时保留冲突副本并提示用户选择,不静默覆盖。
  • WebDAV 凭证在服务端加密保存或使用 KMS 引用,前台只能看到脱敏连接状态;Base URL 做 HTTPS/allowlist/私网阻断和路径规范化,连接失败进入可重试的离线队列,不阻塞生成任务主链路。
  • 平台侧 V1 只保存任务元数据、账本和必要的临时 staging 结果;staging 位于静态目录之外,使用随机对象键、所有权校验、TTL、软删除和 GC 状态。对象存储 adapter 预留但默认关闭,后续接入不改变资产/任务接口。
  • 后台可视化配置任务结果、原图和 WebDAV manifest 的保留时长、归档策略和最大延长次数;用户可以在上限内手动延长,超过上限需要后台权限或套餐策略。归档优先写入 WebDAV,失败时保留待处理状态,不静默丢失。
  • 用户可以在权限和保留策略允许的范围内主动删除任务结果、原图和自己的 WebDAV manifest;删除先写软删除/审计事件,再由 GC 清理平台 staging,WebDAV 删除失败进入重试队列并显示状态。

1.8 余额和消费展示

  • 右上角或账户中心显示统一余额单位,V1 默认展示“金币”文字和金币图标;前台不出现“积分”字样。
  • 余额单位由后台配置名称、短代码、图标 key、符号、精度和显示小数位;后续可以切换为其他文字单位或图标单位,但同一生效版本只能有一个用户可用单位。
  • 充值金额通过后台发布的换算比例转为金币,例如支付货币 amount -> balanceUnitAmount;换算比例、舍入方式、最低充值和生效版本都进入订单快照。
  • 提交任务前显示预计消耗。
  • 批量生成显示按数量和分辨率计算的预计消耗。
  • 任务详情显示预扣、实际扣除、释放/退款状态。
  • 余额不足时阻止提交并跳转充值,不创建不可执行任务。
  • 用户可以查看充值订单、消费账单和退款/释放记录,但不能修改账本。
  • 用户可以购买后台发布的套餐;套餐可包含赠送金币、购买价格、有效时长、并发限制、队列优先级和可用渠道组。套餐余额和普通充值余额都进入同一账本,但来源和过期策略必须分开记录。

1.9 用户侧错误和可用性提示

用户不能看到供应商内部故障细节,但必须得到可执行提示:

  • 当前模型不可用,请切换到其他旗舰模型。
  • 余额不足,请充值后重试。
  • 当前分辨率不支持该模型,请降低分辨率或切换模型。
  • 请求参数无效,请修改提示词/参考图。
  • 任务已取消,预扣余额已释放。
  • 任务部分成功,仅对成功结果扣费。
  • 系统正在排队,显示任务编号和预计状态,不重复提交。

内部日志可以保留 provider、channel、attempt、HTTP 状态和响应摘要,但前台只显示公共错误码、任务 ID 和建议动作。

2. 后台管理范围

后台仅管理员可用,地址保留 /admin/。TDesign 模板中的 Dashboard、List、Form、Detail、User、Result 页面可以继续作为视觉和路由壳,但所有示例 mock、Tencent 文案、模板用户数据和模板接口必须替换为真实业务域。

2.1 管理员认证和权限

  • 管理员登录、退出、刷新会话。
  • 管理员使用独立认证域和独立会话 Cookie;管理员 Access Token 的 aud 不得被用户端 API 接受,/admin/ 静态路径本身不视为权限边界,所有 /api/v1/admin/* 请求都必须经过服务端鉴权。
  • 管理员角色:至少 super_admin、operator、finance、support、auditor。
  • 权限粒度:用户、认证消息、渠道、模型产品、任务、余额/订单、系统配置、审计日志;默认拒绝,按角色授予最小权限,并对用户、任务、账单等对象做范围校验。
  • 高风险操作二次确认:禁用渠道、调整余额、退款、删除用户、修改价格和切换路由优先级。
  • 管理员操作写入审计日志,记录操作者、对象、前后值、IP、请求 ID 和时间。

管理员安全基线:

  • 高风险操作必须重新认证;MFA、IP 白名单和设备策略由后台开关控制,默认关闭增强项。管理员登录、权限变更、密钥查看/轮换和高风险操作均写入不可变审计记录;管理员未开启增强策略时只需邮箱和密码。
  • 人工调账和支付退款采用“申请 -> 审批 -> 执行”状态机,申请人和审批人不能是同一账号;没有审批记录不得执行。
  • 管理员列表和配置写入使用 Idempotency-Key、资源版本号/If-Match 做幂等和乐观锁,版本冲突返回 409,不能静默覆盖其他管理员的变更。
  • support 默认不能查看完整提示词、原图、WebDAV 凭证或渠道密钥;临时 break-glass 授权需要审批、过期时间、脱敏展示和独立审计。

2.2 用户管理

管理员可以:

  • 按用户 ID、邮箱、手机号、状态、注册时间、余额和最近活动搜索。
  • 查看用户基本资料、验证状态、会话、登录设备、任务历史、消费和充值记录。
  • 冻结/解冻账户、触发密码重置、重新发送验证消息。
  • 手动增加/扣减余额,但必须通过“人工账本调整”记录原因和审批人。
  • 设置用户等级、限流、并发数、每日额度和可见模型产品。
  • 查看用户是否配置 WebDAV,但不能明文查看用户 WebDAV 密码。

2.3 注册、认证、邮件和短信管理

后台配置并监控:

  • 邮件供应商:SMTP/第三方邮件 API、发件人、模板、域名状态。
  • 短信供应商:供应商、签名、模板、区域和发送策略。
  • 验证模板:注册验证、登录验证码、密码重置、异常登录提醒、余额/订单通知。
  • 消息发送日志:待发送、发送中、成功、失败、重试次数、供应商响应摘要。
  • 验证码策略:有效期、发送冷却、每日上限、失败次数、IP/设备/目标限制、图形验证码或人机挑战开关。防刷策略为一期必做项,不得只依赖前端按钮禁用。
  • 两步验证策略:用户默认关闭,管理员保持独立登录流程,MFA 默认关闭并由后台安全开关启用。后台提供启用/关闭、重置、恢复码和生效范围配置,策略变更必须二次确认并写审计。
  • Provider 故障切换:邮件/SMS 也使用 outbox + 重试,不阻塞用户注册主事务。

验证码必须只保存哈希或不可逆摘要,不保存明文;敏感信息不得写入普通日志。 验证码的目标(邮箱/手机号)需规范化后参与限流键;消费操作必须使用一次性原子更新(未过期、未使用、尝试次数未超限),并记录发送 IP、设备和 provider message ID,重复消费统一返回验证失败而不改变账户状态。

2.4 渠道管理

渠道是供应商账号或接口实例,不是用户看到的模型产品。

单个渠道最少包含:

  • channelId、名称、供应商、环境、区域。
  • Base URL、API 格式、认证方式、加密后的 API Key/Secret。
  • 支持的能力:image/text/audio/3D/utility。
  • 可用 provider model ID 映射。
  • 超时、最大并发、速率限制、单次重试次数。
  • 启用/禁用状态、管理员备注、维护窗口。
  • 健康状态、连续失败次数、熔断状态、最近成功/失败时间。
  • 成本估算、供应商计费单位和内部成本备注。

渠道安全要求:Base URL 只允许 HTTPS 和后台配置的域名/IP allowlist,阻断 loopback、link-local、RFC1918、Unix socket 和重定向到私网;API Key/Secret 使用 KMS 或部署密钥加密并带版本号,轮换时保留旧版本到在途 attempt 结束,前台、审计日志和错误响应均不得出现明文凭证。

后台操作:新增、编辑、测试、启用、禁用、轮换凭证、查看脱敏健康信息、查看调用统计和失败原因。

2.5 渠道分组和路由顺序

分组是用户请求所映射的内部路由池,例如:

旗舰图片组
  1. Provider-A 账号 1 -> providerModelId=MODEL_A
  2. Provider-B 账号 2 -> providerModelId=MODEL_B
  3. Provider-C 账号 1 -> providerModelId=MODEL_C
  4. Provider-D 账号 4 -> providerModelId=MODEL_D

分组配置:

  • groupId、内部名称、能力、用途和维护说明。
  • 成员渠道及明确的 priority 顺序。
  • 是否允许自动故障切换。
  • 组级超时、重试上限、并发和熔断策略。
  • 组级公共错误文案和推荐替代模型产品。
  • 绑定的公开模型产品和分辨率策略。
  • 配置发布版本、修改人和生效时间;每次发布生成不可变版本,支持回滚到上一版本。
  • 失败分类白名单、每渠道 retry budget、退避初始值/上限/抖动、熔断阈值、半开探活间隔和任务 lease 超时。

默认路由规则:

  1. 创建任务时把 modelProduct、分辨率、价格、渠道组、绑定关系和路由策略的发布版本全部写入任务快照;任务排队期间后台改价、改 priority 或下架产品,不改变该任务的计费和路由依据。
  2. 按快照中的 priority 从小到大选择启用且未熔断的渠道;渠道启停只影响尚未创建快照的新任务,已创建任务仅在安全策略允许时跳过明确禁用的渠道。
  3. 每次调用都创建一个 attempt,状态至少为 pending -> sent -> succeeded/failed/unknown/canceled;写入 worker lease、provider request ID、平台幂等键和超时原因。队列使用可见性超时、心跳和死信队列,worker 崩溃后由恢复任务接管。
  4. 单渠道发生可重试错误时,按组级 retry budget、指数退避和抖动策略重试;达到该渠道预算后切到下一渠道。供应商已接受请求但客户端超时的 unknown 结果先按 provider request ID 查询/对账,不直接重复提交。
  5. 熔断计数、半开探活和并发占用使用 Redis 原子操作;熔断状态包含 closed/open/half_open、版本和过期时间,只有探活成功才能恢复。管理员手动启停或探活结果都写健康事件。
  6. 401/403/模型不存在按“渠道凭证/模型配置错误”处理:隔离该渠道并告警;若请求本身被策略拒绝,不切换渠道。用户参数错误、内容审核拒绝、图片格式无效等不可重试错误直接结束任务。
  7. 组内全部渠道不可用时返回公共错误 MODEL_GROUP_UNAVAILABLE,提示用户切换同档位其他模型;除非后台明确设置 fallbackGroupId,否则不从旗舰组静默降级到高级组或基础模型。
  8. 渠道切换对用户透明,任务 ID 不变;后台任务详情展示所有 attempt。用户取消与 worker/供应商完成竞态时,以服务端先提交的终态为准,迟到结果只做对账,不重复入账或覆盖已取消状态。

2.6 模型产品和分辨率配置

管理员要管理“用户看到的模型”而不是只管理渠道:

  • 公开模型产品:基础、高级、旗舰,以及抠图、拆分、线稿等 V1 专项产品;3D 产品只保留后台草稿/契约,不在 V1 上架。
  • 公共名称、公开模型 ID、描述、图标、能力标签、排序、上架状态。
  • 绑定的 channelGroupId。
  • 可选分辨率预设:低、中、高、超高/4K,实际宽高、比例、模型限制。
  • 默认质量、最大生成数量、参考图数量、支持 mask 与否。
  • 每种“模型产品 + 分辨率 + 功能”的公开价格/余额消耗。
  • 替代模型建议:同档位优先,其次由后台选择允许的跨档位推荐。
  • 发布版本和生效时间;修改价格或路由需写审计日志。

套餐和队列策略由后台单独配置,不把 provider 信息暴露给用户:

  • 套餐字段:planId、套餐名称、公共编码、图标、基本介绍、套餐时长、购买价格、包含金币、有效期、上架状态、排序、发布版本。
  • 套餐权益:允许使用的公开模型产品,以及后台内部的 allowedChannelGroupIds、并发上限、队列优先级、单文件大小、结果保留上限和是否允许延长/归档;渠道组 ID 只存于后台权益快照,不返回用户端。
  • V1 不限制每日任务数;并发数、队列优先级和套餐可用范围必须限制,并在任务创建时写入权益快照。
  • 用户端只展示套餐名称、价格、金币数量、时长、公开模型/能力范围和权益说明;不显示 provider 分组、账号或内部渠道顺序。
  • 套餐可停用但不删除历史版本;已购买权益按购买时版本结算,新增任务按当前发布版本校验。

前台目录 API 只返回这些公开字段,不返回 channelId、providerModelId、Base URL、Key、内部成本和渠道顺序。

2.7 任务中心和接口调用监控

后台可以查看:

  • 任务 ID、用户、公开模型产品、功能、分辨率、数量、状态、余额状态。
  • queued/running/succeeded/partial/failed/canceled/refunded 状态变化。
  • 每次 provider attempt、渠道、开始/结束时间、HTTP 状态、错误分类和重试结果。
  • 平均耗时、成功率、P50/P95 延迟、渠道错误率、模型组可用率。
  • 取消任务、重试任务、标记异常、查看脱敏请求/响应摘要。
  • 查看 WebSocket 连接数、心跳、断线重连、事件积压和消费延迟;任务事件以 taskId + eventId + sequence 去重。
  • 不允许管理员在任务页面直接查看用户 API Key、完整提示词附件或敏感凭证,除非有明确权限和审计。

2.8 余额、账本、充值和支付预留

计费方式统一为余额制:

  • 充值成功:按订单快照中的换算比例增加统一余额单位(V1 默认金币)。
  • 任务提交:预扣预计余额。
  • 任务成功:按实际成功输出结算。
  • 任务取消、全渠道失败或系统错误:释放预扣或产生退款账本记录。
  • 批量任务部分成功:只扣成功结果,失败项释放预扣。
  • 同一任务的 provider 重试不向用户重复收费。

金额必须使用整数最小单位或定点 Decimal,禁止使用浮点数直接计算余额。余额不可直接覆盖,只能追加账本流水:

balance_accounts
balance_ledger
  -> reserve      预扣
  -> settle       成功结算
  -> release      释放预扣
  -> refund       退款
  -> manual_adj   管理员人工调整
recharge_orders
payment_events

支付接口只做适配层预留:

  • createRechargeOrder(userId, amount, provider)。
  • queryPayment(orderId)。
  • handlePaymentWebhook(provider, signature, payload)。
  • refundPayment(orderId, amount, reason)。
  • 支付回调签名校验、幂等键、订单状态机和重复通知处理。

余额单位和换算配置必须可视化管理:

  • 余额单位配置:名称、短代码、图标 key、符号、精度、显示小数位、是否启用。
  • 换算规则配置:支付货币、余额单位、兑换比例、舍入模式、最低/最高充值、赠送规则、版本和生效时间。
  • 价格和套餐金额以余额最小单位保存;充值订单同时保存支付金额、余额到账金额和规则版本,避免后续改比例影响历史订单。

一期充值只提供管理员人工充值和 mock provider;不能用“收到前端 success 参数”直接加余额。真实支付供应商在后续接入时只实现 adapter,不改余额账本规则。支付 API 和 webhook 契约必须先预留,等待用户提供第三方支付开发文档。

套餐后台页面必须支持:新增/编辑/复制/上架/下架、名称、公共编码、图标、介绍、套餐时长、包含金币、购买价格、可用模型产品/渠道组、并发上限、队列优先级、结果保留上限和版本回滚。套餐购买订单与普通充值订单分开记录,但到账仍写入统一余额账本。

2.9 系统配置和审计

  • 邮件/SMS 供应商、验证码策略。
  • 模型产品、渠道组、渠道健康阈值、价格和限流。
  • 余额单位、金币图标/文字、换算比例、舍入和充值上下限。
  • 套餐名称、时长、购买价格、包含金币、上架状态、介绍、可用模型/渠道组、并发和队列优先级。
  • 余额/订单/支付开关。
  • 本地 staging、WebDAV、对象存储 adapter 开关、任务/原图/manifest 保留期、归档和用户延长上限。
  • 全部敏感配置加密或通过部署环境注入。
  • 审计日志采用 append-only 存储,至少保存链式摘要/防篡改校验、保留期、脱敏策略和导出权限;审计日志自身的读取/导出也必须产生审计记录。
  • 审计日志支持按管理员、对象、操作类型、请求 ID 查询和导出;任务、支付、消息和 provider 请求贯穿同一 requestId/correlationId,便于追踪一次调用的全部状态。

3. 服务端调用和路由逻辑

3.1 前台提交任务

前台统一调用平台 API,不再调用供应商地址:

POST /api/v1/tasks/image
Authorization: Bearer ACCESS_TOKEN
Idempotency-Key: CLIENT_GENERATED_KEY
{
  "modelProductId": "flagship-image",
  "resolutionPresetId": "high",
  "prompt": "...",
  "references": [...],
  "mask": ...,
  "count": 4,
  "canvasProjectId": "..."
}

服务端顺序:

  1. 校验 Access Token、账户状态、产品是否对该用户可见。
  2. 校验提示词、参考图、分辨率、数量和功能参数。
  3. 校验引用文件、mask 和画布项目属于当前用户,检查 MIME、大小、像素、数量、病毒/恶意内容扫描状态和引用有效期;不接受任意外部 URL 直接进入 provider。
  4. 读取模型产品、分辨率价格、绑定分组;不信任前端传来的价格或 provider model ID,并把目录、价格、分辨率、渠道组和路由策略版本复制到任务快照。
  5. 解析用户当前有效套餐,检查公开模型/内部渠道组权益、余额、并发和队列优先级;每日任务数 V1 不设上限。
  6. 使用幂等键创建任务并预扣余额;重复请求返回原任务,不重复预扣。
  7. 将任务放入队列,返回任务 ID、状态和预计消耗。

3.2 队列和 provider attempt

generation_task
  -> resolve modelProduct
  -> resolve channelGroup
  -> ordered channels
  -> provider attempt #1
       success -> normalize result -> store output -> settle
       retryable failure -> attempt #2
  -> provider attempt #2 ...
  -> all unavailable -> fail public error -> release reserve

任务应支持:

  • HTTP 查询 GET /api/v1/tasks/:id。
  • WebSocket 是 V1 长任务进度主通道:连接使用用户会话鉴权、心跳、订阅/取消订阅和 taskId 权限校验;事件带递增 sequence、taskId、attemptId 和 eventId,客户端通过 cursor/last sequence 断线重放,服务端以任务历史快照为权威并按 eventId 去重。HTTP 轮询仅作为断线或不支持 WS 客户端的降级方案,SSE 不作为一期主通道。
  • POST /api/v1/tasks/:id/cancel 取消排队或可取消的运行任务;若 provider 支持取消则发送取消请求,否则等待未知结果对账,不能因迟到响应重复结算。
  • 任务完成后返回结果元数据、缩略图/签名 URL、画布关联信息和资产保存入口;结果下载必须校验用户所有权和资源 scope。
  • 任务结果存储采用短期签名对象 URL,URL 绑定 userId/taskId/outputId、用途和过期时间,可主动撤销;保存到资产或 WebDAV 后创建持久化引用,清理任务回收未保存结果。

服务端与 provider 使用统一 adapter 契约:

  • 输入至少包含 taskType、规范化参数、引用对象、超时、取消信号和平台幂等键;adapter 负责把它转换成供应商请求,不把密钥、Base URL 或原始响应传回前台。
  • 输出统一为 queued/running/succeeded/partial/failed/unknown/canceled、标准化 outputs[]、成本/用量摘要、provider request ID 和可审计错误分类。V1 的 image、text、audio、2D utility 可以有各自参数;3D adapter 只保留契约,启用后也必须遵守同一任务/attempt/结果生命周期。
  • adapter 必须限制出站超时、响应大小和 MIME,屏蔽供应商提示词/凭证泄露;管理员配置的 Base URL 经过 HTTPS、域名/IP allowlist 和私网地址阻断,禁止 SSRF。

3.3 错误分类

错误类别 示例 行为
用户参数错误 尺寸非法、参考图格式错误、提示词缺失 直接失败,不切换渠道,不扣费。
内容/策略拒绝 provider 返回内容审核拒绝 直接失败,禁止切换渠道;该输出不计费,未使用的预扣全部 release,记录公共拒绝码。
渠道暂时不可用 超时、网络错误、429、502、503、供应商维护 记录 attempt,按顺序切换后续渠道。
渠道凭证/配置错误 401、403、模型不存在 标记渠道健康异常,切换后续渠道;管理员收到告警。
系统错误 队列、存储、账本事务失败 任务进入系统失败,释放预扣并记录告警。
全组不可用 所有渠道耗尽或全部熔断 返回 MODEL_GROUP_UNAVAILABLE,建议切换其他公开模型。

用户消息只使用公共错误码和可执行建议;provider 原文只在后台脱敏日志中保存。

401/403 只有在确认属于渠道凭证/权限配置错误时才隔离渠道;若是用户内容、租户权限或产品策略拒绝,按用户参数错误处理,不把同一请求扩散到其他供应商。所有 attempt 的原始响应先脱敏再写入日志,禁止保存完整 API Key、Cookie、Authorization、原图和未授权的 WebDAV 凭证。

3.4 余额结算规则

  • 预扣发生在任务入队前,余额不足不入队。
  • 预扣金额以公开模型产品、分辨率、数量和功能参数计算,provider 切换不改变用户价格。
  • 成功输出逐项结算;一张失败图不应让整批成功图重复或多扣。
  • provider 重试属于平台成本,不向用户重复生成多条扣费记录。
  • 任务超时、取消、全渠道失败必须产生 release/refund 账本记录。
  • 所有账本写入和任务状态变化必须具备事务边界和幂等约束。

账本不变量和状态转移:

  • 账户永远满足 available + reserved = ledger_confirmed_balance,available >= 0、reserved >= 0;所有金额使用同一币种和整数最小单位/Decimal,流水金额正负方向固定并在 API 中明确。
  • V1 账本以余额单位最小整数(默认金币)记账;支付货币只出现在充值订单和换算规则中。任务价格、套餐到账和人工调账都必须保存单位版本,禁止在账本层混用支付货币与余额单位。
  • reserve 只允许从 available 转入 reserved,settle 从 reserved 转为实际消费,release 把未使用部分转回 available;refund 仅表示已结算消费的补回,不等同于预扣释放,也不直接代表支付渠道退款。
  • 预扣按后台定义的消费顺序(默认优先使用最早到期的套餐/赠送批次)分配到 balance_buckets,释放时按原批次返还;任务快照记录 bucket allocation,避免套餐过期或换算比例变化造成错扣。
  • 每个任务/输出最多一条生效的 reserve、settle、release 或 refund 关系;数据库唯一约束和 Idempotency-Key 共同防止重复记账。任务状态和账本状态在同一事务中提交,或由带版本的 outbox/reconciler 可证明地补偿。
  • 预扣带 expiresAt;超时由 reconciler 扫描并根据 attempt/任务最终状态执行 release 或进入人工对账,不允许静默丢失冻结余额。余额更新使用行锁或乐观版本 CAS,冲突重试后仍失败则任务不入队。
  • 批量任务按输出保存 unitPriceSnapshot 和 chargedAmount;成功输出逐项 settle,失败/重复/未知输出不重复扣费。provider 成本与用户价格分离,provider 重试只记录平台成本。

支付订单与回调状态至少为 created -> pending -> paid/failed/expired/refunding/refunded。payment_events 以供应商事件 ID 唯一,校验签名、订单号、金额、币种和用户后再入账;乱序/重复通知按状态机幂等处理,另有定时对账和拒付/退款补偿任务。

4. 最小领域数据模型

以下是一期需要在服务端落地的领域,不要求一次采用完全相同的表名,但关系和约束必须保留。

4.1 用户和认证

  • users:用户主表、状态、昵称、注册时间、最后活动。
  • user_identities:邮箱/手机号、验证状态、唯一索引、脱敏展示字段。
  • password_credentials:密码哈希、算法版本、修改时间。
  • verification_codes:用途、目标、哈希、过期时间、尝试次数、发送来源。
  • sessions:用户/管理员会话域、refresh token 哈希、设备、IP、audience、过期、轮换链和撤销时间。
  • user_mfa_factors:用户/管理员身份、因子类型、密钥/恢复码摘要、启用状态和最近使用时间;密钥材料加密或只保存不可逆摘要。
  • captcha_challenges:目标、IP/设备指纹、挑战类型、哈希结果、过期时间、消费状态和失败次数。
  • admin_roles / admin_permissions / admin_user_roles:后台 RBAC。

4.2 模型和渠道

  • model_products:用户看到的基础/高级/旗舰及专项产品。
  • model_product_resolutions:公开分辨率、实际像素、倍率、能力限制。
  • channel_groups:分组策略、优先级、熔断和公共错误配置、发布版本和生效时间。
  • provider_channels:供应商账号、加密凭证、Base URL、状态和限流。
  • channel_bindings:组成员顺序、provider model ID、参数映射。
  • channel_health:成功率、连续失败、熔断开始/结束、最近探活。
  • pricing_rules:模型产品/分辨率/功能/数量的公开价格和生效版本。
  • membership_plans:套餐名称、公共编码、图标、介绍、时长、购买价格、包含金币、上架状态、可用模型/渠道组、并发、队列优先级、保留上限和版本。
  • plan_purchases:用户、套餐版本、支付金额、到账金币、有效期、权益快照和状态。

4.3 任务和结果

  • generation_tasks:用户、公开模型、功能、参数摘要、状态、幂等键、预扣金额、余额单位版本、产品/分辨率/价格/渠道组/路由/套餐权益快照版本、状态版本、lease、队列优先级和结果保留期。
  • generation_attempts:任务、渠道、provider model、开始/结束、错误分类、重试序号、attempt 状态、worker lease、平台幂等键、provider request ID、unknown 对账信息。
  • generation_outputs:结果文件、缩略图、MIME、尺寸、成功/失败、单位价格快照、实际扣费、资源 scope、签名 URL 过期和保留期。
  • upload_objects:用户、对象 key、MIME、大小、校验和、扫描状态、来源、过期时间和软删除时间;所有参考图/mask/资产内容先经过该对象层。
  • canvas_projects / canvas_nodes / assets:如果一期把项目和资产同步到云端,则与用户隔离;若暂时保持浏览器本地,也必须保存任务和资产关联 ID。

4.4 余额和支付

  • balance_accounts:用户余额、冻结/预扣余额、版本号。
  • balance_buckets:充值/套餐到账批次、剩余余额、有效期、消费顺序;过期批次由 GC/账本任务处理,不能直接覆盖账户总额。
  • balance_ledger:不可变流水、类型、金额、余额单位版本、来源(充值/套餐/任务/调账)、关联任务/订单、有效期、幂等键。
  • balance_units:单位名称、短代码、图标 key、符号、精度、显示小数位和状态。
  • balance_conversion_rules:支付货币、余额单位、兑换比例、舍入、上下限、赠送规则、版本和生效时间。
  • recharge_orders:用户、金额、支付渠道、状态、过期时间。
  • payment_events:供应商事件 ID、签名校验结果、原始摘要、处理状态。
  • refund_records:退款金额、原因、原订单、支付状态。

4.5 消息和审计

  • message_providers:邮件/SMS 供应商和加密配置。
  • message_templates:注册、验证、重置、通知模板和版本。
  • message_outbox:异步发送状态、重试和 provider message ID。
  • audit_logs:管理员、操作、对象、前后值摘要、IP、请求 ID。
  • storage_policies:任务结果、原图、WebDAV manifest 的保留期、归档策略、用户延长上限和 GC 规则。

4.6 存储和同步

  • webdav_connections:用户、加密凭证引用、规范化 Base URL、根目录命名空间、最近测试和轮换时间;读取接口只返回脱敏信息。
  • sync_manifests:用户、资源类型、版本、校验和、更新时间、冲突状态和最后同步游标。
  • canvas_projects、assets 和 upload_objects 都必须带 ownerId;对象访问、下载、任务引用和 WebDAV 同步均做所有权校验,禁止通过可猜测 ID 跨用户读取。

4.7 团队扩展预留(V1 不启用)

  • organizations / teams:未来的工作空间、所有者、套餐/余额归属和状态;V1 不创建团队业务记录。
  • organization_members:未来的成员、角色、邀请状态和加入/退出时间;V1 不开放邀请和共享操作。
  • resource_scopes:未来为画布、资产、任务和对象增加 ownerType/ownerId 范围字段;V1 固定为用户所有权,预留字段不能改变当前的越权校验。
  • 未来启用团队时,必须先定义共享资产、团队余额、成员审计和对象级权限,再开放 /organizations/* API。

5. API 边界规划

5.1 用户公开/认证 API

POST /api/v1/auth/register
POST /api/v1/auth/challenge
GET  /api/v1/auth/policy
POST /api/v1/auth/verify-email
POST /api/v1/auth/verify-sms
POST /api/v1/auth/login
POST /api/v1/auth/refresh
POST /api/v1/auth/logout
POST /api/v1/auth/password/forgot
POST /api/v1/auth/password/reset
POST /api/v1/auth/password/change
POST /api/v1/auth/verification/resend
POST /api/v1/auth/mfa/setup
POST /api/v1/auth/mfa/verify
POST /api/v1/auth/mfa/disable
POST /api/v1/auth/mfa/recovery
POST /api/v1/me/close
GET  /api/v1/me
GET  /api/v1/me/plans
GET  /api/v1/me/entitlements
GET  /api/v1/me/sessions
DELETE /api/v1/me/sessions/:id

5.2 用户目录、任务、资产和余额 API

GET  /api/v1/catalog/models
GET  /api/v1/catalog/models/:id
GET  /api/v1/catalog/balance-unit
GET  /api/v1/catalog/plans
GET  /api/v1/catalog/plans/:id
POST /api/v1/tasks/image
POST /api/v1/tasks/text
POST /api/v1/tasks/audio
POST /api/v1/tasks/image/reverse-prompt
POST /api/v1/tasks/image/multi-angle
POST /api/v1/tasks/image/matting
POST /api/v1/tasks/image/split
POST /api/v1/tasks/image/upscale
POST /api/v1/tasks/image/expand
POST /api/v1/tasks/3d
GET  /api/v1/tasks
GET  /api/v1/tasks/:id
GET  /api/v1/tasks/:id/events       # 事件历史/cursor 重放,不是 SSE
WS   /api/v1/ws/tasks
POST /api/v1/tasks/:id/cancel
GET  /api/v1/balance
GET  /api/v1/balance/ledger
POST /api/v1/recharge/orders
GET  /api/v1/recharge/orders/:id
POST /api/v1/recharge/plan-orders
GET  /api/v1/recharge/plan-orders/:id
GET  /api/v1/assets
POST /api/v1/assets
PATCH /api/v1/assets/:id
DELETE /api/v1/assets/:id
POST /api/v1/uploads/presign
POST /api/v1/uploads/:id/complete
GET  /api/v1/uploads/:id/download
GET  /api/v1/me/webdav
PUT  /api/v1/me/webdav
POST /api/v1/me/webdav/test
POST /api/v1/me/webdav/sync
GET  /api/v1/me/webdav/sync-status

图片专项 API 可以先统一映射到一个 taskType,不要求每个功能都复制一套 provider 调用代码。裁剪等纯本地操作可以继续在前台执行,但凡涉及模型或扣费的能力必须经过任务网关。 POST /api/v1/tasks/3d 仅作为禁用状态的契约预留;V1 目录不发布 3D capability,调用时返回统一的 CAPABILITY_NOT_ENABLED,不能把 2D 多角度结果伪装成 3D 文件。

一期固定以浏览器本地画布/资产 + WebDAV 为用户内容的持久化方式,服务端只保存任务、余额、结果引用和必要的资产关联;云端 canvas/projects CRUD 不进入 V1,仅保留未来扩展契约。

上传接口只返回平台对象 ID,不接受任意外部 URL;完成上传时服务端重新校验大小、MIME、校验和、扫描状态和用户所有权。WebDAV 接口保存加密凭证引用,Base URL 必须通过 HTTPS、域名/IP allowlist 和私网地址阻断,远端路径固定在每个用户的命名空间内,禁止 ..、绝对路径和跨用户 manifest。

资产写入至少包含 kind、title、tags、sourceTaskId、sourceOutputId 和 objectId/文本内容;服务端生成下载授权并校验软删除状态。任务结果保存到资产与账本结算必须有明确的关联 ID,重复保存请求返回同一资产而不是创建副本。

5.3 管理员 API

POST       /api/v1/admin/auth/login
POST       /api/v1/admin/auth/refresh
POST       /api/v1/admin/auth/logout
POST       /api/v1/admin/auth/mfa/setup
POST       /api/v1/admin/auth/mfa/verify
POST       /api/v1/admin/auth/mfa/disable

GET/PATCH /api/v1/admin/users
POST       /api/v1/admin/users/:id/freeze
POST       /api/v1/admin/users/:id/balance-adjustments

GET/POST/PATCH /api/v1/admin/message-providers
GET/POST/PATCH /api/v1/admin/message-templates
GET          /api/v1/admin/message-outbox

GET/POST/PATCH /api/v1/admin/channels
POST          /api/v1/admin/channels/:id/test
POST          /api/v1/admin/channels/:id/rotate-secret
GET/POST/PATCH /api/v1/admin/channel-groups
PATCH         /api/v1/admin/channel-groups/:id/order
GET           /api/v1/admin/channel-health

GET/POST/PATCH /api/v1/admin/model-products
GET/POST/PATCH /api/v1/admin/model-products/:id/resolutions
GET/POST/PATCH /api/v1/admin/pricing-rules
GET/POST/PATCH /api/v1/admin/billing/units
GET/POST/PATCH /api/v1/admin/billing/conversion-rules
GET/POST/PATCH /api/v1/admin/membership-plans
POST          /api/v1/admin/membership-plans/:id/publish
POST          /api/v1/admin/membership-plans/:id/rollback

GET           /api/v1/admin/tasks
GET           /api/v1/admin/tasks/:id/attempts
POST          /api/v1/admin/tasks/:id/retry
POST          /api/v1/admin/tasks/:id/cancel

GET           /api/v1/admin/balance/ledger
GET/POST/PATCH /api/v1/admin/recharge-orders
GET/POST/PATCH /api/v1/admin/payment-providers
GET           /api/v1/admin/payment-events
GET/POST/PATCH /api/v1/admin/storage-policies
GET           /api/v1/admin/ws/metrics

GET           /api/v1/admin/audit-logs

所有管理员写操作都需要权限检查、请求 ID、审计日志和幂等处理。

6. 后台页面规划

6.1 总览 Dashboard

  • 注册用户、活跃用户、余额总额、充值金额、生成任务数。
  • 各模型产品成功率、P95 延迟、失败率和消耗。
  • 渠道组健康度、熔断渠道、当前告警。
  • 邮件/SMS 成功率、支付回调异常、队列积压。

6.2 用户与认证

  • 用户列表、用户详情、身份验证状态、登录设备和会话。
  • 冻结/解冻、重置密码、验证消息重发。
  • 用户模型可见范围、额度、并发和余额调整。
  • 注册策略、验证码策略、邮件/SMS provider、模板和发送日志。

6.3 模型与渠道

  • 模型产品列表:基础/高级/旗舰/专项能力。
  • 分辨率和数量配置、价格、上架/下架、替代模型建议。
  • 渠道列表:凭证脱敏、测试、启停、健康、成本、限流。
  • 渠道分组:成员顺序、绑定模型 ID、熔断策略、公共不可用提示。
  • 变更预览:修改路由或价格前显示影响范围。

6.4 任务、余额与支付

  • 任务列表、任务详情、attempt 时间线、结果和扣费状态。
  • 余额单位/金币图标、换算比例、舍入和充值上下限。
  • 套餐管理:名称、编码、时长、包含金币、购买价格、介绍、上架状态、可用模型/渠道组、并发、队列优先级、保留上限和版本发布。
  • 余额账户、账本、人工调整审批。
  • 充值订单、支付 provider 配置、回调事件、退款记录。
  • 任务队列和重试监控。

6.5 系统、存储与审计

  • 对象存储、临时结果保留期、WebDAV 策略。
  • 结果/原图/manifest 归档、用户延长次数和 GC 执行状态。
  • WebSocket 连接、心跳、事件积压和断线重连指标。
  • 任务、媒体和日志清理策略。
  • 审计日志、管理员操作记录、密钥轮换记录。
  • 系统错误、provider 告警和消息 outbox。

7. 现有代码迁移规划

7.1 前台代码复用

保留并逐步改造:

  • MiragenFlow-front/src/data/artworks.ts:不进入 V1 运行时;首页不保留演示作品数据,公开模型目录和工作流状态必须来自真实 API。
  • MiragenFlow-front/src/App.tsx、src/main.tsx:不直接复制;重写到 web/src/app/,改用项目现有 BrowserRouter、认证守卫、错误边界和统一 providers,不能把 hash 路由作为 V1 公网路由。
  • 各页面和组件的 *.module.css:随对应组件迁移到目标目录;公共 token 合并到 web/src/styles/,不复制一份互相覆盖的全局 CSS。
  • MiragenFlow-front/src/components/primitives/*:迁移到 web/src/components/ui/,保留按钮、输入、反馈、选择器的视觉规范;不把组件验收页作为生产导航。
  • MiragenFlow-front/src/components/layout/*:迁移到 web/src/components/layout/,接入真实登录、余额、通知、账户和权限状态。
  • MiragenFlow-front/src/components/content/* 与 src/pages/HomePage.tsx:视觉原则已吸收至 web/src/pages/home/;首页内容、模型目录和任务入口使用真实 API,不复制演示作品流或占位页。
  • MiragenFlow-front/src/styles/*:合并到 web/src/styles/,以现有画布主题、TDesign/Tailwind tokens 为最终来源,避免两套全局变量并存。
  • MiragenFlow-front/src/assets/holopix/*:迁移到 web/src/assets/reference/;只允许作为前台公开素材或视觉参考,禁止在其中放配置、用户上传文件、响应数据或密钥。
  • MiragenFlow-front/src/pages/ComponentsPage.tsx:迁移为受保护的开发验收入口或移出生产构建,不保留“组件中心”作为普通用户功能。
  • MiragenFlow-front/src/pages/PlaceholderPage.tsx:只作为迁移过渡,不进入一期生产路由;真实页面完成后删除。
  • MiragenFlow-front/src/components/primitives/primitives.test.tsx:迁移到 web/src/components/ui/__tests__/ 或按现有测试结构重写;测试 fixture 不进入生产 bundle。
  • MiragenFlow-front/public/favicon.svg、public/icons.svg:只在完成版权、命名和内容核验后迁移到 web/public/;不得把不明 SVG 中的外链、脚本或用户数据带入静态目录。
  • MiragenFlow-front/index.html:重建为 web/index.html,只保留元境幻生标题、favicon 和公开 meta,不复制模板的 /src/main.tsx 引用或演示标题。
  • MiragenFlow-front/package.json、package-lock.json、vite.config.ts、tsconfig*.json、.oxlintrc.json:不直接覆盖现有 web/ 构建配置;按依赖和脚本逐项评估后合并,锁文件只保留 web 自身的一份。
  • MiragenFlow-front/docs/COMPONENTS.md、README.md���迁移到 docs/design-reference/ 作为设计输入记录,不能当作产品文档或运行时依赖。
  • MiragenFlow-front/dist/、node_modules/、临时截图和构建缓存:不作为源码迁移,不提交仓库;即使目录已存在,也不得复制其中 hashed JS/CSS、图片或字体到生产资源。
  • web/src/pages/canvas/project.tsx:保留节点交互、画布编排、结果回写和本地编辑工具。
  • web/src/components/canvas/*:保留节点 UI、裁剪、蒙版、切分、角度和批量结果 UI。
  • web/src/lib/canvas/canvas-node-generation.ts:改为组装平台任务请求和引用资源。
  • web/src/lib/canvas/canvas-export.ts、web/src/services/webdav-sync.ts:保留用户导出和 WebDAV 能力。
  • web/src/stores/use-asset-store.ts、useCanvasStore:先支持本地恢复,再增加用户/云端任务关联。

7.2 必须移出用户端的能力

  • web/src/stores/use-config-store.ts 中的 Base URL、API Key、供应商渠道管理。
  • web/src/components/layout/channel-editor-drawer.tsx 的用户渠道编辑。
  • web/src/components/layout/model-script-editor.tsx 的用户自定义供应商脚本。
  • web/src/services/api/image.ts、audio.ts 中直接携带外部 Key 的浏览器请求。

这些逻辑迁移到服务端 adapter/gateway。前台配置面板改为公开模型档位、分辨率、数量、语言、主题、WebDAV 和账户设置。

7.3 后台模板改造

  • 保留 TDesign Layout、菜单、主题、表格、表单和结果页组件。
  • 删除模板示例业务的 mock 数据、Tencent/tdesign 示例链接、合同/商品示例命名。
  • 将页面替换为用户、认证消息、渠道、渠道组、模型产品、任务、余额、充值、支付、审计。
  • 统一通过 /api/v1/admin/* 调用服务端,不再在页面里写静态演示数据。

7.4 同一公网入口

最终对外建议保持一个 origin:

/          前台静态资源
/admin/    后台静态资源
/api/      业务 API、认证、任务、余额
/api/v1/ws/ WebSocket 长任务事件(V1 主通道)

开发环境可以继续保留两个 Vite 进程;生产环境由反向代理统一转发,前台和后台不能依赖不同公网端口。

7.5 模板接入原则

  • MiragenFlow-front 是一次性模板输入目录,不作为运行时 package、workspace 或静态资源根目录;迁移完成后删除临时目录,或仅保留到 docs/design-reference/ 供设计追溯。
  • web/、admin/ 和 server/ 只能通过 packages/contracts/ 共享 API 类型、错误码和事件 schema;前台不得 import server 文件,server 不得 import web/admin 页面。
  • 浏览器端只能保存公开目录、主题、语言和本地画布/资产数据;Access Token 在内存,Refresh Token 使用 HttpOnly Cookie,provider 凭证和 WebDAV 密码只在服务端密文/KMS 中保存。
  • .env.example 只允许公开地址、功能开关和非敏感默认值;真实 .env、密钥、支付签名、短信/邮件凭证和 provider Key 不进入 git、构建产物、public/、日志或图示文档。
  • 用户上传、任务 staging、WebDAV 下载和导出文件必须使用服务层授权,不得放进 web/public/、admin/public/ 或可被 Vite 静态访问的目录。
  • CI/提交前检查必须拒绝 *.env、*.pem、*.key、上传目录、staging 目录、数据库快照和疑似 Authorization/API Key 内容;构建产物扫描通过后才能发布前台或后台静态资源。

8. 一期验收标准

8.1 用户链路

  • 普通用户默认使用邮箱或手机号加密码直接注册并登录;后台开启验证策略后,才需要邮箱/短信验证、人机校验或 MFA。
  • 用户可以登录、刷新、退出、重置密码,冻结账户不能提交任务。
  • 登录后能看到公开模型产品、分辨率、数量、预计余额消耗。
  • 前台网络请求中不出现 provider API Key、Base URL、provider model ID 或渠道顺序。
  • 用户可以提交图片、文本、音频和已纳入的图片工具任务。
  • 任务支持排队、进度、取消、结果、失败重试和历史查询。
  • 长任务通过 WebSocket 接收心跳、进度、attempt 和终态事件;断线后可使用 cursor 重放,轮询只作为降级。

8.2 路由和计费

  • 一个分组有四个渠道时,第一渠道失败会自动继续第二、第三、第四渠道。
  • 单渠道重试不会创建新的用户扣费。
  • 全组不可用时任务给出公共错误和同档位切换建议。
  • 余额不足不能入队;任务成功只扣实际成功结果。
  • 全失败、取消和系统错误会释放预扣余额。
  • 重复幂等请求不会重复创建任务或扣款。
  • 支付回调重复到达不会重复增加余额。
  • 金币单位、图标/文字、换算比例和套餐版本修改不影响历史订单和已创建任务快照。
  • 任务创建后修改模型价格或渠道 priority,不改变该任务的快照、路由和用户价格。
  • provider 已接受但网关超时会进入 unknown 对账流程,不直接重复生成;worker 崩溃可由 lease 恢复且不重复结算。
  • reserve/settle/release/refund 任一重复事件都保持账本不变量,过期预扣能被 reconciler 找回。

8.3 管理后台

  • 管理员能配置渠道、渠道组、priority、内部模型 ID、模型产品、分辨率和价格。
  • 管理员能配置金币单位、换算比例、套餐名称/时长/价格/金币/介绍/上架状态、可用模型或渠道组、并发和队列优先级。
  • 管理员能看到健康、失败 attempt、任务状态、余额账本、充值订单和消息 outbox。
  • 管理员写操作有权限校验和审计记录。
  • 不同角色无法读取越权用户对象、完整提示词、WebDAV 凭证或渠道密钥;高风险操作需要重新认证/审批。
  • 禁用一个渠道后,路由自动跳过;恢复后按策略重新参与。
  • 后台不展示明文 Key,日志不记录完整敏感请求和响应。

8.4 前台能力

  • 画布现有节点、连线、导入导出、WebDAV 和本地图片工具不因网关迁移而回归。
  • 基础/高级/旗舰和分辨率选项由后台目录动态控制。
  • 游戏资产、艺术资产、参考图、反推提示词、多角度、局部编辑、抠图、拆分、放大具备统一任务状态和结果回写;3D 入口在 V1 不发布,调用预留契约返回 CAPABILITY_NOT_ENABLED。
  • 参考图/mask 只能引用当前用户已上传且通过扫描的对象;结果签名 URL 按用户/任务/输出授权并可过期或撤销。
  • 视频/动画入口不存在,避免把未开发功能暴露给用户。
  • 3D 生成入口不存在;调用预留 3D 契约返回 CAPABILITY_NOT_ENABLED。
  • V1 不包含模型训练和内容治理;内容治理需求进入 V2 规划。

9. 当前阶段明确不开发

  • 视频生成、首尾帧、图生视频、文生视频。
  • 动画时间轴、骨骼、动效编辑器和视频序列导出。
  • Local Agent、Codex、MCP、Skill、远程 Prompt 和远程插件市场。
  • 面向用户的供应商 API Key、Base URL、原始 model ID 和自定义调用脚本。
  • 多人实时协作、团队空间和公开模型市场;V1 不实现,但保留 organization/team、成员邀请、workspace owner、共享资产、团队余额和对象范围字段/接口预留。
  • 内容治理不进入 V1;敏感词、图片审核、版权标记、投诉处理和人工复核统一列入 V2。
  • V2 内容治理预留:moderation_policies、moderation_decisions、copyright_marks、complaints、manual_reviews;V1 只保留 provider 拒绝结果和基础文件扫描,不建设治理后台流程。

版本边界:

版本 纳入范围
V1 认证/防刷/两步验证、金币余额和换算、人工/mock 充值、套餐、异步队列、WebSocket、本地 + WebDAV、图片/音频/2D 多视图工具、渠道路由和后台管理
V2 内容治理、敏感词/图片审核、版权标记、投诉和人工复核
后续 真正图生 3D/文生 3D、团队协作、模型训练、对象存储正式启用、公开模型市场、视频/动画

10. 一期交付顺序和依赖

按以下顺序拆分开发,前一阶段的契约和数据约束作为后一阶段的输入:

  1. 基础工程与安全底座:服务端项目、数据库迁移、配置/密钥管理、统一错误码、requestId、用户/管理员认证、RBAC、审计和限流。
  2. 余额与消息底座:余额账户和账本状态机、预扣/结算/释放、充值订单与支付 adapter 接口、邮件/SMS outbox、验证码策略和对账任务。
  3. 模型目录与渠道路由:渠道、渠道组、模型产品、分辨率/价格发布版本、健康探活、熔断、attempt 状态机、队列 lease、未知结果对账。
  4. 任务网关:上传对象、图片/文本/音频 adapter、统一任务 API、WebSocket 长任务进度、HTTP 轮询降级、取消/重试、签名结果 URL和输出持久化。
  5. 前台账户和目录改造:登录注册、账户/余额/账单、公开模型目录、配置面板替换为产品选项,移除浏览器 provider Key/脚本入口。
  6. 画布接入平台任务:保留节点和交互,改写生成上下文、引用对象、进度、结果回写、取消和错误提示;保留本地导入导出与 WebDAV。
  7. 游戏/艺术资产工具:反推提示词、多角度、局部编辑、抠图、规则切分/全能拆分、放大、扩图等统一接入任务能力矩阵。
  8. 套餐与后台业务页面:完成 TDesign 后台的用户、认证、渠道、模型、套餐、任务、余额、支付、存储、审计页面;3D 仅保留禁用的 adapter 契约和 feature flag,不纳入 V1 交付。
  9. 联调与验收:按第 8 节逐项验收,覆盖故障切换、重复事件、余额不变量、权限越权、WebDAV 冲突和前台无 provider 凭证。

视频、动画时间轴、团队协作实现、公开模型市场、模型训练和 V2 内容治理不阻塞前述一期主链路。

11. 目录结构和模板接入树

一期统一采用以下目录边界。目录名称先固定,后续实现不得把服务端密钥、用户文件或 provider 请求代码放入前台/后台静态目录。

11.1 当前模板输入快照

当前提供的模板目录为 /Users/qiu/Desktop/MiragenFlow/docs/design-reference/MiragenFlow-front,其用途是用户端视觉和交互基础,不是新的独立产品目录:

  • 技术栈:Vite 8、React 19、TypeScript、React Router 7、Zustand、TanStack Query、Lucide React、CSS Modules。
  • 当前入口:src/main.tsx -> src/App.tsx -> AppShell;使用 hash 路由,已有 home、components、models、create、canvas、assets 六个演示路由。
  • 已有视觉基础:src/components/primitives/ 基础组件、src/components/layout/ 壳层、src/components/content/ 首页内容、src/styles/ tokens/global、src/assets/holopix/ 公开参考素材;其中 alimama.woff2 被 tokens 引用,迁移前必须完成字体版权和静态资源核验。
  • ComponentsPage 是设计系统验收页,PlaceholderPage 是模块占位页;二者不能作为 V1 用户业务页面或默认导航。
  • 当前模板没有真实认证、模型目录、余额、任务 API、WebSocket、WebDAV 服务端或 provider 调用;接入时必须迁移到本项目 web/ 并替换 mock/占位逻辑。
  • dist/ 和 node_modules/ 属于构建产物/依赖缓存,禁止迁入源码、Docker 镜像或生产静态目录。
MiragenFlow/
├── web/                         # 用户端,唯一面向普通用户的前台应用
│   ├── public/                  # 仅公开 favicon、静态图标和无敏感信息资源
│   └── src/
│       ├── app/                 # AppProviders、路由、权限守卫、错误边界
│       ├── pages/               # home、auth、workspace、canvas、tools、tasks、assets、account、settings
│       ├── components/
│       │   ├── ui/              # MiragenFlow-front primitives 迁移后的基础组件
│       │   ├── layout/          # Header、Sidebar、UserMenu、NotificationCenter
│       │   ├── home/            # Hero、作品卡片、发现和筛选
│       │   ├── generation/      # Prompt、ModelPicker、Queue、Result
│       │   ├── canvas/          # 画布节点、工具栏、属性面板和导出
│       │   ├── assets/          # 资产卡片、上传队列、详情抽屉
│       │   ├── account/         # 余额、套餐、账单、会话
│       │   └── storage/         # WebDAV、同步、归档和保留状态
│       ├── services/
│       │   ├── api/             # 只调用 /api/v1,不保存 provider 地址或 Key
│       │   ├── realtime/        # WebSocket 连接、心跳、cursor、任务事件去重
│       │   └── storage/         # localforage/IndexedDB、ZIP、WebDAV 客户端
│       ├── stores/               # auth、catalog、balance、tasks、canvas、assets、settings
│       ├── hooks/                # 跨页面复用的 UI 副作用和任务订阅
│       ├── lib/                  # 纯函数、校验、错误码、格式化和画布工具
│       ├── styles/               # tokens、global、主题和第三方覆盖
│       └── types/                # 前台类型,公共 API 类型从 packages/contracts 引入
├── admin/                       # TDesign 管理台,不承载用户端页面
│   ├── public/                  # 仅公开静态资源
│   └── src/
│       ├── pages/               # dashboard、users、auth-messages、channels、groups、products、plans、tasks、billing、storage、audit
│       ├── router/              # /admin 路由和权限元数据
│       ├── services/             # 只调用 /api/v1/admin/*
│       ├── stores/               # admin session、RBAC、filters、dashboard metrics
│       ├── components/           # 管理台私有表格、表单、审批和时间线
│       └── styles/               # 管理台主题和 TDesign token
├── server/                      # 一期新增的服务端网关和任务系统
│   ├── src/
│   │   ├── app/                 # HTTP/WS bootstrap、middleware、error boundary
│   │   ├── modules/              # auth、admin-auth、users、catalog、billing、plans、channels、tasks、providers、messages、storage、webdav、audit
│   │   ├── adapters/             # provider、payment、email、sms、staging、future object storage
│   │   ├── infra/                # PostgreSQL、Redis、queue、WS broker、KMS、observability
│   │   ├── jobs/                 # retry、unknown reconciliation、outbox、GC、archive、payment reconciliation
│   │   └── shared/               # domain errors、idempotency、requestId、security helpers
│   ├── migrations/               # 数据库迁移,禁止把密钥或生产数据提交进来
│   └── tests/                    # 单元、集成、路由故障、账本和权限测试
├── packages/
│   └── contracts/                # API DTO、WS event schema、错误码、能力矩阵和版本常量
├── docs/                         # 用户文档、开发文档和图示
├── scripts/                      # dev/build/迁移/校验脚本
├── assets/                       # 仓库级公开素材,不放用户上传或服务端响应
├── docs/design-reference/        # 临时模板输入和视觉参考,不参与运行时构建
└── .env.example                  # 只放公开配置示例,不放任何真实凭证

模板迁移映射固定如下:

临时模板路径 目标路径 处理方式
src/components/primitives/ web/src/components/ui/ 合并基础组件,保留交互状态和可访问性
src/components/primitives/primitives.test.tsx web/src/components/ui/__tests__/ 迁移或重写测试,不进入生产 bundle
src/components/layout/ web/src/components/layout/ 接入真实会话、余额、通知和权限
src/components/content/ web/src/pages/home/ 仅吸收视觉原则,首页使用真实 API
src/data/artworks.ts 不迁移 删除演示数据,生产改接公开 API
src/App.tsx、src/main.tsx web/src/app/ 重写入口、providers、BrowserRouter 和守卫,不复制 hash 路由
src/pages/HomePage.tsx web/src/pages/home/index.tsx 改为真实首页和公开目录入口
src/pages/*.module.css 对应 web/src/pages/* 随页面迁移,合并 tokens
src/pages/ComponentsPage.tsx web/src/pages/dev/components/ 仅开发验收使用,不进普通用户导航
src/pages/PlaceholderPage.tsx 不迁移 真实页面完成后删除
src/assets/holopix/ web/src/assets/reference/ 只放公开设计素材,不放业务数据
public/favicon.svg、public/icons.svg web/public/ 版权、脚本和外链核验后迁移
index.html web/index.html 重建标题、favicon 和公开 meta
package.json、package-lock.json、Vite/TS/Oxlint 配置 不直接复制 逐项合并到 web 构建配置
README.md、docs/COMPONENTS.md docs/design-reference/ 仅作设计输入记录
dist/、node_modules/ 不迁移 构建产物和依赖缓存禁止作为源码

12. 系统图示

页面结构、ASCII(SSI)图示、用户侧逻辑、管理员侧逻辑、系统请求时序、整体架构和数据关系统一维护在 system-diagrams.md。

该文档覆盖当前已有页面和一期规划页面,并明确标记 current、phase 1 与“待确认”范围。新增页面、API、任务状态或账本状态时,必须同步更新图示文档,避免页面规划与调用链脱节。

13. 已确认决策和实现参数

本期范围已经收敛,不再把以下内容列为待确认功能:

  • 不接第三方登录;用户邮箱/短信验证、验证码防刷和用户两步验证作为可配置增强能力,普通用户默认关闭;管理员 MFA/人机验证码同样默认关闭,并支持审计启用/关闭。
  • V1 统一余额单位默认称为“金币”,支持后台配置文字/图标、换算比例、舍入和版本;不使用“积分”作为用户界面概念。
  • 充值只做管理员人工充值、mock provider 和支付接口预留;真实支付等用户提供第三方文档后接入。
  • 所有长任务使用异步队列,WebSocket 为进度主通道,HTTP 轮询为降级;V1 不做 SSE 主通道。
  • V1 使用浏览器本地 + WebDAV,平台对象存储只保留 adapter 接口且默认关闭;保留、归档、用户延长次数由后台可视化配置。
  • V1 不开放真正图生 3D/文生 3D、模型训练或内容治理;3D 仅保留契约和 feature flag,内容治理列入 V2。
  • V1 每日任务数不设上限,但必须限制并发、队列优先级、套餐权益、单文件大小和结果保留策略。
  • V1 不做团队协作,但预留 organization/team、成员、workspace owner、共享资产、团队余额和对象授权字段/接口。

仍需在实现阶段确定的只是参数和供应商细节,不改变上述范围:

  1. 图形验证码、人机挑战和风控供应商的具体选型、阈值和地区策略。
  2. 管理员 IP 白名单、硬件密钥等增强策略是否在默认 MFA 之外启用。
  3. 真实支付 provider、回调字段、签名算法和对账周期,等待第三方支付文档。
  4. 任务结果、原图和 WebDAV manifest 的默认 TTL 数值、归档目录格式、用户延长的具体上限。
  5. 退款/拒付 provider 流程的字段映射;平台内部 release、refund 和人工调账状态机不改变。