Phase B 并行建(4 路互斥目录),主 agent 合并 reactor 验证: - compliance(109/V9):ComplianceGateApi.evaluate seam + 风格原子桩(StyleComplianceAtom/IpComplianceSeam) + 分级 + 封禁(R3 状态分支,下架联动留 Phase C)+ V9 DDL(gate_result/content_rating/user_ban,不建审核状态机表 D2) - studio(112/V8):创作任务链(createDraft→project.createProject / generate→aigc)+ attachments 持久化-only + 新增 AigcApi seam(additive)+ V8 DDL - contractGaps 后端:GAP-3 feed ShareMeta versionId(调 getCurrentVersionId 仅已发布)、GAP-2 runtime manifestUrl(纯派生零DDL) - contractGaps 前端 game-studio:GAP-1 publish admitted/gates、GAP-3 share→play versionId、GAP-2 取包 manifestUrl+sha256 - 合并验证:全 53 模块 reactor 编译 SUCCESS;新/改模块单测全绿(compliance8/studio11/feed12/runtime24) - 注:前端 game-studio build 待 mini-desktop 验;Phase C 待接入 project.publish→ComplianceGateApi Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
187 lines
11 KiB
YAML
187 lines
11 KiB
YAML
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 }
|