SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;

USE hyapp_lucky_gift;

-- AB 实验事实表：两组各钉住一个不可变 rule_version，运行时按 bucket_salt + user 哈希分流。
-- active 生成列只在未完成状态为 1，配合唯一键保证同一奖池同时最多一个未完成实验；
-- completed 后 active 为 NULL，不占用唯一键，历史实验可以保留任意多条。
CREATE TABLE IF NOT EXISTS lucky_gift_experiments (
  app_code VARCHAR(32) NOT NULL COMMENT '应用编码',
  experiment_id VARCHAR(64) NOT NULL COMMENT '实验 ID',
  pool_id VARCHAR(96) NOT NULL COMMENT '幸运礼物奖池 ID',
  name VARCHAR(128) NOT NULL COMMENT '实验名称',
  control_rule_version BIGINT NOT NULL COMMENT '对照组钉住的规则版本',
  treatment_rule_version BIGINT NOT NULL COMMENT '实验组钉住的规则版本',
  treatment_traffic_ppm BIGINT NOT NULL DEFAULT 0 COMMENT '实验组流量比例 ppm，0..1000000',
  bucket_salt VARCHAR(64) NOT NULL COMMENT '分桶盐；实验生命周期内不可变，保证同一用户分组稳定',
  status VARCHAR(16) NOT NULL DEFAULT 'running' COMMENT 'running/paused/completed',
  active TINYINT AS (IF(status IN ('running', 'paused'), 1, NULL)) STORED COMMENT '未完成实验为 1，completed 为 NULL',
  winner_arm VARCHAR(16) NOT NULL DEFAULT '' COMMENT '结束实验时选择的获胜组 control/treatment',
  winner_rule_version BIGINT NOT NULL DEFAULT 0 COMMENT '获胜组钉住的规则版本',
  final_rule_version BIGINT NOT NULL DEFAULT 0 COMMENT '结束时重发布的收敛版本，全量流量由它承接',
  created_by_admin_id BIGINT NOT NULL DEFAULT 0 COMMENT '创建管理员 ID',
  started_at_ms BIGINT NOT NULL COMMENT '实验开始时间，UTC epoch ms',
  ended_at_ms BIGINT NOT NULL DEFAULT 0 COMMENT '实验结束时间，UTC epoch ms',
  created_at_ms BIGINT NOT NULL COMMENT '创建时间，UTC epoch ms',
  updated_at_ms BIGINT NOT NULL COMMENT '更新时间，UTC epoch ms',
  PRIMARY KEY (app_code, experiment_id),
  UNIQUE KEY uk_lucky_gift_experiments_active_pool (app_code, pool_id, active),
  KEY idx_lucky_gift_experiments_pool (app_code, pool_id, started_at_ms)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='幸运礼物 AB 实验';

-- 白名单 override：把指定用户强制固定到某个组，用于放量前验证。
-- user_key：内部用户为十进制 user_id；外部用户为 "ext:" + external_user_id。
CREATE TABLE IF NOT EXISTS lucky_gift_experiment_overrides (
  app_code VARCHAR(32) NOT NULL COMMENT '应用编码',
  experiment_id VARCHAR(64) NOT NULL COMMENT '实验 ID',
  -- user_key 必须字节精确（binary collation）：FNV 分桶按字节计算，ci 排序规则会让大小写不同的外部用户在白名单上碰撞/静默失配。
  user_key VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '用户标识：内部十进制 user_id 或 ext:external_user_id',
  arm VARCHAR(16) NOT NULL COMMENT '强制组 control/treatment',
  created_by_admin_id BIGINT NOT NULL DEFAULT 0 COMMENT '操作管理员 ID',
  created_at_ms BIGINT NOT NULL COMMENT '创建时间，UTC epoch ms',
  PRIMARY KEY (app_code, experiment_id, user_key)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='幸运礼物 AB 实验用户白名单';

-- 实验分组统计按 (app, pool, rule_version, 时间窗) 聚合；没有含 rule_version 的索引时热池会退化为大范围回表扫描。
SET @ddl := IF((SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'lucky_draw_records' AND INDEX_NAME = 'idx_lucky_draw_pool_version') = 0,
  'ALTER TABLE lucky_draw_records ADD KEY idx_lucky_draw_pool_version (app_code, pool_id, rule_version, created_at_ms)', 'SELECT 1');
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;

-- 兜底：006 首版曾以表默认 ci 排序规则建过 overrides 表；重复执行时归一到 binary。
SET @ddl := IF((SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'lucky_gift_experiment_overrides' AND COLUMN_NAME = 'user_key' AND COLLATION_NAME <> 'utf8mb4_bin') = 1,
  'ALTER TABLE lucky_gift_experiment_overrides MODIFY user_key VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT ''用户标识：内部十进制 user_id 或 ext:external_user_id''', 'SELECT 1');
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
