-- +goose Up CREATE TABLE friendships ( low_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, high_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, sender_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, accepted boolean NOT NULL DEFAULT false, created_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY(low_id,high_id), CHECK(low_id < high_id), CHECK(sender_id IN (low_id,high_id)) ); CREATE INDEX friendships_high_idx ON friendships(high_id); CREATE TABLE social_blocks ( user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, peer_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, PRIMARY KEY(user_id,peer_id), CHECK(user_id <> peer_id) ); CREATE TABLE direct_messages ( seq bigserial PRIMARY KEY, id uuid NOT NULL UNIQUE, sender_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, recipient_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, text text NOT NULL DEFAULT '', attachment_kind text NOT NULL DEFAULT 'none' CHECK(attachment_kind IN ('none','track','playlist')), attachment_id uuid, created_at timestamptz NOT NULL DEFAULT now(), read_at timestamptz, CHECK(sender_id <> recipient_id), CHECK(length(text) <= 4000), CHECK((attachment_kind='none' AND attachment_id IS NULL AND length(trim(text))>0) OR (attachment_kind<>'none' AND attachment_id IS NOT NULL)) ); CREATE INDEX direct_messages_pair_idx ON direct_messages(LEAST(sender_id,recipient_id),GREATEST(sender_id,recipient_id),seq DESC); CREATE INDEX direct_messages_unread_idx ON direct_messages(recipient_id,sender_id,seq) WHERE read_at IS NULL; CREATE INDEX direct_messages_sender_time_idx ON direct_messages(sender_id,created_at DESC); CREATE TABLE social_notifications ( id uuid PRIMARY KEY, user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, actor_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, kind text NOT NULL CHECK(kind IN ('friend_request','friend_accepted','message','music')), message_seq bigint REFERENCES direct_messages(seq) ON DELETE CASCADE, created_at timestamptz NOT NULL DEFAULT now(), read_at timestamptz ); CREATE INDEX social_notifications_user_idx ON social_notifications(user_id,created_at DESC); CREATE INDEX social_notifications_request_rate_idx ON social_notifications(actor_id,created_at DESC) WHERE kind='friend_request'; -- +goose Down DROP TABLE social_notifications; DROP TABLE direct_messages; DROP TABLE social_blocks; DROP TABLE friendships;