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>
219 lines
11 KiB
YAML
219 lines
11 KiB
YAML
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 }
|