81 lines
3.4 KiB
SQL
81 lines
3.4 KiB
SQL
CREATE TABLE IF NOT EXISTS hwlab_redeem_codes (
|
|
id TEXT PRIMARY KEY,
|
|
code_hash TEXT NOT NULL UNIQUE,
|
|
code_prefix TEXT NOT NULL,
|
|
display_name TEXT NOT NULL DEFAULT '',
|
|
status TEXT NOT NULL DEFAULT 'active',
|
|
credit_amount BIGINT NOT NULL,
|
|
reason TEXT NOT NULL DEFAULT 'redeem',
|
|
max_redemptions INTEGER NOT NULL DEFAULT 1,
|
|
per_user_limit INTEGER NOT NULL DEFAULT 1,
|
|
redeemed_count INTEGER NOT NULL DEFAULT 0,
|
|
expires_at TIMESTAMPTZ,
|
|
created_by_user_id TEXT,
|
|
created_by_username TEXT,
|
|
disabled_at TIMESTAMPTZ,
|
|
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CHECK (status IN ('active', 'disabled', 'expired')),
|
|
CHECK (credit_amount > 0),
|
|
CHECK (max_redemptions > 0),
|
|
CHECK (per_user_limit > 0),
|
|
CHECK (redeemed_count >= 0)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS hwlab_redeem_codes_status_created_idx ON hwlab_redeem_codes(status, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS hwlab_redeem_codes_prefix_idx ON hwlab_redeem_codes(code_prefix);
|
|
|
|
CREATE TABLE IF NOT EXISTS hwlab_redeem_redemptions (
|
|
id TEXT PRIMARY KEY,
|
|
code_id TEXT NOT NULL REFERENCES hwlab_redeem_codes(id) ON DELETE CASCADE,
|
|
user_id TEXT NOT NULL REFERENCES hwlab_users(id) ON DELETE CASCADE,
|
|
ledger_id TEXT REFERENCES hwlab_credit_ledger(id) ON DELETE SET NULL,
|
|
credit_amount BIGINT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'applied',
|
|
idempotency_key TEXT UNIQUE,
|
|
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CHECK (credit_amount > 0),
|
|
CHECK (status IN ('applied', 'rejected'))
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS hwlab_redeem_redemptions_code_created_idx ON hwlab_redeem_redemptions(code_id, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS hwlab_redeem_redemptions_user_created_idx ON hwlab_redeem_redemptions(user_id, created_at DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS hwlab_user_subscriptions (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL REFERENCES hwlab_users(id) ON DELETE CASCADE,
|
|
plan_id TEXT NOT NULL REFERENCES hwlab_billing_plans(id),
|
|
status TEXT NOT NULL DEFAULT 'active',
|
|
source TEXT NOT NULL DEFAULT 'manual',
|
|
current_period_start TIMESTAMPTZ,
|
|
current_period_end TIMESTAMPTZ,
|
|
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CHECK (status IN ('active', 'trialing', 'past_due', 'canceled', 'disabled')),
|
|
CHECK (source IN ('manual', 'redeem', 'payment_placeholder', 'system'))
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS hwlab_user_subscriptions_user_status_idx ON hwlab_user_subscriptions(user_id, status, created_at DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS hwlab_payment_orders (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL REFERENCES hwlab_users(id) ON DELETE CASCADE,
|
|
provider TEXT NOT NULL DEFAULT 'unconfigured',
|
|
status TEXT NOT NULL DEFAULT 'unconfigured',
|
|
credit_amount BIGINT NOT NULL DEFAULT 0,
|
|
amount_minor BIGINT NOT NULL DEFAULT 0,
|
|
currency TEXT NOT NULL DEFAULT 'CNY',
|
|
reason TEXT NOT NULL DEFAULT '',
|
|
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CHECK (status IN ('unconfigured', 'created', 'pending', 'paid', 'failed', 'cancelled', 'refunded')),
|
|
CHECK (credit_amount >= 0),
|
|
CHECK (amount_minor >= 0)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS hwlab_payment_orders_user_created_idx ON hwlab_payment_orders(user_id, created_at DESC);
|