244 lines
12 KiB
SQL
244 lines
12 KiB
SQL
-- Yumi Gift Challenge: ordinary GOLD gift ledger, daily/overall ranking, three daily tasks,
|
|
-- frozen reward templates and two-phase item-level settlement.
|
|
--
|
|
-- Performance review:
|
|
-- 1. The MQ hot path resolves at most one enabled activity through
|
|
-- (sys_origin, enabled, start_time, end_time), deduplicates by a unique event key, and updates
|
|
-- one overall plus one daily aggregate primary key. Ranking never GROUP BYs the gift ledger.
|
|
-- 2. Daily/overall ranks use covering order indexes matching
|
|
-- score DESC, score_reached_time ASC, user_id ASC; user-rank counts remain activity/date scoped.
|
|
-- 3. Settlement discovery uses (status, snapshot_due_time), while parent and delivery claims use
|
|
-- unique owner/business keys and narrow owner/status indexes. UNKNOWN items are never auto-retried.
|
|
-- 4. This migration creates empty tables only: no UPDATE, DELETE, backfill, table-copy ALTER, or
|
|
-- unbounded scan is executed. Run DDL under the target database's normal online-DDL policy.
|
|
|
|
SET NAMES utf8mb4;
|
|
|
|
CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_activity` (
|
|
`id` BIGINT NOT NULL,
|
|
`activity_code` VARCHAR(64) NOT NULL,
|
|
`activity_name` VARCHAR(128) NOT NULL,
|
|
`activity_desc` VARCHAR(1000) NOT NULL DEFAULT '',
|
|
`sys_origin` VARCHAR(32) NOT NULL,
|
|
`time_zone` VARCHAR(64) NOT NULL DEFAULT 'Asia/Riyadh',
|
|
`start_time` DATETIME(3) NOT NULL,
|
|
`end_time` DATETIME(3) NOT NULL,
|
|
`daily_settlement_delay_minutes` INT NOT NULL DEFAULT 30,
|
|
`overall_settlement_delay_minutes` INT NOT NULL DEFAULT 30,
|
|
`overall_settlement_time` DATETIME(3) NOT NULL,
|
|
`display_top_n` INT NOT NULL DEFAULT 100,
|
|
`enabled` TINYINT(1) NOT NULL DEFAULT 0,
|
|
`overall_settlement_status` VARCHAR(32) NOT NULL DEFAULT 'NOT_STARTED',
|
|
`version` INT NOT NULL DEFAULT 0,
|
|
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
`update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `uk_yumi_gc_activity_code` (`activity_code`),
|
|
KEY `idx_yumi_gc_activity_window` (`sys_origin`, `enabled`, `start_time`, `end_time`),
|
|
KEY `idx_yumi_gc_activity_settle` (`overall_settlement_status`, `overall_settlement_time`, `id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Yumi gift challenge activity cycle';
|
|
|
|
CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_task_config` (
|
|
`id` BIGINT NOT NULL,
|
|
`activity_id` BIGINT NOT NULL,
|
|
`task_code` VARCHAR(64) NOT NULL,
|
|
`task_type` VARCHAR(32) NOT NULL,
|
|
`task_title` VARCHAR(128) NOT NULL,
|
|
`task_desc` VARCHAR(500) NOT NULL DEFAULT '',
|
|
`target_value` DECIMAL(24,2) NOT NULL,
|
|
`resource_group_id` BIGINT NULL,
|
|
`enabled` TINYINT(1) NOT NULL DEFAULT 1,
|
|
`sort_order` TINYINT NOT NULL,
|
|
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
`update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `uk_yumi_gc_task_code` (`activity_id`, `task_code`),
|
|
UNIQUE KEY `uk_yumi_gc_task_sort` (`activity_id`, `sort_order`),
|
|
KEY `idx_yumi_gc_task_enabled` (`activity_id`, `enabled`, `sort_order`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Exactly three Yumi gift challenge daily tasks';
|
|
|
|
CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_rank_reward` (
|
|
`id` BIGINT NOT NULL,
|
|
`activity_id` BIGINT NOT NULL,
|
|
`period_type` VARCHAR(16) NOT NULL,
|
|
`start_rank` INT NOT NULL,
|
|
`end_rank` INT NOT NULL,
|
|
`resource_group_id` BIGINT NOT NULL,
|
|
`reward_name` VARCHAR(128) NOT NULL DEFAULT '',
|
|
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
`update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `uk_yumi_gc_rank_range` (`activity_id`, `period_type`, `start_rank`, `end_rank`),
|
|
KEY `idx_yumi_gc_rank_match` (`activity_id`, `period_type`, `start_rank`, `end_rank`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Configurable daily and overall rank reward ranges';
|
|
|
|
CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_reward_snapshot` (
|
|
`id` BIGINT NOT NULL,
|
|
`activity_id` BIGINT NOT NULL,
|
|
`resource_group_id` BIGINT NOT NULL,
|
|
`reward_config_id` BIGINT NOT NULL,
|
|
`reward_type` VARCHAR(64) NOT NULL,
|
|
`detail_type` VARCHAR(64) NOT NULL DEFAULT '',
|
|
`content` TEXT NOT NULL,
|
|
`quantity` BIGINT NOT NULL,
|
|
`sort_order` INT NOT NULL DEFAULT 0,
|
|
`remark` VARCHAR(500) NOT NULL DEFAULT '',
|
|
`cover` TEXT NOT NULL,
|
|
`source_url` TEXT NOT NULL,
|
|
`display_name` VARCHAR(500) NOT NULL DEFAULT '',
|
|
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `uk_yumi_gc_snapshot_item` (`activity_id`, `resource_group_id`, `reward_config_id`),
|
|
KEY `idx_yumi_gc_snapshot_group` (`activity_id`, `resource_group_id`, `sort_order`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Full reward item template frozen when activity is enabled';
|
|
|
|
CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_gift_ledger` (
|
|
`id` BIGINT NOT NULL,
|
|
`activity_id` BIGINT NOT NULL,
|
|
`source_event_track_id` VARCHAR(128) NOT NULL,
|
|
`user_id` BIGINT NOT NULL,
|
|
`gift_id` BIGINT NOT NULL,
|
|
`gift_tab` VARCHAR(32) NOT NULL,
|
|
`amount` DECIMAL(24,2) NOT NULL,
|
|
`event_time` DATETIME(3) NOT NULL,
|
|
`stat_date` DATE NOT NULL,
|
|
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `uk_yumi_gc_ledger_event` (`activity_id`, `source_event_track_id`),
|
|
KEY `idx_yumi_gc_ledger_user` (`activity_id`, `user_id`, `event_time`),
|
|
KEY `idx_yumi_gc_ledger_date` (`activity_id`, `stat_date`, `event_time`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Idempotent ordinary GOLD gift activity ledger';
|
|
|
|
CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_user_score` (
|
|
`activity_id` BIGINT NOT NULL,
|
|
`user_id` BIGINT NOT NULL,
|
|
`score` DECIMAL(24,2) NOT NULL DEFAULT 0.00,
|
|
`score_reached_time` DATETIME(3) NOT NULL,
|
|
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
`update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (`activity_id`, `user_id`),
|
|
KEY `idx_yumi_gc_overall_rank` (`activity_id`, `score` DESC, `score_reached_time` ASC, `user_id` ASC)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Materialized overall gift challenge score';
|
|
|
|
CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_user_daily_score` (
|
|
`activity_id` BIGINT NOT NULL,
|
|
`stat_date` DATE NOT NULL,
|
|
`user_id` BIGINT NOT NULL,
|
|
`score` DECIMAL(24,2) NOT NULL DEFAULT 0.00,
|
|
`score_reached_time` DATETIME(3) NOT NULL,
|
|
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
`update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (`activity_id`, `stat_date`, `user_id`),
|
|
KEY `idx_yumi_gc_daily_rank` (`activity_id`, `stat_date`, `score` DESC, `score_reached_time` ASC, `user_id` ASC)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Materialized activity-timezone daily gift challenge score';
|
|
|
|
CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_user_task_daily` (
|
|
`id` BIGINT NOT NULL,
|
|
`activity_id` BIGINT NOT NULL,
|
|
`stat_date` DATE NOT NULL,
|
|
`user_id` BIGINT NOT NULL,
|
|
`task_config_id` BIGINT NOT NULL,
|
|
`task_code` VARCHAR(64) NOT NULL,
|
|
`task_type` VARCHAR(32) NOT NULL,
|
|
`task_title` VARCHAR(128) NOT NULL,
|
|
`sort_order` TINYINT NOT NULL,
|
|
`target_value` DECIMAL(24,2) NOT NULL,
|
|
`progress_value` DECIMAL(24,2) NOT NULL DEFAULT 0.00,
|
|
`completed_time` DATETIME(3) NULL,
|
|
`resource_group_id` BIGINT NULL,
|
|
`business_no` VARCHAR(160) NOT NULL,
|
|
`claim_request_id` VARCHAR(128) NOT NULL DEFAULT '',
|
|
`delivery_status` VARCHAR(32) NOT NULL DEFAULT 'NOT_CLAIMED',
|
|
`retry_count` INT NOT NULL DEFAULT 0,
|
|
`failure_reason` VARCHAR(500) NOT NULL DEFAULT '',
|
|
`claimed_time` DATETIME(3) NULL,
|
|
`deliver_time` DATETIME(3) NULL,
|
|
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
`update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `uk_yumi_gc_user_task` (`activity_id`, `stat_date`, `user_id`, `task_code`),
|
|
UNIQUE KEY `uk_yumi_gc_task_business` (`business_no`),
|
|
KEY `idx_yumi_gc_user_task_page` (`activity_id`, `stat_date`, `user_id`, `sort_order`),
|
|
KEY `idx_yumi_gc_task_delivery` (`delivery_status`, `update_time`, `id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Frozen per-user per-day task state and reward owner';
|
|
|
|
CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_period_settlement` (
|
|
`id` BIGINT NOT NULL,
|
|
`activity_id` BIGINT NOT NULL,
|
|
`period_type` VARCHAR(16) NOT NULL,
|
|
`period_key` VARCHAR(16) NOT NULL,
|
|
`stat_date` DATE NULL,
|
|
`snapshot_due_time` DATETIME(3) NOT NULL,
|
|
`status` VARCHAR(32) NOT NULL DEFAULT 'NOT_STARTED',
|
|
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
`update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `uk_yumi_gc_period` (`activity_id`, `period_type`, `period_key`),
|
|
KEY `idx_yumi_gc_period_due` (`status`, `snapshot_due_time`, `id`),
|
|
KEY `idx_yumi_gc_period_activity` (`activity_id`, `status`, `period_type`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Daily and overall write gates including empty periods';
|
|
|
|
CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_settlement` (
|
|
`id` BIGINT NOT NULL,
|
|
`activity_id` BIGINT NOT NULL,
|
|
`period_type` VARCHAR(16) NOT NULL,
|
|
`period_key` VARCHAR(16) NOT NULL,
|
|
`stat_date` DATE NULL,
|
|
`user_id` BIGINT NOT NULL,
|
|
`rank_no` INT NOT NULL,
|
|
`score` DECIMAL(24,2) NOT NULL,
|
|
`rank_reward_id` BIGINT NOT NULL,
|
|
`resource_group_id` BIGINT NOT NULL,
|
|
`business_no` VARCHAR(180) NOT NULL,
|
|
`delivery_status` VARCHAR(32) NOT NULL DEFAULT 'PENDING',
|
|
`retry_count` INT NOT NULL DEFAULT 0,
|
|
`failure_reason` VARCHAR(500) NOT NULL DEFAULT '',
|
|
`deliver_time` DATETIME(3) NULL,
|
|
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
`update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `uk_yumi_gc_settle_user` (`activity_id`, `period_type`, `period_key`, `user_id`),
|
|
UNIQUE KEY `uk_yumi_gc_settle_rank` (`activity_id`, `period_type`, `period_key`, `rank_no`),
|
|
UNIQUE KEY `uk_yumi_gc_settle_business` (`business_no`),
|
|
KEY `idx_yumi_gc_settle_status` (`activity_id`, `period_type`, `period_key`, `delivery_status`, `rank_no`),
|
|
KEY `idx_yumi_gc_settle_recovery` (`delivery_status`, `update_time`, `id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Frozen rank winner parent records';
|
|
|
|
CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_delivery_item` (
|
|
`id` BIGINT NOT NULL,
|
|
`owner_type` VARCHAR(16) NOT NULL COMMENT 'TASK or SETTLEMENT',
|
|
`owner_id` BIGINT NOT NULL,
|
|
`activity_id` BIGINT NOT NULL,
|
|
`user_id` BIGINT NOT NULL,
|
|
`reward_config_id` BIGINT NOT NULL,
|
|
`resource_group_id` BIGINT NOT NULL,
|
|
`reward_type` VARCHAR(64) NOT NULL,
|
|
`detail_type` VARCHAR(64) NOT NULL DEFAULT '',
|
|
`content` TEXT NOT NULL,
|
|
`quantity` BIGINT NOT NULL,
|
|
`sort_order` INT NOT NULL DEFAULT 0,
|
|
`remark` VARCHAR(500) NOT NULL DEFAULT '',
|
|
`delivery_status` VARCHAR(32) NOT NULL DEFAULT 'PENDING',
|
|
`retry_count` INT NOT NULL DEFAULT 0,
|
|
`failure_reason` VARCHAR(500) NOT NULL DEFAULT '',
|
|
`deliver_time` DATETIME(3) NULL,
|
|
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
`update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `uk_yumi_gc_delivery_item` (`owner_type`, `owner_id`, `reward_config_id`),
|
|
KEY `idx_yumi_gc_delivery_claim` (`owner_type`, `owner_id`, `delivery_status`, `sort_order`, `id`),
|
|
KEY `idx_yumi_gc_delivery_stale` (`delivery_status`, `update_time`, `id`),
|
|
KEY `idx_yumi_gc_delivery_activity` (`activity_id`, `delivery_status`, `id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
COMMENT='Item-level idempotent frozen reward delivery';
|