81 lines
4.3 KiB
SQL
81 lines
4.3 KiB
SQL
CREATE TABLE point_rules (
|
|
rule_key text PRIMARY KEY CHECK (rule_key ~ '^[a-z0-9][a-z0-9._-]{0,63}$'),
|
|
name text NOT NULL CHECK (char_length(btrim(name)) BETWEEN 1 AND 128),
|
|
points integer NOT NULL CHECK (points BETWEEN -100000 AND 100000),
|
|
enabled boolean NOT NULL DEFAULT true,
|
|
description text NOT NULL DEFAULT '' CHECK (char_length(description) <= 1000),
|
|
updated_by uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
INSERT INTO point_rules(rule_key,name,points,description) VALUES
|
|
('playback.completed','有效观看',5,'单次观看达到 10 分钟后奖励,每个播放会话仅奖励一次'),
|
|
('feedback.accepted','有效反馈',10,'管理员确认媒体问题后奖励');
|
|
|
|
CREATE TABLE point_accounts (
|
|
user_id uuid PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
|
balance bigint NOT NULL DEFAULT 0 CHECK (balance >= 0),
|
|
lifetime_earned bigint NOT NULL DEFAULT 0 CHECK (lifetime_earned >= 0),
|
|
lifetime_spent bigint NOT NULL DEFAULT 0 CHECK (lifetime_spent >= 0),
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE point_ledger (
|
|
id bigserial PRIMARY KEY,
|
|
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
delta integer NOT NULL CHECK (delta <> 0 AND delta BETWEEN -100000 AND 100000),
|
|
balance_after bigint NOT NULL CHECK (balance_after >= 0),
|
|
reason text NOT NULL CHECK (char_length(btrim(reason)) BETWEEN 1 AND 200),
|
|
source_type text NOT NULL DEFAULT 'manual' CHECK (source_type IN ('manual','playback_session','media_feedback','redemption')),
|
|
source_id text NOT NULL DEFAULT '' CHECK (char_length(source_id) <= 128),
|
|
actor_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
UNIQUE(user_id,source_type,source_id)
|
|
);
|
|
CREATE INDEX point_ledger_user_time_idx ON point_ledger(user_id,created_at DESC,id DESC);
|
|
|
|
CREATE TABLE media_feedback (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
media_id uuid,
|
|
source_id uuid,
|
|
playback_session_id uuid REFERENCES playback_sessions(id) ON DELETE SET NULL,
|
|
category text NOT NULL CHECK (category IN ('playback','subtitle','audio','metadata','quality','other')),
|
|
title text NOT NULL CHECK (char_length(btrim(title)) BETWEEN 1 AND 200),
|
|
detail text NOT NULL CHECK (char_length(btrim(detail)) BETWEEN 1 AND 5000),
|
|
status text NOT NULL DEFAULT 'submitted' CHECK (status IN ('submitted','reviewing','resolved','rejected')),
|
|
priority text NOT NULL DEFAULT 'normal' CHECK (priority IN ('low','normal','high','urgent')),
|
|
resolution text NOT NULL DEFAULT '' CHECK (char_length(resolution) <= 5000),
|
|
assigned_to uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
resolved_by uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
resolved_at timestamptz,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
CREATE INDEX media_feedback_user_time_idx ON media_feedback(user_id,created_at DESC);
|
|
CREATE INDEX media_feedback_queue_idx ON media_feedback(status,priority,updated_at DESC);
|
|
|
|
CREATE TABLE telegram_bot_settings (
|
|
singleton boolean PRIMARY KEY DEFAULT true CHECK (singleton),
|
|
enabled boolean NOT NULL DEFAULT true,
|
|
commands_enabled boolean NOT NULL DEFAULT true,
|
|
rate_limit_per_minute integer NOT NULL DEFAULT 12 CHECK (rate_limit_per_minute BETWEEN 1 AND 120),
|
|
welcome_message text NOT NULL DEFAULT '欢迎使用站点助手,请先绑定账户。' CHECK (char_length(welcome_message) BETWEEN 1 AND 1000),
|
|
maintenance_message text NOT NULL DEFAULT '' CHECK (char_length(maintenance_message) <= 1000),
|
|
updated_by uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
INSERT INTO telegram_bot_settings(singleton) VALUES(true);
|
|
|
|
CREATE TABLE telegram_command_logs (
|
|
id bigserial PRIMARY KEY,
|
|
telegram_user_id bigint NOT NULL,
|
|
user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
command text NOT NULL CHECK (char_length(command) BETWEEN 1 AND 64),
|
|
result text NOT NULL CHECK (char_length(result) BETWEEN 1 AND 64),
|
|
duration_ms integer NOT NULL DEFAULT 0 CHECK (duration_ms >= 0),
|
|
created_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
CREATE INDEX telegram_command_logs_rate_idx ON telegram_command_logs(telegram_user_id,created_at DESC);
|
|
CREATE INDEX telegram_command_logs_admin_idx ON telegram_command_logs(created_at DESC,id DESC);
|