openapi: 3.0.3 # 契约 #1 API | 模块:studio(game-module-studio,Wave3 创作主链路最小版)| owner:studio 路 # 职责(架构 Doc B §71-76):有状态创作工作台后端。编排「建草稿(委托 project createProject)→一句话生成(委托 aigc) # →进度轮询→重生成→模板应用」。不跑 LLM(委托 aigc)、不持久化项目版本(交 project)、不做锁风裁决(调 compliance)。 # 与 game-studio 前端仓区分:本契约是后端 studio 模块(错误码段 112),game-studio 是产品端前端仓名,二者不同。 # 端:/app-api(产品端 game-studio,用户 Token);前缀由 yudao 框架按 controller.app 包名自动添加。 # 错误码段:studio = 1-112-***-***(R4 治理新登记,本模块独占,禁与他模块重叠: # 100 project/101 aigc/102 runtime/103 feed/104 telemetry/105 pay/106 trade/107 community/108 ip/109 compliance/110 biz/111 ad/112 studio) # 响应统一 Yudao CommonResult 信封:{ code, data, msg };code=0 成功。 # 编排链路(MVP 轮询非 MQ,D4): # /template/list (透传 aigc 模板注册表) → /draft (调 project ProjectApi.createProject 拿 gameId upsert 会话) # → /generate (调 aigc AigcApi.submitGenerate 落任务链回填 aigc_task_id) → /task/{id} (透传 aigc 进度轮询) # → /task/{id}/regenerate (调 aigc AigcApi.retryTask 新建 retry_of 任务链) # x-feign-contracts(studio 是调用方,依赖以下对方 -api seam,本契约不对外暴露 Feign): # - project-api ProjectApi.createProject(creatorUserId, title, templateId) → gameId(写类 RPC,显式 creatorUserId,归属校验在 project service) # - aigc-api AigcApi.submitGenerate / getTask / retryTask / getTemplateList(Wave3 新增 seam,纯暴露层委托 AigcTaskService) # attachments(R7):StudioGenerateReqVO.attachments 本波仅持久化(studio 侧落库),不透传 aigc(aigc reqDTO 无 attachments 字段);P1 再透传。 # 狠切留 seam 不实现(P1):rig/对白树/可视化批量;资产图仅槽位表(game_studio_asset)+ 单步调度,不六路并发。 info: title: 造梦AI studio 模块 API version: 1.0.0 description: >- 创作主链路最小版("做得出"工作台)。创作者进工作坊建草稿(移交 project 建游戏拿 gameId)→ 一句话生成(委托 aigc)→ 轮询进度直至终态(透传 aigc)→ 失败可重生成(委托 aigc retryTask)。MVP 轮询非 MQ;前端据此 vite-plugin-mock 自动生成 mock。 servers: - url: http://localhost:48080 description: 本地(Swagger/Knife4j http://localhost:48080/doc.html) paths: # =========================================================================== # 产品端 /app-api(创作工作台,用户 Token) # =========================================================================== /app-api/studio/template/list: get: tags: [app-studio] summary: 玩法模板列表(模板浏览/应用 P-TPL-01/03,透传 aigc 模板注册表) description: 透传 aigc 模板注册表(T-AGC-03);MVP 骨架返回空列表占位,待模板注册表接入。 responses: '200': description: 成功(玩法模板列表) content: application/json: schema: { $ref: '#/components/schemas/CommonResultStudioTemplateList' } /app-api/studio/draft: post: tags: [app-studio] summary: 建草稿(进工作坊 P-CRT-10 + 草稿移交 project P-TPL-03) description: >- 编排:服务端调 project ProjectApi.createProject(creatorUserId=当前登录用户, title, templateId) 建游戏拿 gameId 回写会话,再落会话(status=0 草稿)。attachments 仅持久化(R7)。createProject 是硬前置,返回空 gameId 视为移交失败。 requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/StudioDraftCreateReqVO' } responses: '200': description: 成功(新建会话,含回写的 gameId) content: application/json: schema: { $ref: '#/components/schemas/CommonResultStudioSession' } /app-api/studio/generate: post: tags: [app-studio] summary: 一句话生成(P-CRT-01,委托 aigc 提交生成) description: >- 编排:校验 session 归属 → 落任务链(status=1 生成中) → 委托 aigc AigcApi.submitGenerate(带 prompt/templateId/gameId/userId) → 回填 aigc_task_id → 立即返回任务链句柄,前端据 taskChainId 轮询。同步直写无 MQ(D4)。 attachments 仅持久化(R7),不入 aigc reqDTO。 requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/StudioGenerateReqVO' } responses: '200': description: 成功(任务链句柄,含 aigc_task_id) content: application/json: schema: { $ref: '#/components/schemas/CommonResultStudioTaskChain' } /app-api/studio/task/{id}: get: tags: [app-studio] summary: 进度轮询(P-CRT-12,透传 aigc 进度/状态) description: >- 编排:校验任务链归属 → 委托 aigc AigcApi.getTask 取进度/状态 → 映射链态 (aigc succeeded → 链完成回填 version_id + 会话完成;failed/timed_out → 链失败 + 会话失败;其余保持生成中仅回写 progress)。 parameters: - { name: id, in: path, required: true, schema: { type: integer, format: int64 }, description: '创作任务链 ID(taskChainId)' } responses: '200': description: 成功(任务链最新态,完成后 versionId 非空) content: application/json: schema: { $ref: '#/components/schemas/CommonResultStudioTaskChain' } /app-api/studio/task/{id}/regenerate: post: tags: [app-studio] summary: 重生成迭代(P-CRT-09,委托 aigc retryTask) description: 编排:校验原任务链归属 → 委托 aigc AigcApi.retryTask 重提生成 → 新建一条任务链(retry_of=原 id)回填新 aigc_task_id。 parameters: - { name: id, in: path, required: true, schema: { type: integer, format: int64 }, description: '原创作任务链 ID' } responses: '200': description: 成功(新建的重试任务链句柄) content: application/json: schema: { $ref: '#/components/schemas/CommonResultStudioTaskChain' } components: schemas: # ========== 请求 VO ========== StudioDraftCreateReqVO: type: object required: [title, templateId] properties: title: { type: string, maxLength: 128, description: '作品标题(透传 project createProject)', example: '我的放置小镇' } templateId: { type: string, description: '玩法模板 ID(透传 project/aigc)', example: 'idle' } prompt: { type: string, maxLength: 1000, description: '一句话 Prompt(建草稿可空,generate 必填)', example: '做一个躲避陨石的小游戏' } attachments: { type: string, description: '附件上下文 JSON(P-CRT-04);本波仅持久化,P1 透传 aigc' } StudioGenerateReqVO: type: object required: [sessionId, prompt] properties: sessionId: { type: integer, format: int64, description: '创作会话 ID(建草稿返回的 sessionId)', example: 1024 } prompt: { type: string, maxLength: 1000, description: '一句话 Prompt(透传 aigc submitGenerate)', example: '做一个躲避陨石的小游戏' } attachments: { type: string, description: '附件上下文 JSON(P-CRT-04);【本波仅持久化,P1 透传 aigc】——studio 侧落库持久化,本波不透传 aigc' } # ========== 响应 VO ========== StudioTemplateRespVO: type: object description: 玩法模板(透传 aigc 模板注册表,对齐 aigc.yaml TemplateRespVO) properties: templateId: { type: string, description: '模板 ID', example: 'dodge' } name: { type: string, description: '模板名称', example: '躲避' } description: { type: string, description: '模板说明' } coverUrl: { type: string, description: '模板封面/示意图 URL' } examplePrompt: { type: string, description: '示例 Prompt(P-CRT-11)', example: '做一个躲避陨石的小游戏' } StudioSessionRespVO: type: object properties: id: { type: integer, format: int64, description: '创作会话 ID(sessionId)', example: 1024 } gameId: { type: integer, format: int64, description: '移交后的游戏 ID(project.game_project.id)', example: 2048 } templateId: { type: string, description: '玩法模板 ID', example: 'idle' } title: { type: string, description: '作品标题', example: '我的放置小镇' } prompt: { type: string, description: '一句话 Prompt' } status: { type: integer, description: '会话状态:0草稿 1生成中 2完成 3失败', example: 0 } StudioTaskChainRespVO: type: object properties: id: { type: integer, format: int64, description: '创作任务链 ID(taskChainId,轮询用)', example: 1024 } sessionId: { type: integer, format: int64, description: '所属创作会话 ID', example: 512 } aigcTaskId: { type: integer, format: int64, description: '委托的 aigc 生成任务 ID', example: 8888 } gameId: { type: integer, format: int64, description: '关联游戏 ID(project.game_project.id)', example: 2048 } versionId: { type: integer, format: int64, description: '产物版本 ID(project.game_version.id);完成后非空', example: 4096 } status: { type: integer, description: '任务链状态:0初始 1生成中 2完成 3失败', example: 1 } progress: { type: integer, description: '进度百分比 0-100(透传 aigc)', example: 60 } retryOf: { type: integer, format: int64, description: '若为重生成,指向原任务链 ID(P-CRT-09 血缘)', example: 1000 } # ========== CommonResult 信封 ========== CommonResultStudioTemplateList: type: object properties: code: { type: integer, example: 0 } data: { type: array, items: { $ref: '#/components/schemas/StudioTemplateRespVO' } } msg: { type: string } CommonResultStudioSession: type: object properties: code: { type: integer, example: 0 } data: { $ref: '#/components/schemas/StudioSessionRespVO' } msg: { type: string } CommonResultStudioTaskChain: type: object properties: code: { type: integer, example: 0 } data: { $ref: '#/components/schemas/StudioTaskChainRespVO' } msg: { type: string }