hyapp-server/services/wallet-service/deploy/mysql/migrations/001_activity_reward_snapshots.sql
2026-07-15 09:43:33 +08:00

74 lines
3.8 KiB
SQL

-- Activity reward snapshots are wallet-owned immutable grant facts. Every ALTER/INDEX is guarded so this
-- migration can run after fresh initdb and can be retried on later deployments without duplicate errors.
CREATE TABLE IF NOT EXISTS resource_group_snapshots (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码',
snapshot_id VARCHAR(96) NOT NULL COMMENT '不可变资源组快照 ID',
pin_key VARCHAR(192) NOT NULL COMMENT '发布方业务版本幂等键',
source_group_id BIGINT NOT NULL COMMENT '来源资源组 ID',
version_no BIGINT NOT NULL COMMENT '来源资源组递增快照版本',
snapshot_hash CHAR(64) NOT NULL COMMENT '完整快照 SHA-256',
snapshot_json JSON NOT NULL COMMENT '含资源详情、礼物语义和钱包资产的完整不可变快照',
source_group_updated_at_ms BIGINT NOT NULL COMMENT '锁定时来源资源组版本',
source_content_hash CHAR(64) NOT NULL COMMENT '资源组、组项和嵌套资源的规范化内容哈希',
created_by_user_id BIGINT NOT NULL,
created_at_ms BIGINT NOT NULL,
PRIMARY KEY (app_code, snapshot_id),
UNIQUE KEY uk_resource_group_snapshot_pin (app_code, pin_key),
UNIQUE KEY uk_resource_group_snapshot_version (app_code, source_group_id, version_no),
KEY idx_resource_group_snapshot_source (app_code, source_group_id, created_at_ms)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='资源组发布态不可变奖励快照';
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'user_resource_entitlements' AND COLUMN_NAME = 'source_snapshot_id') = 0,
'ALTER TABLE user_resource_entitlements ADD COLUMN source_snapshot_id VARCHAR(96) NOT NULL DEFAULT '''' AFTER source_grant_id',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'user_resource_entitlements' AND COLUMN_NAME = 'resource_snapshot_hash') = 0,
'ALTER TABLE user_resource_entitlements ADD COLUMN resource_snapshot_hash CHAR(64) NOT NULL DEFAULT '''' AFTER source_snapshot_id',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'user_resource_entitlements' AND COLUMN_NAME = 'resource_snapshot_json') = 0,
'ALTER TABLE user_resource_entitlements ADD COLUMN resource_snapshot_json JSON NULL AFTER resource_snapshot_hash',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'user_resource_entitlements' AND COLUMN_NAME = 'gift_snapshot_hash') = 0,
'ALTER TABLE user_resource_entitlements ADD COLUMN gift_snapshot_hash CHAR(64) NOT NULL DEFAULT '''' AFTER resource_snapshot_json',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'user_resource_entitlements' AND COLUMN_NAME = 'gift_snapshot_json') = 0,
'ALTER TABLE user_resource_entitlements ADD COLUMN gift_snapshot_json JSON NULL AFTER gift_snapshot_hash',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'user_resource_entitlements' AND INDEX_NAME = 'idx_user_resource_semantic') = 0,
'CREATE INDEX idx_user_resource_semantic ON user_resource_entitlements (app_code, user_id, resource_id, resource_snapshot_hash, status, expires_at_ms)',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;