feat: add affiliate invite rebate flow and admin rebate-rate setting
This commit is contained in:
58
backend/migrations/131_affiliate_rebate_hardening.sql
Normal file
58
backend/migrations/131_affiliate_rebate_hardening.sql
Normal file
@@ -0,0 +1,58 @@
|
||||
-- 1) Normalize historical affiliate rebate rate values.
|
||||
-- Legacy compatibility treated 0<x<=1 as fractional inputs (e.g. 0.2 => 20%).
|
||||
-- We now use pure percentage semantics, so convert persisted fractional values once.
|
||||
UPDATE settings
|
||||
SET value = to_char((value::numeric * 100), 'FM999999990.########'),
|
||||
updated_at = NOW()
|
||||
WHERE key = 'affiliate_rebate_rate'
|
||||
AND value ~ '^-?[0-9]+(\\.[0-9]+)?$'
|
||||
AND value::numeric > 0
|
||||
AND value::numeric <= 1;
|
||||
|
||||
-- 2) Affiliate ledger for accrual/transfer traceability.
|
||||
CREATE TABLE IF NOT EXISTS user_affiliate_ledger (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
action VARCHAR(32) NOT NULL,
|
||||
amount DECIMAL(20,8) NOT NULL,
|
||||
source_user_id BIGINT NULL REFERENCES users(id) ON DELETE SET NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_user_affiliate_ledger_user_id ON user_affiliate_ledger(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_user_affiliate_ledger_action ON user_affiliate_ledger(action);
|
||||
|
||||
COMMENT ON TABLE user_affiliate_ledger IS '邀请返利资金流水(累计/转入)';
|
||||
COMMENT ON COLUMN user_affiliate_ledger.action IS 'accrue|transfer';
|
||||
|
||||
-- 3) Enforce idempotency at DB layer for payment audit actions.
|
||||
WITH ranked AS (
|
||||
SELECT id,
|
||||
ROW_NUMBER() OVER (PARTITION BY order_id, action ORDER BY id) AS rn
|
||||
FROM payment_audit_logs
|
||||
)
|
||||
DELETE FROM payment_audit_logs p
|
||||
USING ranked r
|
||||
WHERE p.id = r.id
|
||||
AND r.rn > 1;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_payment_audit_logs_order_action_uniq
|
||||
ON payment_audit_logs(order_id, action);
|
||||
|
||||
-- 4) Prevent retroactive affiliate rebate issuance for legacy completed balance orders.
|
||||
INSERT INTO payment_audit_logs (order_id, action, detail, operator, created_at)
|
||||
SELECT po.id::text,
|
||||
'AFFILIATE_REBATE_SKIPPED',
|
||||
'{"reason":"baseline before affiliate rebate idempotency rollout"}',
|
||||
'system',
|
||||
NOW()
|
||||
FROM payment_orders po
|
||||
WHERE po.order_type = 'balance'
|
||||
AND po.status = 'COMPLETED'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM payment_audit_logs pal
|
||||
WHERE pal.order_id = po.id::text
|
||||
AND pal.action IN ('AFFILIATE_REBATE_APPLIED', 'AFFILIATE_REBATE_SKIPPED')
|
||||
);
|
||||
Reference in New Issue
Block a user