Phase A 串行收口(主 agent 独占改黄金模块,11 单测绿),为 Phase B 并行建模块铺底:
- R1 publish 唯一化:submitPublish void→ProjectPublishRespVO{admitted,gates};门禁收集不抛、
block→admitted=false 不改状态机;compliance gate 留 Phase C 接入 seam(TODO,不 import)
- R2 ProjectApi seam 单点定稿:+getCurrentVersionId(GAP-3)/+createProject(写类RPC 显式 creatorUserId)
- GAP-4:events.schema.json 信封 envelope/user 由 snake→camelCase(与 telemetry/前端 SDK 对齐,破坏性窗口收敛)
- R4 治理:登记 studio=112/Flyway V8(README §4/§1/§2 + CLAUDE.md;与前端仓 game-studio 区分)
- R6 G0:V6/V7 集中复制到 yudao-server/db/migration(diff-identical)
- project.yaml publish 响应同步结构化;D2 锚点 reviewProject/game_review_record 未动
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
229 lines
9.1 KiB
YAML
229 lines
9.1 KiB
YAML
openapi: 3.0.3
|
||
# 契约 #1 API | 模块:project(黄金模板)| owner:WS1 lead 主笔,全员 review
|
||
# 端:/app-api(产品端 game-studio,用户 Token+DataPermission) /admin-api(管理端 game-admin,RBAC);前缀由 yudao 框架按 controller.app/admin 包名自动添加
|
||
# 错误码段:project = 1-100-***-***
|
||
# 响应统一 Yudao CommonResult 信封:{ code, data, msg };code=0 成功
|
||
info:
|
||
title: 绘境AI project 模块 API
|
||
version: 1.0.0
|
||
description: 游戏项目 CRUD / 状态机 / 版本 / 草稿 / 发布编排 / 审核 / 专区。前端据此 vite-plugin-mock 自动生成 mock。
|
||
|
||
servers:
|
||
- url: http://localhost:48080
|
||
description: 本地(Swagger/Knife4j http://localhost:48080/doc.html)
|
||
|
||
paths:
|
||
/app-api/project/my:
|
||
get:
|
||
tags: [app-project]
|
||
summary: 我的项目列表(创作者只见自己数据)
|
||
parameters:
|
||
- { name: status, in: query, required: false, schema: { type: integer }, description: 按状态机筛选 }
|
||
- { name: pageNo, in: query, required: false, schema: { type: integer, default: 1 } }
|
||
- { name: pageSize, in: query, required: false, schema: { type: integer, default: 10 } }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultProjectPage' }
|
||
|
||
/app-api/project:
|
||
post:
|
||
tags: [app-project]
|
||
summary: 创建项目(初始 status=0 草稿)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/ProjectCreateReqVO' }
|
||
responses:
|
||
'200':
|
||
description: 返回新建项目 ID
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultLong' }
|
||
|
||
/app-api/project/{id}:
|
||
get:
|
||
tags: [app-project]
|
||
summary: 项目详情
|
||
parameters:
|
||
- { name: id, in: path, required: true, schema: { type: integer, format: int64 } }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultProject' }
|
||
|
||
/app-api/project/{id}/draft:
|
||
put:
|
||
tags: [app-project]
|
||
summary: 保存草稿(仅 status=0 可改;标题/简介/封面/标签/适龄)
|
||
parameters:
|
||
- { name: id, in: path, required: true, schema: { type: integer, format: int64 } }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/ProjectDraftReqVO' }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultBoolean' }
|
||
|
||
/app-api/project/{id}/publish:
|
||
post:
|
||
tags: [app-project]
|
||
summary: 提交发布(发布前门禁聚合 → 进审核 BPM;统一发布编排 compliance→runtime→feed 失败回滚 ←G6)
|
||
description: >-
|
||
归属/草稿态为安全前置,失败抛异常(code≠0)。发布前门禁聚合为 gates:全部通过则 admitted=true 并置 status=1 审核中;
|
||
任一拦截则 admitted=false 且不改状态机(无副作用),创作者据 gates 修复后重提。
|
||
parameters:
|
||
- { name: id, in: path, required: true, schema: { type: integer, format: int64 } }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/ProjectPublishReqVO' }
|
||
responses:
|
||
'200':
|
||
description: 成功(含发布前门禁聚合结果 admitted + gates)
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultProjectPublish' }
|
||
|
||
/admin-api/project/review/page:
|
||
get:
|
||
tags: [admin-project]
|
||
summary: 审核队列(管理端 RBAC)
|
||
parameters:
|
||
- { name: status, in: query, required: false, schema: { type: integer }, description: 默认取 status=1 审核中 }
|
||
- { name: pageNo, in: query, required: false, schema: { type: integer, default: 1 } }
|
||
- { name: pageSize, in: query, required: false, schema: { type: integer, default: 10 } }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultProjectPage' }
|
||
|
||
/admin-api/project/review:
|
||
post:
|
||
tags: [admin-project]
|
||
summary: 审核决策(通过/拒绝/下架;锁风门 Gate 二态聚合)
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/ReviewReqVO' }
|
||
responses:
|
||
'200':
|
||
description: 成功
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/CommonResultBoolean' }
|
||
|
||
components:
|
||
schemas:
|
||
# ---- Yudao CommonResult 信封 ----
|
||
CommonResultBoolean:
|
||
type: object
|
||
properties:
|
||
code: { type: integer, description: '0=成功,非0=错误码 1-100-***-***' }
|
||
data: { type: boolean }
|
||
msg: { type: string }
|
||
CommonResultLong:
|
||
type: object
|
||
properties:
|
||
code: { type: integer }
|
||
data: { type: integer, format: int64, description: 新建项目 ID }
|
||
msg: { type: string }
|
||
CommonResultProject:
|
||
type: object
|
||
properties:
|
||
code: { type: integer }
|
||
data: { $ref: '#/components/schemas/ProjectRespVO' }
|
||
msg: { type: string }
|
||
CommonResultProjectPublish:
|
||
type: object
|
||
properties:
|
||
code: { type: integer }
|
||
data: { $ref: '#/components/schemas/ProjectPublishRespVO' }
|
||
msg: { type: string }
|
||
CommonResultProjectPage:
|
||
type: object
|
||
properties:
|
||
code: { type: integer }
|
||
data:
|
||
type: object
|
||
properties:
|
||
list: { type: array, items: { $ref: '#/components/schemas/ProjectRespVO' } }
|
||
total: { type: integer, format: int64 }
|
||
msg: { type: string }
|
||
|
||
# ---- 请求/响应 VO ----
|
||
ProjectCreateReqVO:
|
||
type: object
|
||
required: [title, templateId]
|
||
properties:
|
||
title: { type: string, maxLength: 60, description: 标题 }
|
||
templateId: { type: string, description: 玩法模板 ID }
|
||
ProjectDraftReqVO:
|
||
type: object
|
||
properties:
|
||
title: { type: string, maxLength: 60 }
|
||
summary: { type: string, maxLength: 500 }
|
||
coverUrl: { type: string }
|
||
tags: { type: array, items: { type: string }, maxItems: 10 }
|
||
ageRating: { type: string, enum: [all, '8+', '12+', '16+'] }
|
||
ProjectPublishReqVO:
|
||
type: object
|
||
required: [versionId, launchZoneId]
|
||
properties:
|
||
versionId: { type: integer, format: int64, description: 发布的版本 ID }
|
||
launchZoneId: { type: integer, format: int64, description: 发布去向专区(launchZone ←G1) }
|
||
GateResultVO:
|
||
type: object
|
||
required: [key, pass]
|
||
properties:
|
||
key: { type: string, description: '门禁键(稳定标识,如 age;Phase C 增 compliance)' }
|
||
label: { type: string, description: 门禁中文标签(展示用) }
|
||
pass: { type: boolean, description: 是否通过 }
|
||
code: { type: string, description: '拦截时错误码字符串(pass=true 时为 null;复用对应模块错误码段,不新增)' }
|
||
message: { type: string, description: 拦截时提示文案(pass=true 时为 null) }
|
||
ProjectPublishRespVO:
|
||
type: object
|
||
required: [admitted, gates]
|
||
properties:
|
||
admitted: { type: boolean, description: '是否准入(全部门禁通过=true;任一拦截=false 且不改状态机)' }
|
||
gates: { type: array, items: { $ref: '#/components/schemas/GateResultVO' }, description: 发布前门禁逐项结果 }
|
||
ReviewReqVO:
|
||
type: object
|
||
required: [gameId, versionId, decision]
|
||
properties:
|
||
gameId: { type: integer, format: int64 }
|
||
versionId: { type: integer, format: int64 }
|
||
decision: { type: integer, enum: [1, 2, 3], description: '1通过 2拒绝 3下架' }
|
||
reason: { type: string, maxLength: 500, description: 拒绝/下架理由(回填创作者) }
|
||
ProjectRespVO:
|
||
type: object
|
||
properties:
|
||
id: { type: integer, format: int64 }
|
||
title: { type: string }
|
||
summary: { type: string }
|
||
coverUrl: { type: string }
|
||
tags: { type: array, items: { type: string } }
|
||
templateId: { type: string }
|
||
ageRating: { type: string }
|
||
status: { type: integer, description: '0草稿 1审核中 2已通过 3已拒绝 4已发布 5已下架 6已封禁' }
|
||
currentVersionId: { type: integer, format: int64 }
|
||
launchZoneId: { type: integer, format: int64 }
|
||
featured: { type: boolean }
|
||
playCount: { type: integer, format: int64 }
|
||
likeCount: { type: integer, format: int64 }
|
||
createTime: { type: string, format: date-time }
|