131 lines
3.6 KiB
PL/PgSQL
131 lines
3.6 KiB
PL/PgSQL
-- Notifications table
|
|
CREATE TABLE notifications (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
type text NOT NULL CHECK (type IN ('new_podcast', 'like', 'comment')),
|
|
data jsonb NOT NULL DEFAULT '{}',
|
|
read boolean NOT NULL DEFAULT false,
|
|
created_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_notifications_user ON notifications(user_id, created_at DESC);
|
|
|
|
ALTER TABLE notifications ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY "Users can view their own notifications"
|
|
ON notifications FOR SELECT
|
|
USING (user_id = auth.uid());
|
|
|
|
CREATE POLICY "Users can update their own notifications"
|
|
ON notifications FOR UPDATE
|
|
USING (user_id = auth.uid())
|
|
WITH CHECK (user_id = auth.uid());
|
|
|
|
-- Trigger: notify followers when a new podcast is created
|
|
CREATE OR REPLACE FUNCTION notify_new_podcast()
|
|
RETURNS TRIGGER AS $$
|
|
DECLARE
|
|
creator_username text;
|
|
follower_record RECORD;
|
|
BEGIN
|
|
-- Skip scheduled podcasts
|
|
IF NEW.published_at IS NOT NULL AND NEW.published_at > now() THEN
|
|
RETURN NEW;
|
|
END IF;
|
|
|
|
SELECT username INTO creator_username FROM profiles WHERE id = NEW.creator_id;
|
|
|
|
FOR follower_record IN
|
|
SELECT follower_id FROM follows WHERE following_id = NEW.creator_id
|
|
LOOP
|
|
INSERT INTO notifications (user_id, type, data)
|
|
VALUES (
|
|
follower_record.follower_id,
|
|
'new_podcast',
|
|
jsonb_build_object(
|
|
'podcast_id', NEW.id,
|
|
'podcast_title', NEW.title,
|
|
'username', COALESCE(creator_username, 'Quelqu''un')
|
|
)
|
|
);
|
|
END LOOP;
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
|
|
CREATE TRIGGER on_podcast_created
|
|
AFTER INSERT ON podcasts
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION notify_new_podcast();
|
|
|
|
-- Trigger: notify podcast creator when someone likes their podcast
|
|
CREATE OR REPLACE FUNCTION notify_like()
|
|
RETURNS TRIGGER AS $$
|
|
DECLARE
|
|
liker_username text;
|
|
podcast_record RECORD;
|
|
BEGIN
|
|
SELECT username INTO liker_username FROM profiles WHERE id = NEW.user_id;
|
|
SELECT id, title, creator_id INTO podcast_record FROM podcasts WHERE id = NEW.podcast_id;
|
|
|
|
-- Don't notify if user likes their own podcast
|
|
IF podcast_record.creator_id = NEW.user_id THEN
|
|
RETURN NEW;
|
|
END IF;
|
|
|
|
INSERT INTO notifications (user_id, type, data)
|
|
VALUES (
|
|
podcast_record.creator_id,
|
|
'like',
|
|
jsonb_build_object(
|
|
'podcast_id', podcast_record.id,
|
|
'podcast_title', podcast_record.title,
|
|
'username', COALESCE(liker_username, 'Quelqu''un')
|
|
)
|
|
);
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
|
|
CREATE TRIGGER on_like_created
|
|
AFTER INSERT ON likes
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION notify_like();
|
|
|
|
-- Trigger: notify podcast creator when someone comments
|
|
CREATE OR REPLACE FUNCTION notify_comment()
|
|
RETURNS TRIGGER AS $$
|
|
DECLARE
|
|
commenter_username text;
|
|
podcast_record RECORD;
|
|
BEGIN
|
|
SELECT username INTO commenter_username FROM profiles WHERE id = NEW.user_id;
|
|
SELECT id, title, creator_id INTO podcast_record FROM podcasts WHERE id = NEW.podcast_id;
|
|
|
|
-- Don't notify if user comments on their own podcast
|
|
IF podcast_record.creator_id = NEW.user_id THEN
|
|
RETURN NEW;
|
|
END IF;
|
|
|
|
INSERT INTO notifications (user_id, type, data)
|
|
VALUES (
|
|
podcast_record.creator_id,
|
|
'comment',
|
|
jsonb_build_object(
|
|
'podcast_id', podcast_record.id,
|
|
'podcast_title', podcast_record.title,
|
|
'username', COALESCE(commenter_username, 'Quelqu''un')
|
|
)
|
|
);
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
|
|
CREATE TRIGGER on_comment_created
|
|
AFTER INSERT ON comments
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION notify_comment();
|