fix(flyway): 删 5 个 module 迁移重复副本——消同版本重复致 dev/2.0.0 启动失败(P0 #3)

Flyway 在 classpath 撞同版本即拒启(Found more than one migration with version):V6/7/8/9/18 既在
huijing-server 聚合(V1-V25,已应用到 live = 单一事实源)又各在 module-server 重复(06-18 各 lane 加功能误放)。
删 module 副本、留 huijing-server 聚合:
- V6/V8/V9/V18 两边 md5 完全一致 = 纯去重
- V7(trade) 仅注释差异(列定义同;game_trade_grant 表在 V21 不在 V7)→ 留 huijing-server 已应用版
  (改已应用迁移会 checksum 漂移;module 副本的注释改动弃)
全仓扫描:删后无重复版本、无 module-only 迁移(30=25 聚合+5 副本)。库停 V17 未污染。
注:依赖自身 db/migration 的 module 测试若存在需后续改 test-scoped schema(本修以解 boot 为先,redeploy -DskipTests 不受影响)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
lili 2026-06-19 05:55:09 -07:00
parent de3bf4cb62
commit ff46b90ee7
5 changed files with 0 additions and 420 deletions

View File

@ -1,77 +0,0 @@
-- =============================================================================
-- 契约 #2 DB 迁移 | 模块adgame-module-adWave2 变现域「广告引擎」)| ownerWS5
-- 文件V6.0.0__create_game_ad.sqlFlyway只新增已合入禁止修改回滚写新补偿迁移
-- 内容ad 模块核心表 —— 广告位配置 game_ad_slot对齐契约#7+ 广告收入台账 game_ad_revenuead↔trade seam 数据源)
-- 职责(架构 Doc B联盟接入/广告位 AI 植入/曝光计费/eCPM/归因;不做结算提现(归 trade。MVP provider 默认 mock。
-- 脊柱钱财闭环上游SDK 拉广告位 → 有效曝光/激励完成计费上报(幂等) → mock eCPM 计收入 → 落 game_ad_revenue(settle_status=0)
-- → trade 经 AdRevenueApi.getUnsettledRevenue 拉取做 T+1 分账 → markSettled 回标 settle_status=1seam 详见 ad.yaml x-feign-contracts
-- 计费 vs 分析埋点:本模块台账=计费级(决定收入),区别于 telemetry(#5 ad_impression/ad_reward) 分析埋点(仅统计),二者并存口径不同
-- 约定InnoDB + utf8mb4显式列含 Yudao 审计列 creator/create_time/updater/update_time/deleted + tenant_id
-- 金额一律「分」(BIGINT),禁浮点;状态机用 tinyint非法流转由 Service 校验DO 层不承载;中文列注释;关键查询建索引、禁裸 select*。
-- 错误码段ad = 1-111-***-***
-- =============================================================================
-- -----------------------------------------------------------------------------
-- 表game_ad_slot —— 广告位配置表(字段严格对齐契约#7 ad-slot.schema.json
-- 用途admin CRUD 维护SDK Plugin.Ad 拉 enabled=true 广告位渲染(/app-api/ad/slot/list-enabled
-- Provider SPIprovider=mock 走桩MVP 默认csj 穿山甲 / gdt 优量汇 走审核闸门后由人填 provider_slot_id 注入
-- 唯一键slot_id 业务唯一uk_slot埋点 ad_impression.slot_id 与计费上报均引用此逻辑 ID
-- compliance未成年人保护拆为显式列 block_minor / max_per_session不用 JSON 整块存(便于查询与计费限流)
-- -----------------------------------------------------------------------------
CREATE TABLE `game_ad_slot` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '广告位主键 ID',
`slot_id` VARCHAR(64) NOT NULL COMMENT '广告位逻辑 ID平台内唯一对齐契约#7 slotId埋点/计费上报均引用)',
`type` VARCHAR(16) NOT NULL DEFAULT 'rewarded' COMMENT '广告形式(对齐#7 typerewarded 激励视频/interstitial 插屏/banner 横幅',
`provider` VARCHAR(16) NOT NULL DEFAULT 'mock' COMMENT '联盟(对齐#7 providerSPI AdProvidercsj 穿山甲/gdt 优量汇/mock 桩MVP 默认)',
`placement` VARCHAR(16) NOT NULL DEFAULT 'game_end' COMMENT '触发场景(对齐#7 placementgame_end 本局结束/pause 暂停/feed 游戏流间隙',
`provider_slot_id` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '联盟侧真实广告位 ID对齐#7 providerSlotIdprovider!=mock 时由人提供——审核闸门后注入;不下发前端明文)',
`ecpm_floor` BIGINT NOT NULL DEFAULT 0 COMMENT 'eCPM 底价(单位:分,对齐#7 ecpmFloor低于此不展示mock 计费亦用此算单次收入',
`enabled` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否启用(对齐#7 enabled0停用 1启用SDK 只拉启用项',
`block_minor` BIT(1) NOT NULL DEFAULT b'1' COMMENT '合规:识别为未成年则不展示/不计费(对齐#7 compliance.blockMinor默认 1=拦截)',
`max_per_session` INT NOT NULL DEFAULT 0 COMMENT '合规:单会话最大展示次数(对齐#7 compliance.maxPerSession0=不限;计费上报按此限流)',
`creator` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建者Yudao 审计列)',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '逻辑删除0未删 1已删',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户 IDYudao 多租户兼容MVP 单租户=0',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_slot` (`slot_id`, `deleted`, `tenant_id`) COMMENT '广告位逻辑 ID 业务唯一键(含 deleted/tenant_id 适配 Yudao 逻辑删除+多租户,避免软删后无法复用 slot_id',
KEY `idx_enabled` (`enabled`, `placement`) COMMENT 'SDK 按启用+场景拉广告位list-enabled',
KEY `idx_provider` (`provider`, `type`) COMMENT '管理端按联盟+形式分页/筛选'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '广告位配置表(对齐契约#7admin CRUD + SDK 拉取)';
-- -----------------------------------------------------------------------------
-- 表game_ad_revenue —— 广告收入台账(有效曝光/激励计费产出ad↔trade seam 的数据源)
-- 用途计费上报impression/reward按 mock eCPM 算收入落账trade 按 settle_status=0 拉取做 T+1 分账
-- 收入归因creator_user_id = 由 game_id 反查 project.game_project.creator_user_id收入归到游戏作者trade 按此聚合分账)
-- 幂等核心uk_trace=(trace_id,event_type),同 (trace_id,event_type) 重复上报只计一条(计费幂等);同一 trace_id 的 impression 与 reward 各落一条、互不覆盖(防 reward 被 impression 静默吞掉=丢账)
-- 收入口径避免同一次展示重复计收入type=rewarded 收入计在 rewardimpression 若上报则 revenue_amount=0type=interstitial/banner 收入计在 impression。event_type 仅区分计费事件,不对同一次展示重复计收入
-- 结算状态机 settle_status0未结算 → 1已结算trade 分账入账成功后经 AdRevenueApi.markSettled 回标,幂等;非法回退由 Service 拒绝)
-- 扫描入口trade 的 getUnsettledRevenue(statDate) 按 (settle_status=0, stat_date) 命中 idx_settle_date 扫描,禁裸 select*
-- 金额单位ecpm / revenue_amount 一律「分」(BIGINT),禁浮点
-- -----------------------------------------------------------------------------
CREATE TABLE `game_ad_revenue` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '广告收入台账记录 ID= trade 侧 game_trade_income.source_ref 对账锚点)',
`slot_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '广告位逻辑 ID= game_ad_slot.slot_id',
`game_id` BIGINT NOT NULL COMMENT '产生收入的游戏 IDproject.game_project.id',
`creator_user_id` BIGINT NOT NULL COMMENT '收入归因到的创作者用户 ID由 game_id 反查 game_project.creator_user_idtrade 按此聚合分账)',
`event_type` TINYINT NOT NULL DEFAULT 1 COMMENT '计费事件类型1 impression 有效曝光 / 2 reward 激励完成',
`provider` VARCHAR(16) NOT NULL DEFAULT 'mock' COMMENT '产生收入的联盟csj/gdt/mock与广告位 provider 一致)',
`ecpm` BIGINT NOT NULL DEFAULT 0 COMMENT 'eCPM单位mock 取广告位 ecpm_floor',
`revenue_amount` BIGINT NOT NULL DEFAULT 0 COMMENT '本条广告收入单位BIGINT金额一律用分禁浮点mock=ecpm/1000 向下取整)',
`trace_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '全链路追踪 ID与 event_type 组成计费幂等键 uk_trace透传到 trade.trace_id 供端到端对账',
`settle_status` TINYINT NOT NULL DEFAULT 0 COMMENT '结算状态机0未结算 1已结算trade 分账后经 markSettled 回标 1非法回退由 Service 拒绝)',
`stat_date` DATE NOT NULL COMMENT '归集日yyyy-MM-dd按日归集供 trade 按日扫未结算做 T+1 分账)',
`creator` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建者Yudao 审计列;计费上报为 system/上报方)',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间(计费入账时间)',
`updater` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '更新者trade 回标时为结算 job',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '逻辑删除0未删 1已删',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户 IDYudao 多租户兼容MVP 单租户=0',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_trace` (`trace_id`, `event_type`, `tenant_id`) COMMENT '计费幂等键:(trace_id+event_type) 唯一——同 (trace_id,event_type) 重复上报只落一条(计费幂等);同一 trace_id 的 impression 与 reward 各计一条、不互相覆盖(防 reward 被 impression 静默吞掉)',
KEY `idx_settle_date` (`settle_status`, `stat_date`) COMMENT 'trade 扫未结算做 T+1 分账getUnsettledRevenue 按 settle_status=0 + stat_date 扫描)',
KEY `idx_creator_date` (`creator_user_id`, `stat_date`) COMMENT '按创作者+归集日聚合分账/对账',
KEY `idx_game` (`game_id`, `stat_date`) COMMENT '按游戏查收入(归因/计费对账)'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '广告收入台账表计费产出ad↔trade seam 数据源settle_status 供 trade 分账)';

View File

@ -1,84 +0,0 @@
-- =============================================================================
-- 契约 #2 DB 迁移 | 模块compliancegame-module-complianceWave3 合规域「锁风门 Gate」| ownerWave3 compliance 子 agent
-- 文件V9.0.0__create_game_compliance.sqlFlyway只新增已合入禁止修改回滚写新补偿迁移 V9.0.1 DROP TABLE
-- 内容compliance 模块三张表 —— 锁风门评估台账 game_compliance_gate_result + 内容分级 game_content_rating + 封禁台账 game_user_ban
-- 职责(架构 Doc B + D2 范围铁律):只做 Gate聚合风格/IP 原子→verdict + 内容分级 + 封禁台账);
-- 【明确不建】审核状态机表 / audit_record —— 审核状态机权威归 projectgame_review_recordcompliance 绝不重写。
-- 锁风门 seamR1project.submitPublish 同进程调 ComplianceGateApi.evaluate → 聚合裁决落 game_compliance_gate_result + 分级落 game_content_rating
-- → 返回 verdict 供 project 据此置 admittedblock→admitted=false 不抛异常)。
-- 封禁联动R3 状态分支):写 game_user_ban 台账(主操作恒执行);下架仅当 project 状态==PUBLISHED 时才调 project reviewProject(3)
-- 非 PUBLISHED 只记封禁不调状态机。【本波说明】ProjectApi 暂无 reviewProject seam下架联动标 TODO 留 Phase C 主 agent 收口,本波仅写台账。
-- 降权出流屏蔽P1 本波不生效R5不建 FeedDownweightApi 孤儿 seam
-- 约定InnoDB + utf8mb4显式列含 Yudao 审计列 creator/create_time/updater/update_time/deleted + tenant_id
-- 状态机用 tinyint非法流转由 Service 校验DO 层不承载;中文列注释;关键查询建索引、禁裸 select*。
-- 错误码段compliance = 1-109-***-***
-- =============================================================================
-- -----------------------------------------------------------------------------
-- 表game_compliance_gate_result —— 锁风门评估台账(每次 publish 评估各落一条,审计/溯源用)
-- 用途project.publish 注入 evaluate 时落聚合裁决 + 各原子明细 JSONadmin 复核与合规溯源据此查
-- 写口径非幂等每次评估各落一条审计记录不去重verdict 为聚合结果 max(各原子)
-- -----------------------------------------------------------------------------
CREATE TABLE `game_compliance_gate_result` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '锁风门评估记录 ID',
`game_id` BIGINT NOT NULL COMMENT '评估的游戏 IDproject.game_project.id',
`version_id` BIGINT NOT NULL DEFAULT 0 COMMENT '评估的版本 ID待发布版本无版本时为 0',
`verdict` VARCHAR(16) NOT NULL DEFAULT 'pass' COMMENT '聚合裁决pass 通过/review 需人工复核/block 拦截(= max(各原子)',
`rating` VARCHAR(16) NOT NULL DEFAULT '' COMMENT '本次评估落定的内容分级all/8+/12+/16+(可空)',
`details` VARCHAR(2048) NOT NULL DEFAULT '' COMMENT '各合规原子明细 JSON[{atom,verdict,reason}],便于复核溯源)',
`trace_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '全链路追踪 ID与 publish 链路对账)',
`creator` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建者Yudao 审计列;锁风门评估为 system/发布发起方)',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间(评估时间)',
`updater` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '逻辑删除0未删 1已删',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户 IDYudao 多租户兼容MVP 单租户=0',
PRIMARY KEY (`id`),
KEY `idx_game_version` (`game_id`, `version_id`) COMMENT '按游戏+版本查最近一次锁风门评估(复核/溯源)'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '锁风门评估台账(每次 publish 评估落一条,聚合裁决+原子明细;审计/溯源)';
-- -----------------------------------------------------------------------------
-- 表game_content_rating —— 内容分级表(按游戏+版本唯一评估时落、admin 复核可改)
-- 用途:/app-api/compliance/rating/get 读分级;分级写入仅由 Gate evaluate 落定 + admin 复核产生
-- 唯一键:(game_id,version_id) 业务唯一(含 deleted/tenant_id 适配逻辑删+多租户),同游戏同版本只存一条最新分级
-- -----------------------------------------------------------------------------
CREATE TABLE `game_content_rating` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '内容分级记录 ID',
`game_id` BIGINT NOT NULL COMMENT '游戏 IDproject.game_project.id',
`version_id` BIGINT NOT NULL DEFAULT 0 COMMENT '版本 ID无版本时为 0',
`rating` VARCHAR(16) NOT NULL DEFAULT 'all' COMMENT '内容分级all 全年龄/8+/12+/16+',
`rated_by` VARCHAR(32) NOT NULL DEFAULT 'gate' COMMENT '分级来源gate 锁风门自动/admin 人工复核',
`creator` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建者Yudao 审计列)',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '更新者admin 复核改分级时记录)',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '逻辑删除0未删 1已删',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户 IDYudao 多租户兼容MVP 单租户=0',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_game_version` (`game_id`, `version_id`, `deleted`, `tenant_id`) COMMENT '游戏+版本分级业务唯一键(含 deleted/tenant_id 适配逻辑删+多租户)'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '内容分级表(评估落定+admin 复核;/app-api 只读取)';
-- -----------------------------------------------------------------------------
-- 表game_user_ban —— 封禁台账(封禁/降权的权威台账;主操作恒执行)
-- 用途admin 封禁游戏/用户落台账恒执行R3 下架联动仅当游戏==PUBLISHED 时才调 project 状态机(本波标 TODO
-- R5 降权出流屏蔽 P1 本波不生效(不建 feed seam
-- 唯一键:(target_type,target_id,status) 生效中唯一status=1 生效,含 deleted/tenant_id同目标不可重复生效封禁解封后(status=0)可再次封禁
-- 状态机 status1 生效 → 0 已解封(解封由 admin 触发Service 校验合法流转)
-- -----------------------------------------------------------------------------
CREATE TABLE `game_user_ban` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '封禁台账记录 ID',
`target_type` TINYINT NOT NULL COMMENT '封禁目标类型1 游戏 / 2 用户',
`target_id` BIGINT NOT NULL COMMENT '封禁目标 ID游戏=game_id / 用户=user_id',
`ban_type` TINYINT NOT NULL DEFAULT 1 COMMENT '处置类型1 封禁(下架/禁用)/ 2 降权出流屏蔽P1 本波不生效)',
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '封禁状态机1 生效 / 0 已解封(合法流转由 Service 校验)',
`reason` VARCHAR(512) NOT NULL DEFAULT '' COMMENT '封禁/降权原因(合规处置说明)',
`creator` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建者Yudao 审计列;封禁操作的 admin userId',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间(封禁时间)',
`updater` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '更新者(解封操作的 admin userId',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '逻辑删除0未删 1已删',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户 IDYudao 多租户兼容MVP 单租户=0',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_target_active` (`target_type`, `target_id`, `status`, `deleted`, `tenant_id`) COMMENT '生效中封禁业务唯一键:同目标 status=1 不可重复(含 deleted/tenant_id 适配逻辑删+多租户)',
KEY `idx_type_status` (`target_type`, `status`) COMMENT 'admin 按目标类型+状态分页查封禁台账'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '封禁台账表(封禁/降权权威台账;主操作恒执行,下架联动按 project 状态分支)';

View File

@ -1,49 +0,0 @@
-- =============================================================================
-- 契约 #2 DB 迁移 | 模块studiogame-module-studio| owner后端线6c6g 编辑 / mini-desktop 验迁移)
-- 文件V18.0.0__create_game_source_project.sqlFlyway只新增接 V17.0.0 之后;
-- 已合入禁止修改,回滚写新补偿迁移 V18.0.1 DROP TABLE遵 V2.0.0/V17 头注铁律)
-- 背书HJ 固定架构+SAA agentic studio execution §5.22026-06-17——「源项目存储=独立 game_source_project 表,勿塞 game_version」。
-- 内容:新增源项目工件表 game_source_project —— 生成主线「改源不改打包产物」基座的源侧存储面(与 GamePackage 产物面解耦)。
-- 范式(生命周期项目模型):游戏 = 长生命周期源项目LLM as 工作室);本表存「可维护的结构化源项目工件」
-- SourceProject schema = contracts/agent-loop/source-project.schema.json构建产物bundle/manifest仍存
-- game_version + game_runtime_packageGamePackage 产物 schema 不变)。
-- 边界纪律:
-- - 源/产物物理解耦源项目存本表additive 新存储面),打包产物存 game_version既冻 GamePackage schema 不变);勿把源字段塞进 game_version。
-- - 版本产物权威仍归 projectgame_version本表 version_id 仅持引用(构建成功建包后回填),不在本模块建版本表。
-- - 事务边界化解孤儿execution §5.2):源落库(status=0) → 触发确定性构建 → 成功建 preview package 回填 version_id+status=1
-- 失败 status=2(孤儿)、不建包、不动 currentVersion。源落库与建包非同一大事务构建数十秒级长事务=连接池杀手),用 status 机器态串联。
-- - modify「改源不改产物」base_version_id 记血缘create 时 NULLmodify 产新源行 → 新预览版,不动 currentVersion、不自动入 feed走发布审核。
-- 约定InnoDB + utf8mb4显式列含 Yudao 审计列 creator/create_time/updater/update_time/deleted + tenant_id
-- 状态机用 tinyint非法流转由 Service 校验DO 层不承载;中文列注释;关键查询建索引、禁裸 select*。
-- 错误码段studio = 1-112-***-***(本迁移不引入新错误码)。
-- =============================================================================
-- -----------------------------------------------------------------------------
-- 表game_source_project —— 游戏源项目工件表(改源不改产物的源侧存储面)
-- 用途studio 工作室编排create/modify/extend产出的结构化源项目工件落库构建从源重新产出字节等价 bundle可寻址/幂等/可复现)。
-- 可寻址/幂等source_hash = 源规范化 sha256= SourceProject.sourceHash按 game_id 查历史、按 version_id 反查源、按 source_hash 去重。
-- 源态 status0 草稿 → 1 已构建(建包回填 version_id / 2 孤儿(构建失败,不建包) / 3 已发布。
-- M0 存储source_json 走 DBLONGTEXT大资产经 ref 外置;切对象存储后改用 source_url与 source_json 二选一)。
-- -----------------------------------------------------------------------------
CREATE TABLE `game_source_project` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '源项目工件 ID',
`game_id` BIGINT NOT NULL COMMENT '所属游戏 IDproject.game_project.id',
`version_id` BIGINT NULL DEFAULT NULL COMMENT '关联产物版本 IDproject.game_version.id构建成功建包后回填失败留 NULL=孤儿',
`source_json` LONGTEXT NULL COMMENT '源项目工件 JSONSourceProject schemaM0 走 DB大资产经 ref 外置)',
`source_url` VARCHAR(512) NOT NULL DEFAULT '' COMMENT '源项目对象存储 URL切对象存储后用与 source_json 二选一)',
`source_hash` CHAR(64) NOT NULL DEFAULT '' COMMENT '源规范化 sha256可寻址/幂等键;= SourceProject.sourceHash',
`schema_version` VARCHAR(16) NOT NULL DEFAULT '1.0' COMMENT '源项目契约版本(独立于 GamePackage 版本)',
`build_profile` VARCHAR(64) NOT NULL DEFAULT 'default' COMMENT '构建画像(目标引擎/优化档;= buildProfile影响 buildInputHash',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '源态0草稿 1已构建 2孤儿(构建失败) 3已发布Service 校验流转)',
`base_version_id` BIGINT NULL DEFAULT NULL COMMENT 'modify 血缘:本源派生自的 base 版本 IDcreate 时 NULL',
`creator` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建者Yudao 审计列)',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '逻辑删除0未删 1已删',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户 IDYudao 多租户兼容MVP 单租户=0',
PRIMARY KEY (`id`),
KEY `idx_game` (`game_id`, `id`) COMMENT '按游戏查源项目历史(按 id 倒序)',
KEY `idx_version` (`version_id`) COMMENT '按产物版本反查源',
KEY `idx_source_hash` (`source_hash`) COMMENT '可寻址/幂等去重'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '游戏源项目工件表(改源不改产物;与 game_version 产物面解耦)';

