Files
OverCooked-Installer/s-migrations/000043_plugin_v11.up.sql
T

105 lines
5.0 KiB
SQL

CREATE TABLE IF NOT EXISTS plugin_user_policies (
user_id uuid PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
is_disabled boolean NOT NULL DEFAULT false,
is_administrator boolean NOT NULL DEFAULT false,
allow_video_playback boolean NOT NULL DEFAULT true,
allow_audio_playback boolean NOT NULL DEFAULT true,
allow_content_downloading boolean NOT NULL DEFAULT false,
enable_remote_access boolean NOT NULL DEFAULT true,
enabled_library_ids text[] NOT NULL DEFAULT '{}',
blocked_library_ids text[] NOT NULL DEFAULT '{}',
max_concurrent_streams integer NOT NULL DEFAULT 0 CHECK (max_concurrent_streams >= 0),
updated_at timestamptz NOT NULL DEFAULT now()
);
ALTER TABLE playback_decisions
ADD COLUMN IF NOT EXISTS media_type text NOT NULL DEFAULT '' CHECK (media_type IN ('','video','audio'));
ALTER TABLE playback_sessions
ADD COLUMN IF NOT EXISTS media_type text NOT NULL DEFAULT '' CHECK (media_type IN ('','video','audio'));
CREATE INDEX IF NOT EXISTS playback_sessions_plugin_report_idx ON playback_sessions(created_at DESC,user_id);
CREATE TABLE IF NOT EXISTS user_group_media_policies (
group_id uuid PRIMARY KEY REFERENCES user_groups(id) ON DELETE CASCADE,
enabled_library_ids text[] NOT NULL DEFAULT '{}',
blocked_library_ids text[] NOT NULL DEFAULT '{}',
updated_by uuid REFERENCES users(id),
updated_at timestamptz NOT NULL DEFAULT now(),
CHECK (cardinality(enabled_library_ids) <= 500),
CHECK (cardinality(blocked_library_ids) <= 500)
);
ALTER TABLE invite_codes
ADD COLUMN IF NOT EXISTS owner_reward_points integer NOT NULL DEFAULT 0 CHECK (owner_reward_points >= 0),
ADD COLUMN IF NOT EXISTS owner_reward_membership_days integer NOT NULL DEFAULT 0 CHECK (owner_reward_membership_days >= 0),
ADD COLUMN IF NOT EXISTS redeemer_reward_points integer NOT NULL DEFAULT 0 CHECK (redeemer_reward_points >= 0),
ADD COLUMN IF NOT EXISTS redeemer_reward_membership_days integer NOT NULL DEFAULT 0 CHECK (redeemer_reward_membership_days >= 0);
CREATE TABLE IF NOT EXISTS invite_redemptions (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
invite_id uuid NOT NULL REFERENCES invite_codes(id) ON DELETE CASCADE,
redeemed_by_user_id uuid NOT NULL REFERENCES users(id),
idempotency_key text NOT NULL CHECK (char_length(idempotency_key) BETWEEN 1 AND 256),
owner_reward_points integer NOT NULL DEFAULT 0,
owner_reward_membership_days integer NOT NULL DEFAULT 0,
redeemer_reward_points integer NOT NULL DEFAULT 0,
redeemer_reward_membership_days integer NOT NULL DEFAULT 0,
redeemed_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (invite_id, redeemed_by_user_id),
UNIQUE (invite_id, idempotency_key)
);
CREATE INDEX IF NOT EXISTS invite_redemptions_user_time_idx ON invite_redemptions(redeemed_by_user_id,redeemed_at DESC);
INSERT INTO membership_plans(code,name,duration_days,max_playbacks,max_devices,max_bitrate_kbps,price_points,self_service,enabled)
VALUES('points-7d','7 天会员',7,1,3,0,30,true,true)
ON CONFLICT(code) DO NOTHING;
ALTER TABLE point_ledger DROP CONSTRAINT IF EXISTS point_ledger_source_type_check;
ALTER TABLE point_ledger ADD CONSTRAINT point_ledger_source_type_check CHECK (source_type IN (
'manual','playback_session','media_feedback','redemption','daily_checkin',
'membership_purchase','telegram_red_packet','invite_reward'
));
CREATE TABLE IF NOT EXISTS plugin_telegram_contexts (
token_hash bytea PRIMARY KEY,
plugin_id text NOT NULL,
tenant_id text NOT NULL,
telegram_user_id bigint NOT NULL,
chat_id bigint NOT NULL,
telegram_username text NOT NULL DEFAULT '',
expires_at timestamptz NOT NULL,
consumed_at timestamptz,
created_at timestamptz NOT NULL DEFAULT now(),
CHECK (expires_at > created_at)
);
CREATE INDEX IF NOT EXISTS plugin_telegram_contexts_expiry_idx ON plugin_telegram_contexts(expires_at) WHERE consumed_at IS NULL;
CREATE TABLE IF NOT EXISTS plugin_telegram_sends (
plugin_id text NOT NULL,
tenant_id text NOT NULL,
action text NOT NULL CHECK (action IN ('send_photo','send_document')),
idempotency_key text NOT NULL CHECK (char_length(idempotency_key) BETWEEN 1 AND 256),
status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','sent')),
message_id bigint NOT NULL DEFAULT 0,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (plugin_id,tenant_id,action,idempotency_key)
);
CREATE INDEX IF NOT EXISTS plugin_telegram_sends_pending_idx ON plugin_telegram_sends(updated_at) WHERE status='pending';
CREATE TABLE IF NOT EXISTS plugin_audit_records (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
plugin_id text NOT NULL,
plugin_version text NOT NULL,
tenant_id text NOT NULL,
actor_type text NOT NULL,
actor_id text NOT NULL,
action text NOT NULL,
target_type text NOT NULL,
target_id text NOT NULL DEFAULT '',
request_id text NOT NULL DEFAULT '',
trace_id text NOT NULL DEFAULT '',
result text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS plugin_audit_records_plugin_time_idx ON plugin_audit_records(plugin_id,tenant_id,created_at DESC,id DESC);