-- Migration: refund commission for existing pending (status=0) withdrawals -- -- Under the old logic, commission was deducted when a withdrawal was submitted. -- Under the new logic, commission is only deducted on approval. -- This migration refunds the deducted amounts back to each user so that -- the system is in a consistent state before the new code is deployed. -- -- Idempotency: the UPDATE only touches rows whose commission would need -- to increase, and each execution produces the same result because -- COALESCE(SUM(amount),0) is deterministic given the same pending set. -- Running this script multiple times is safe only if no new pending -- withdrawals are created between runs; deploy new code immediately after. -- Compatibility: some historical databases missed migration 02122, so the -- withdrawals table may not exist yet. Create it idempotently before the -- refund logic so this migration can self-heal older installations. CREATE TABLE IF NOT EXISTS `withdrawals` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'Primary Key', `user_id` BIGINT NOT NULL COMMENT 'User ID', `amount` BIGINT NOT NULL COMMENT 'Withdrawal Amount', `content` TEXT COMMENT 'Withdrawal Content', `status` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'Withdrawal Status', `reason` VARCHAR(500) NOT NULL DEFAULT '' COMMENT 'Rejection Reason', `created_at` DATETIME NOT NULL COMMENT 'Creation Time', `updated_at` DATETIME NOT NULL COMMENT 'Update Time', PRIMARY KEY (`id`), KEY `idx_user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; INSERT IGNORE INTO `system` (`category`, `key`, `value`, `type`, `desc`, `created_at`, `updated_at`) VALUES ('invite', 'WithdrawalMethod', '', 'string', 'withdrawal method', '2025-04-22 14:25:16.637', '2025-04-22 14:25:16.637'); -- Step 1: refund commission for all users with pending withdrawals. UPDATE `user` u JOIN ( SELECT user_id, COALESCE(SUM(amount), 0) AS pending_total FROM withdrawals WHERE status = 0 GROUP BY user_id ) p ON u.id = p.user_id SET u.commission = u.commission + p.pending_total WHERE p.pending_total > 0; -- Step 2: write a migration log entry for each refunded user. INSERT INTO system_logs (type, date, object_id, content, created_at) SELECT 33 AS type, DATE(NOW()) AS date, p.user_id AS object_id, JSON_OBJECT( 'type', 99, 'amount', p.pending_total, 'order_no', '', 'timestamp', UNIX_TIMESTAMP(NOW()) * 1000, 'note', 'migration: refund pending withdrawal commission (HIF-22)' ) AS content, NOW() AS created_at FROM ( SELECT user_id, COALESCE(SUM(amount), 0) AS pending_total FROM withdrawals WHERE status = 0 GROUP BY user_id HAVING pending_total > 0 ) p;