Files
OverCooked-Installer/s-migrations/000025_user_store_calendar_monitoring.up.sql
T

35 lines
1.7 KiB
SQL

ALTER TABLE membership_plans
ADD COLUMN price_points integer NOT NULL DEFAULT 0 CHECK(price_points >= 0),
ADD COLUMN self_service boolean NOT NULL DEFAULT false;
INSERT INTO membership_plans(code,name,duration_days,max_playbacks,max_devices,max_bitrate_kbps,price_points,self_service,enabled)
VALUES('points-30d','30 天会员',30,1,3,0,100,true,true)
ON CONFLICT(code) DO NOTHING;
ALTER TABLE point_ledger DROP CONSTRAINT 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'));
CREATE TABLE membership_purchases (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
plan_id uuid NOT NULL REFERENCES membership_plans(id),
price_points integer NOT NULL CHECK(price_points >= 0),
membership_id uuid REFERENCES memberships(id),
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX membership_purchases_user_time_idx ON membership_purchases(user_id,created_at DESC);
CREATE TABLE watch_calendar_entries (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
title text NOT NULL CHECK(length(btrim(title)) BETWEEN 1 AND 200),
episode_label text NOT NULL DEFAULT '' CHECK(length(episode_label) <= 100),
next_episode_at timestamptz NOT NULL,
notes text NOT NULL DEFAULT '' CHECK(length(notes) <= 1000),
completed boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX watch_calendar_user_time_idx ON watch_calendar_entries(user_id,completed,next_episode_at);