Files
digital-psychology/apps/api/migrations/000018_redemption_codes.up.sql
T
jackyu66gitandCursor 1eeb0b00e7 feat(ECR-015): RedemptionCode 兑换码并 Closed
批次生成/作废、C 端兑码延长会员;admin-h5 /codes。
Loop continuous。Next:ECR-016 UserIntelligence。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 18:16:13 +08:00

36 lines
1.3 KiB
SQL

-- ECR-015 RedemptionCode
CREATE TABLE IF NOT EXISTS redemption_batches (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
label varchar(64) NOT NULL,
plan_code varchar(32) NOT NULL REFERENCES membership_plans(code),
quantity int NOT NULL CHECK (quantity > 0 AND quantity <= 100),
created_by uuid NOT NULL REFERENCES admin_accounts(id),
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS redemption_codes (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
batch_id uuid NOT NULL REFERENCES redemption_batches(id) ON DELETE CASCADE,
code varchar(32) NOT NULL UNIQUE,
plan_code varchar(32) NOT NULL REFERENCES membership_plans(code),
status varchar(16) NOT NULL DEFAULT 'unused'
CHECK (status IN ('unused','redeemed','disabled')),
redeemed_by uuid NULL REFERENCES users(id),
redeemed_at timestamptz NULL,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_redemption_codes_batch ON redemption_codes(batch_id);
CREATE INDEX IF NOT EXISTS idx_redemption_codes_status ON redemption_codes(status);
INSERT INTO admin_role_permissions(role_id, code)
SELECT r.id, p.code
FROM admin_roles r
CROSS JOIN (VALUES
('admin.membership.codes.read'),
('admin.membership.codes.write')
) AS p(code)
WHERE r.name = 'super_admin'
ON CONFLICT DO NOTHING;