| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- -- 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')
- );
|