zizi b70e90b775 feat(wave3-phaseB): compliance/studio 模块 + contractGaps(后端全绿)
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>
2026-06-09 02:15:20 +00:00

219 lines
11 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

openapi: 3.0.3
# 契约 #1 API | 模块:compliance(game-module-compliance,Wave3 合规域「锁风门 Gate」)| owner:Wave3 compliance 子 agent 主笔,全员 review
# 职责(架构 Doc B + D2 范围铁律):只做 Gate——发布前合规扫描(聚合风格/IP 原子→verdict)+ 内容分级 + 封禁台账。
# 【明确不做】审核状态机:审核状态机权威归 project(game_review_record),compliance 绝不重写(D2)。
# seam(R1):compliance 只交付 ComplianceGateApi.evaluate 供 project.submitPublish 同进程注入(block→admitted=false 不抛异常);
# 不自改 submitPublish、不自登记 publish-blocked 错误码(那条文案由 project 侧 GateResultVO.code 携带)。
# 封禁(R3 状态分支):写 game_user_ban 台账=主操作恒执行;下架联动仅当游戏==PUBLISHED 时才调 project 状态机;
# 本波 ProjectApi 暂无 reviewProject seam,下架联动标 TODO 留 Phase C 主 agent 收口(只写台账、不裸调不存在的方法)。
# 降权(R5):降权出流屏蔽 P1 本波不生效(不建 FeedDownweightApi 孤儿 seam、不调 feed)。
# IP(D5):ip 不独立建模块,仅在 compliance 内留 IpComplianceSeam 扩展点(默认 pass 桩),Wave4 接 ip 只换实现。
# 端:/rpc-api(project.publish 同进程 Feign 注入)/ /admin-api(管理端 game-admin,RBAC 封禁)/ /app-api(产品端只读分级);前缀由 yudao 框架按 controller 包名/RpcConstants 自动添加
# 错误码段:compliance = 1-109-***-***(本模块独占,禁止与他模块重叠:100 project/101 aigc/102 runtime/103 feed/104 telemetry/106 trade/111 ad/112 studio)
# publish-blocked 不在本模块登记(R1:block→admitted=false 不抛异常)。
# 响应统一 Yudao CommonResult 信封:{ code, data, msg };code=0 成功
info:
title: 造梦AI compliance 模块 API
version: 1.0.0
description: >-
合规锁风门 Gate("做得出"安全闸门)。project.publish 发布前同步调 evaluate → 聚合风格/IP 合规原子产出 verdict
(pass/review/block)+ 落锁风门台账 + 落内容分级;block 则 project 置 admitted=false(不抛异常)。
封禁台账供 admin 处置游戏/用户;下架联动按 project 状态分支(本波 TODO 留 Phase C)。MVP 合规原子全 mock 桩(默认 pass)。
servers:
- url: http://localhost:48080
description: 本地(Swagger/Knife4j http://localhost:48080/doc.html)
paths:
# ===========================================================================
# RPC 端 /rpc-api(project.publish 同进程注入,唯一 seam,R1)
# ===========================================================================
/rpc-api/compliance/evaluate:
post:
tags: [rpc-compliance]
summary: 锁风门评估(project.publish 注入用,R1 唯一形态)
description: >-
project.submitPublish 发布前同步调;聚合风格/IP 合规原子产出 verdict = max(各原子)(block>review>pass),
落 game_compliance_gate_result 审计台账 + upsert game_content_rating 分级。
block 仍正常返回 verdict(不抛异常),由 project 侧据此置 admitted=false。
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/ComplianceGateReqDTO' }
responses:
'200':
description: 聚合裁决
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultGateVerdict' }
# ===========================================================================
# 管理端 /admin-api(封禁台账,RBAC,R3 状态分支)
# ===========================================================================
/admin-api/compliance/ban/create:
post:
tags: [admin-compliance]
summary: 创建封禁(写台账=主操作恒执行;游戏下架联动按 project 状态分支)
description: >-
落 game_user_ban(主操作恒执行,同目标生效中封禁查重 uk_target_active)。
R3 下架联动:targetType=游戏 且 game.status==PUBLISHED 时才调 project reviewProject(decision=3);
非 PUBLISHED 只记封禁、不调状态机、不抛异常。【本波】ProjectApi 暂无 reviewProject seam,下架联动 TODO 留 Phase C。
R5 降权出流屏蔽 P1 本波不生效(不调 feed)。
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/BanCreateReqVO' }
responses:
'200':
description: 新建封禁台账 ID
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultLong' }
/admin-api/compliance/ban/cancel:
post:
tags: [admin-compliance]
summary: 解封(status 1→0)
description: 按 banId 解封;记录不存在或已解封报 COMPLIANCE_BAN_NOT_EXISTS。
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/BanCancelReqVO' }
responses:
'200':
description: 是否成功
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultBoolean' }
/admin-api/compliance/ban/page:
get:
tags: [admin-compliance]
summary: 封禁台账分页(admin RBAC)
parameters:
- { name: pageNo, in: query, required: true, schema: { type: integer, default: 1 } }
- { name: pageSize, in: query, required: true, schema: { type: integer, default: 10 } }
- { name: targetType, in: query, required: false, schema: { type: integer }, description: '目标类型过滤:1 游戏/2 用户' }
- { name: status, in: query, required: false, schema: { type: integer }, description: '状态过滤:1 生效/0 已解封' }
responses:
'200':
description: 分页结果
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultPageUserBan' }
# ===========================================================================
# 产品端 /app-api(内容分级只读,用户/匿名 Token)
# ===========================================================================
/app-api/compliance/rating/get:
get:
tags: [app-compliance]
summary: 取内容分级(只读)
description: 按游戏+版本读分级(all/8+/12+/16+);无记录报 COMPLIANCE_RATING_NOT_FOUND。分级写入仅由 Gate evaluate + admin 复核产生。
parameters:
- { name: gameId, in: query, required: true, schema: { type: integer, format: int64 } }
- { name: versionId, in: query, required: false, schema: { type: integer, format: int64 }, description: '无版本传 0' }
responses:
'200':
description: 内容分级
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultContentRating' }
components:
schemas:
# ===== 锁风门 Gate(RPC seam,R1 唯一形态)=====
ComplianceGateReqDTO:
type: object
required: [gameId, versionId]
properties:
gameId: { type: integer, format: int64, description: '游戏项目 ID(锁风门定位锚点)' }
versionId: { type: integer, format: int64, description: '待发布版本 ID' }
title: { type: string, description: '标题(风格原子参考,可空)' }
summary: { type: string, description: '摘要(风格原子参考,可空)' }
ageRating: { type: string, description: '适龄分级建议:all/8+/12+/16+' }
promptHash: { type: string, description: '生成 Prompt 摘要(合规溯源,可空)' }
GateVerdict: # = 草案 ComplianceGateRespDTO,R1 命名对齐
type: object
required: [verdict]
properties:
verdict: { type: string, enum: [pass, review, block], description: '聚合裁决 = max(各原子),block>review>pass' }
rating: { type: string, description: '本次评估落定的内容分级' }
detail: { type: array, items: { $ref: '#/components/schemas/ComplianceGateItemDTO' } }
ComplianceGateItemDTO:
type: object
properties:
atom: { type: string, description: '原子标识:textContent/imageContent/ip-reserved' }
verdict: { type: string, enum: [pass, review, block] }
reason: { type: string, description: '裁决原因(pass 可空)' }
# ===== 封禁(admin,R3 状态分支)=====
BanCreateReqVO:
type: object
required: [targetType, targetId]
properties:
targetType: { type: integer, description: '封禁目标类型:1 游戏 / 2 用户' }
targetId: { type: integer, format: int64, description: '封禁目标 ID(游戏=game_id / 用户=user_id)' }
banType: { type: integer, description: '处置类型:1 封禁 / 2 降权(P1 本波不生效)' }
reason: { type: string, description: '封禁/降权原因' }
BanCancelReqVO:
type: object
required: [banId]
properties:
banId: { type: integer, format: int64, description: '封禁台账记录 ID' }
UserBanRespVO:
type: object
properties:
id: { type: integer, format: int64 }
targetType: { type: integer, description: '1 游戏 / 2 用户' }
targetId: { type: integer, format: int64 }
banType: { type: integer, description: '1 封禁 / 2 降权' }
status: { type: integer, description: '1 生效 / 0 已解封' }
reason: { type: string }
createTime: { type: string, format: date-time }
# ===== 分级(app 只读)=====
ContentRatingRespVO:
type: object
properties:
rating: { type: string, description: 'all/8+/12+/16+' }
ratedBy: { type: string, description: 'gate 锁风门自动 / admin 人工复核' }
updateTime: { type: string, format: date-time }
# ===== CommonResult 信封 =====
CommonResultGateVerdict:
type: object
properties:
code: { type: integer }
data: { $ref: '#/components/schemas/GateVerdict' }
msg: { type: string }
CommonResultContentRating:
type: object
properties:
code: { type: integer }
data: { $ref: '#/components/schemas/ContentRatingRespVO' }
msg: { type: string }
CommonResultPageUserBan:
type: object
properties:
code: { type: integer }
data:
type: object
properties:
list: { type: array, items: { $ref: '#/components/schemas/UserBanRespVO' } }
total: { type: integer, format: int64 }
msg: { type: string }
CommonResultLong:
type: object
properties:
code: { type: integer }
data: { type: integer, format: int64 }
msg: { type: string }
CommonResultBoolean:
type: object
properties:
code: { type: integer }
data: { type: boolean }
msg: { type: string }