View File

@ -1,92 +0,0 @@
-- =============================================================================
-- 契约 #2 DB 迁移 | 模块studiogame-module-studioWave3 创作主链路最小版)| ownerstudio 路
-- 文件V8.0.0__create_game_studio.sqlFlyway只新增已合入禁止修改回滚写新补偿迁移 V8.0.1 DROP TABLE
-- 内容studio 模块核心表 —— 创作会话 game_studio_session + 创作任务链 game_studio_taskchain + 资产槽位 game_studio_asset
-- 职责(架构 Doc B §71-76有状态创作工作台后端。编排「建草稿(委托 project createProject)→一句话生成(委托 aigc)
-- →进度轮询→重生成→模板应用」。不跑 LLM委托 aigc、不持久化项目版本交 project、不做锁风裁决调 compliance
-- 边界纪律:
-- - 项目/版本权威归 projectgame_project / game_versionstudio 仅持 game_id/version_id 引用,不在本模块建版本表。
-- - 生成任务权威归 aigcgame_aigc_taskstudio 任务链仅持 aigc_task_id 引用 + 自身链态,不在本模块重建生成状态机。
-- - attachments 本波仅持久化R7不透传 aigcaigc reqDTO 无 attachments 字段)。
-- - MVP 进度推送走轮询D4非 MQ/SSE。
-- 约定InnoDB + utf8mb4显式列含 Yudao 审计列 creator/create_time/updater/update_time/deleted + tenant_id
-- 状态机用 tinyint非法流转由 Service 校验DO 层不承载;中文列注释;关键查询建索引、禁裸 select*。
-- 错误码段studio = 1-112-***-***
-- =============================================================================
-- -----------------------------------------------------------------------------
-- 表game_studio_session —— 创作会话表(有状态创作工作台主记录,对齐 P-CRT-10 进工作坊)
-- 用途:创作者进工作坊 upsert 一条会话承载草稿入参title/prompt/templateId/attachments+ 移交后的 game_id。
-- 移交createDraft 调 project ProjectApi.createProject 拿 gameId 回写本表 game_id草稿移交 projectP-TPL-03
-- attachmentsJSON 持久化(本波仅持久化不透传 aigcR7
-- 状态机 status0 草稿 → 1 生成中 → 2 完成 / 3 失败StudioSessionStatusEnum由 generate/getTask 透传 aigc 终态映射)。
-- -----------------------------------------------------------------------------
CREATE TABLE `game_studio_session` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '创作会话 ID',
`creator_user_id` BIGINT NOT NULL COMMENT '创作者用户 ID业务字段DataPermission创作者只见自己会话。区别于审计列 creator',
`game_id` BIGINT NULL DEFAULT NULL COMMENT '移交后的游戏 IDproject.game_project.idcreateDraft 调 createProject 后回写',
`template_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '玩法模板 ID透传 aigc如 dodge/runner/clicker/puzzle/shooter',
`title` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '作品标题(建草稿入参,透传 project createProject',
`prompt` VARCHAR(1000) NOT NULL DEFAULT '' COMMENT '一句话自然语言 Prompt透传 aigc submitGenerate',
`attachments` JSON NULL DEFAULT NULL COMMENT '附件上下文P-CRT-04JSON 数组本波仅持久化P1 透传 aigc',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '会话状态机0草稿 1生成中 2完成 3失败StudioSessionStatusEnumService 校验流转)',
`creator` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建者Yudao 审计列)',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '逻辑删除0未删 1已删',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户 IDYudao 多租户兼容MVP 单租户=0',
PRIMARY KEY (`id`),
KEY `idx_creator` (`creator_user_id`, `id`) COMMENT '创作者「我的创作会话」列表DataPermission 边界 + 按 id 倒序)',
KEY `idx_game` (`game_id`) COMMENT '按移交后的游戏 ID 反查会话'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '创作会话表(有状态创作工作台主记录;草稿入参 + 移交 game_id';
-- -----------------------------------------------------------------------------
-- 表game_studio_taskchain —— 创作任务链表(线性单步编排,对齐 P-CRT-01/09 一句话生成 + 重生成血缘)
-- 用途generate 时落一条任务链(status=1),回填 aigc_task_idgetTask 轮询透传 aigc 进度/状态映射链态。
-- 引用边界aigc_task_id 引用 aigc.game_aigc_task.id生成权威归 aigcversion_id 引用 project.game_version.id
-- aigc succeeded 后回填,版本权威归 project本表只持引用 + 自身链态,不重建生成状态机。
-- 重生成血缘retry_of 指向原任务链 idP-CRT-09regenerate 新建一条 retry_of=原 id 的链。
-- 链态 status0 初始 → 1 生成中 → 2 完成(回填 version_id / 3 失败(透传 aigc failed/timed_out
-- -----------------------------------------------------------------------------
CREATE TABLE `game_studio_taskchain` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '创作任务链 ID',
`session_id` BIGINT NOT NULL COMMENT '所属创作会话 ID= game_studio_session.id',
`creator_user_id` BIGINT NOT NULL COMMENT '创作者用户 IDDataPermission 边界,归属校验用)',
`aigc_task_id` BIGINT NULL DEFAULT NULL COMMENT '委托的 aigc 生成任务 ID= aigc.game_aigc_task.idgenerate 后回填,轮询据此查 aigc',
`game_id` BIGINT NULL DEFAULT NULL COMMENT '关联游戏 IDproject.game_project.id透传 aigc 用)',
`version_id` BIGINT NULL DEFAULT NULL COMMENT '产物版本 IDproject.game_version.idaigc succeeded 后由 getTask 回填',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '任务链状态机0初始 1生成中 2完成 3失败Service 校验流转,透传 aigc 终态映射)',
`progress` INT NOT NULL DEFAULT 0 COMMENT '进度百分比 0-100透传 aigc progress供前端进度条 P-CRT-12',
`retry_of` BIGINT NULL DEFAULT NULL COMMENT '若为重生成,指向原任务链 IDP-CRT-09 重生成血缘)',
`creator` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建者Yudao 审计列)',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '逻辑删除0未删 1已删',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户 IDYudao 多租户兼容MVP 单租户=0',
PRIMARY KEY (`id`),
KEY `idx_session` (`session_id`, `id`) COMMENT '按会话查任务链(含重生成历史,按 id 倒序)',
KEY `idx_aigc` (`aigc_task_id`) COMMENT '按 aigc 任务 ID 反查任务链(轮询回写映射)'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '创作任务链表(线性单步编排;持 aigc_task_id/version_id 引用 + 链态)';
-- -----------------------------------------------------------------------------
-- 表game_studio_asset —— 创作资产槽位表(单步出整包,对齐 P-CRT-02MVP 仅落槽位 seam不六路并发
-- 用途单步生成产物的资产槽位记录asset_type 槽位 + asset_url + 槽位状态)。
-- 狠切R7/草稿 scopeMVP 只建槽位表占位 seam不实现六路并发资产生成资产由 aigc 单步整包产出studio 仅登记槽位。
-- -----------------------------------------------------------------------------
CREATE TABLE `game_studio_asset` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '资产槽位 ID',
`session_id` BIGINT NOT NULL COMMENT '所属创作会话 ID= game_studio_session.id',
`asset_type` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '资产槽位类型(如 sprite/background/audio/iconMVP 槽位占位)',
`asset_url` VARCHAR(512) NOT NULL DEFAULT '' COMMENT '资产 URLOSS/MinIO单步整包产出后登记',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '槽位状态0未生成 1已生成Service 校验MVP 单步直填)',
`creator` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建者Yudao 审计列)',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '逻辑删除0未删 1已删',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户 IDYudao 多租户兼容MVP 单租户=0',
PRIMARY KEY (`id`),
KEY `idx_session_type` (`session_id`, `asset_type`) COMMENT '按会话+槽位类型查资产'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '创作资产槽位表(单步出整包槽位 seamMVP 不六路并发)';

View File

@ -1,118 +0,0 @@
-- =============================================================================
-- 契约 #2 DB 迁移 | 模块tradegame-module-tradeWave2 变现域「分账/结算/提现」)| ownerWS5
-- 文件V7.0.0__create_game_trade.sqlFlyway只新增已合入禁止修改回滚写新补偿迁移
-- 内容trade 模块核心表 —— 收益账户 game_trade_account + 收益流水 game_trade_income + 提现申请 game_trade_withdraw
-- 职责(架构 Doc B多源收入分账/归集/结算/对账;钱包打款/提现门槛与打款执行属 trade不属 pay不做支付收单归 pay
-- MVP 钱财闭环(决策 D3广告收入 → trade 分账(创作者 80%) → 创作者收益账户 → 提现(满 5 元)。会员订阅/支付收单=P1本轮不做。
-- 上游 seam消费 ad 模块 AdRevenueApi.getUnsettledRevenue/markSettled详见 ad.yaml x-feign-contractsT+1 SettlementJob 据此分账。
--
-- 【配置化(决策 D3全配置走 Nacos/DB严禁硬编码—— 本迁移不建死值,运行时读 Nacos】
-- - trade.creator-share = 0.80 MVP 全档统一 80% 分账比例;分层结构 creator_share_tier 保留、值后期填,见下方占位说明)
-- - trade.withdraw-min = 500 (单位:分,满 5 元可提现门槛)
-- 分账规则不建表(走 Nacos 配置分层占位说明later若引入分层分账可加 game_trade_share_rule
-- (tier 等级/min_income 门槛/share_rate 比例),按创作者等级取不同 share_rateMVP 不建,统一读 trade.creator-share。
-- 落账定格game_trade_income.share_rate 落账时定格当时的 Nacos 比例快照,不随后续配置变动重算(保证历史流水可对账、金额不漂移)。
--
-- 约定InnoDB + utf8mb4显式列含 Yudao 审计列 creator/create_time/updater/update_time/deleted + tenant_id
-- 金额一律「分」(BIGINT) 禁浮点,比例用 DECIMAL资金写入有幂等键(biz_no/source_ref + uk);状态机用 tinyint非法流转 Service 拒绝;
-- 账户表 = 流水的物化汇总,余额变更必有对应流水/单据;中文列注释;关键查询建索引、禁裸 select*。
-- 错误码段trade = 1-106-***-***
-- =============================================================================
-- -----------------------------------------------------------------------------
-- 表game_trade_account —— 创作者收益账户(物化汇总;余额变更必有对应流水/提现单)
-- 不变式total_income = Σ game_trade_income.net_amount本人分账+ Σ game_trade_grant.amount本人 admin 赋余额)——
-- 即「累计入账」= 分账入账 + admin 赋余额两类资金来源之和U2 起 admin 赋余额也计入,维持下方账面恒等式);
-- balance + frozen + total_withdraw = total_income余额 + 冻结中 + 已提现 = 累计入账,恒等式始终成立)
-- 写入点:① 分账入账SettlementJob→ total_income += net、balance += net
-- ②′ admin 赋余额U2AccountService.grant→ total_income += amount、balance += amount记 game_trade_grant 流水佐证);
-- ② 提现申请 → balance -= amount、frozen += amount冻结
-- ③ 打款成功 → frozen -= amount、total_withdraw += amount
-- ④ 驳回/打款失败 → frozen -= amount、balance += amount退回
-- 并发余额增减用行级原子更新UPDATE ... SET balance = balance ± ? WHERE user_id=? AND balance >= ?),扣减带余额充足条件防超扣。
-- -----------------------------------------------------------------------------
CREATE TABLE `game_trade_account` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '收益账户 ID',
`user_id` BIGINT NOT NULL COMMENT '创作者用户 IDDataPermission创作者只见自己账户',
`balance` BIGINT NOT NULL DEFAULT 0 COMMENT '可提现余额单位BIGINT 禁浮点)',
`frozen` BIGINT NOT NULL DEFAULT 0 COMMENT '冻结中(提现处理中占用,单位:分;提现申请时从 balance 转入)',
`total_income` BIGINT NOT NULL DEFAULT 0 COMMENT '累计入账(单位:分;= Σ 本人收益流水 net_amount + Σ 本人 admin 赋余额 grant.amountU2 起含赋余额,维持 balance+frozen+total_withdraw 恒等式)',
`total_withdraw` BIGINT NOT NULL DEFAULT 0 COMMENT '累计已提现(已打款成功总额,单位:分)',
`creator` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建者Yudao 审计列)',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间(账户初始化时间)',
`updater` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '逻辑删除0未删 1已删',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户 IDYudao 多租户兼容MVP 单租户=0',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user` (`user_id`, `tenant_id`) COMMENT '一个创作者一个收益账户(幂等初始化,防并发重复建账户)'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '创作者收益账户表(流水物化汇总,余额变更必有流水)';
-- -----------------------------------------------------------------------------
-- 表game_trade_income —— 收益流水(分账后入账,每笔来源收入一条;账户余额的明细来源)
-- 分账net_amount = gross_amount × share_rate创作者实得落账时按分计算定格平台分成 = gross - net不单独存报表算
-- 幂等核心uk_source(source, source_ref) 防同一笔来源收入重复分账——
-- 广告source=1(ad)、source_ref=game_ad_revenue.id打赏source=2(tip)、source_ref=打赏单 id。
-- SettlementJob 重跑/补偿时,命中 uk_source 即跳过该笔,保证不重复入账(不重复发钱)。
-- 对账锚点source_ref + trace_id 与 ad 侧 game_ad_revenue.id + trace_id 对齐,端到端可对账。
-- 注本流水即「income_settled 已落账」事实;契约#5 income_settled 事件props:amount/source为分析埋点镜像不替代本表。
-- 金额单位gross_amount / net_amount 一律「分」(BIGINT) 禁浮点share_rate 用 DECIMAL(5,4)(如 0.8000)。
-- -----------------------------------------------------------------------------
CREATE TABLE `game_trade_income` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '收益流水 ID',
`user_id` BIGINT NOT NULL COMMENT '创作者用户 ID收入归属DataPermission只见自己',
`source` TINYINT NOT NULL COMMENT '收入来源1 ad 广告 / 2 tip 打赏MVP 仅 adtip 留位)',
`source_ref` VARCHAR(64) NOT NULL COMMENT '来源单号(对账锚点):广告=game_ad_revenue.id打赏=打赏单 id。与 source 组成幂等唯一键',
`gross_amount` BIGINT NOT NULL DEFAULT 0 COMMENT '原始收入(分账前,单位:分)',
`share_rate` DECIMAL(5,4) NOT NULL DEFAULT 0.0000 COMMENT '分账比例(如 0.8000=创作者得 80%;落账时定格 Nacos trade.creator-share 快照,不随配置变动重算)',
`net_amount` BIGINT NOT NULL DEFAULT 0 COMMENT '创作者实得 = gross_amount × share_rate单位落账定格累加入账户 balance/total_income',
`settle_date` DATE NOT NULL COMMENT 'T+1 结算日yyyy-MM-dd= 上游 game_ad_revenue.stat_date',
`trace_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '全链路 traceId广告来源透传自 game_ad_revenue.trace_id供端到端对账',
`creator` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建者Yudao 审计列;分账 job 为 system',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间(入账时间)',
`updater` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '逻辑删除0未删 1已删',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户 IDYudao 多租户兼容MVP 单租户=0',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_source` (`source`, `source_ref`, `tenant_id`) COMMENT '幂等核心:同一笔来源收入(source+source_ref)只分账入账一次,防重复发钱',
KEY `idx_user_settle` (`user_id`, `settle_date`) COMMENT '我的收益流水分页(创作者+结算日)',
KEY `idx_settle_date` (`settle_date`) COMMENT '平台营收报表按日聚合 gross/net'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '收益流水表分账后入账账户余额明细来源uk 防重复分账)';
-- -----------------------------------------------------------------------------
-- 表game_trade_withdraw —— 提现申请(提现门槛/冻结/审核/打款执行,属 trade 不属 pay
-- 状态机 status0待审核 →(1审核通过打款中 / 3驳回) 1 →(2已打款 / 4打款失败)
-- 合法流转(非法流转由 WithdrawService 拒绝DO 层不承载校验):
-- 0 → 1审核通过 :管理端审核通过
-- 0 → 3审核驳回 :冻结金额 frozen 退回 balance资金原路退回必填 reject_reason
-- 1 → 2打款成功终态 frozen 扣减、total_withdraw 累加MVP mock 渠道审核通过即置 2
-- 1 → 4打款失败终态 frozen 退回 balance可重新发起新单
-- 终态2/3/4 不可再变;非法如 0→2未审核直接打款、2→*(已打款再变)一律拒绝。
-- 幂等核心uk_biz_no(biz_no) 防重复提现申请——同一 biz_no 重复提交返回已有申请,不重复冻结余额。
-- 资金安全:申请时原子校验 amount ≥ Nacos trade.withdraw-min 且 ≤ balance扣 balance 加 frozen金额单位「分」。
-- -----------------------------------------------------------------------------
CREATE TABLE `game_trade_withdraw` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '提现申请 ID',
`user_id` BIGINT NOT NULL COMMENT '创作者用户 IDDataPermission只见自己提现',
`amount` BIGINT NOT NULL COMMENT '提现金额单位BIGINT 禁浮点;申请时校验 ≥Nacos trade.withdraw-min 且 ≤可提现余额)',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '状态机0待审核 1审核通过打款中 2已打款 3驳回 4打款失败合法流转见表头注释非法流转 Service 拒绝)',
`biz_no` VARCHAR(64) NOT NULL COMMENT '提现业务单号 = 幂等键(前端生成唯一;重复提交同一 biz_no 不重复冻结)',
`channel` VARCHAR(16) NOT NULL DEFAULT 'mock' COMMENT '打款渠道MVP=mock 桩;真实 later 接 pay 渠道异步回调',
`apply_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '申请时间',
`audit_time` DATETIME NULL COMMENT '审核时间(审核后写入)',
`audit_user_id` BIGINT NULL COMMENT '审核人用户 ID管理端 RBAC',
`pay_time` DATETIME NULL COMMENT '打款时间(打款成功 status=2 时写入)',
`reject_reason` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '驳回理由status=3 时必填,回填创作者)',
`remark` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '备注(申请/审核备注)',
`creator` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建者Yudao 审计列;申请人)',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '逻辑删除0未删 1已删',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户 IDYudao 多租户兼容MVP 单租户=0',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_biz_no` (`biz_no`, `tenant_id`) COMMENT '提现幂等键:同一 biz_no 只受理一次(防重复提现/重复冻结)',
KEY `idx_user_status` (`user_id`, `status`) COMMENT '我的提现记录分页(创作者+状态)',
KEY `idx_status_apply` (`status`, `apply_time`) COMMENT '管理端提现审核队列(按状态+申请时间)'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '提现申请表(提现门槛/冻结/审核/打款,属 trade';