games-development-ai/contracts/db-schemas/V32.0.0__create_newapi_quota_pool.sql
lili c13595fbc2 feat(aigc): WU2① new-api 额度池表 V32 + DO/Mapper——离线预建 FREE 条目 claim 抢占
内测 per-user ¥100 额度落 new-api 网关账本,game-cloud 维护一张预置池表:
ops 脚本离线预建 (user+token+¥100) 灌成 FREE 条目,注册/懒 claim 时 CAS 抢一个绑玩家。
- V32.0.0 迁移双落契约源 + huijing-server 执行副本(守门①),列名对齐 ops 脚本 INSERT,
  uk_newapi_user/uk_claimed_by/uk_biz_no 三键仿 trade GrantDO 的 uk_biz_no 保幂等。
- NewapiQuotaPoolDO 继承 TenantBaseDO(系统级池,运行时 executeIgnore 跨租户);
  Mapper 提供 selectClaimedByPlayer/countFree 水位/claimOneFree 单条 FREE→CLAIMED CAS。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 12:21:33 -07:00

59 lines
6.9 KiB
SQL
Raw Permalink 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.

-- =============================================================================
-- 契约 #2 DB 迁移 | 主题内测·new-api per-user ¥100 额度池WU22026-07-07 设计 §3.5| owneraigc派发期映射查询 co-locate
-- 文件V32.0.0__create_newapi_quota_pool.sqlFlyway纯新增表已合入禁止修改回滚 = drop 表 + 摘事件消费者)
-- 依据docs/agent-specs/2026-07-07-内测-WU2-newapi额度接入-设计.md草案创始人拍定「离线预置池 + 注册 claim」
-- 版本定序:执行副本 db/migration/ 实测已连续到 V31.0.0WU1 game_player 增列 + outbox本件顺延取 V32.0.0(已 ls|sort -V|tail 复核)。
-- WU1 与 WU2 同批新增迁移——WU1 取 V31、WU2 顺延 V32避免 Flyway 撞号校验失败。
-- 守门①(沿用 V11/V31本件同时落 contracts/db-schemas/(契约源)+ huijing-server 执行副本(唯一执行 classpath
-- 不放任何单模块 -server/db/migration/(避免同版本出现在多个 classpath jar 触发 Flyway 重复校验失败)。
-- 守门②:含中文 SQLmini-desktop 执行必须 --default-character-set=utf8mb4。
-- 内容CREATE newapi_quota_pool —— 离线 ops 脚本预建 FREE 条目 + 注册 claim 绑玩家FREE→CLAIMED账本在 new-api 网关。
-- =============================================================================
-- -----------------------------------------------------------------------------
-- CREATE newapi_quota_pool —— new-api per-user 额度预置池§3.5
-- 语义ops 脚本game-runtime/tools/newapi_pool_provision.py离线预建 N 个 (new-api user + token + ¥100)
-- 按条目 INSERTstatus=FREE、claimed_* 空);注册/懒 claim 时某条被 CAS 抢占翻转 CLAIMED 并绑 game_player。
-- 账本口径唯一 = new-api 网关(权威余额=token remain_quota、权威消耗=user used_quota本表只存 grant_quota 审计快照,不在 game-cloud 记余额。
-- 列名严格对齐 ops 脚本 emit 的 INSERT(newapi_user_id, newapi_token_id, newapi_token_key, grant_quota,
-- quota_per_unit_snapshot, usd_rate_snapshot, status),去重键 uk_newapi_user(newapi_user_id) 供 ON DUPLICATE KEY UPDATE 幂等补池。
-- 审计列creator/create_time/updater/update_time/deleted与 tenant_id 均给默认值ops 脚本 raw INSERT 只给业务列,
-- 审计列/租户列走 DB 默认落值;运行时 claim/查询经 TenantUtils.executeIgnore 跨租户存取(池是系统级资源)。
-- 幂等三键(仿 game_trade_grant 的 uk_biz_no
-- · uk_newapi_user —— 预建条目按 new-api 用户去重(脚本补池锚);
-- · uk_claimed_by —— 一玩家至多一条 CLAIMEDFREE 时 claimed_by 为 NULLNULL 不参与唯一约束,多条 FREE 并存);
-- · uk_biz_no —— claim 幂等键 claim_<gamePlayerId>FREE 时为 NULL
-- 并发/重投由 status='FREE' 单条 CAS + 上述两 NULL 唯一键三重收敛成一条:同玩家不占第二条、两玩家不抢同一条。
-- newapi_token_key 是 new-api 调用凭据明文落库(内测可接受、须视为敏感):随 job 内网下发须日志脱敏,生产化应加密列(红线待办,本阶段不做)。
-- 前后兼容:纯新增表,不改任何既有表结构,无迁移风险。
-- ⚠ 再 claimS4 凭据失效路,本单不实现):将 CLAIMED 隔离为 INVALID 时必须同步清空 claimed_by_game_player_id/biz_no
-- 否则与该玩家新 CLAIMED 条目撞 uk_claimed_by/uk_biz_no。本单只落 FREE→CLAIMEDINVALID 转换延后到 S4。
-- -----------------------------------------------------------------------------
CREATE TABLE `newapi_quota_pool` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '池条目编号',
`newapi_user_id` BIGINT NOT NULL COMMENT '预建的 new-api users.id脚本灌数去重键',
`newapi_token_id` BIGINT NOT NULL COMMENT '预建的 new-api tokens.id',
`newapi_token_key` VARCHAR(64) NOT NULL COMMENT 'new-api tokens.key48 位 sk-…;⚠ 敏感,随 job 下发须脱敏,永不整条落日志)',
`grant_quota` BIGINT NOT NULL COMMENT '该条目预置的 ¥100 折算 quota审计快照权威余额以网关 token.remain_quota 为准)',
`quota_per_unit_snapshot` BIGINT NOT NULL COMMENT '折算时网关 quota_per_unit默认 500000审计追溯用',
`usd_rate_snapshot` DECIMAL(10,4) NOT NULL COMMENT '折算时 usd_exchange_rate默认 7.3,审计追溯用)',
`status` VARCHAR(16) NOT NULL DEFAULT 'FREE' COMMENT '状态FREE可claim / CLAIMED已绑玩家 / INVALID token失效隔离S4claim CAS 抢占锚',
`claimed_by_game_player_id` BIGINT NULL COMMENT 'claim 后 ↔ game_player.idFREE 时 NULLuk 允许多 NULLCLAIMED 保证一玩家至多一条)',
`claimed_at` DATETIME NULL COMMENT 'claim 时间CLAIMED 时回填)',
`biz_no` VARCHAR(64) NULL COMMENT 'claim 幂等键 claim_<gamePlayerId>FREE 时 NULL',
`retry_count` INT NOT NULL DEFAULT 0 COMMENT '预留claim/隔离重试计数',
`remark` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '备注(隔离原因等)',
-- 标准审计列DO 继承 TenantBaseDOops 脚本 raw INSERT 不给这些列,走默认落值,运行时 executeIgnore 跨租户)
`creator` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建者(审计列)',
`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 '租户编号(系统级池资源,运行时 executeIgnore 跨租户存取,值仅占位)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_newapi_user` (`newapi_user_id`) COMMENT '预建条目按 new-api 用户去重(脚本 ON DUPLICATE KEY UPDATE 补池锚)',
UNIQUE KEY `uk_claimed_by` (`claimed_by_game_player_id`) COMMENT '一玩家至多一条 CLAIMEDNULL 不参与约束,多条 FREE 并存)',
UNIQUE KEY `uk_biz_no` (`biz_no`) COMMENT 'claim 幂等键唯一NULL 不参与约束)',
KEY `idx_status` (`status`) COMMENT 'claim 抢占按 status=FREE 扫、水位按 FREE 计数'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = 'new-api per-user ¥100 额度预置池(离线预建 FREE + 注册 claim 绑玩家WU2 §3.5';