feat: add post like
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
DROP TABLE IF EXISTS post_likes;
|
||||
ALTER TABLE posts DROP COLUMN IF EXISTS likes_count;
|
||||
@@ -0,0 +1,26 @@
|
||||
-- Post likes.
|
||||
--
|
||||
-- `post_likes` is the membership table (one row per user-per-post like),
|
||||
-- written synchronously so a viewer's like state and the "liked by" list are
|
||||
-- immediately consistent. The UNIQUE(post_id, user_id) makes liking idempotent.
|
||||
--
|
||||
-- `posts.likes_count` is a denormalized counter that is NOT updated on every
|
||||
-- like (that hot-row UPDATE doesn't scale for popular posts). Instead each
|
||||
-- like/unlike nudges a per-post delta in Redis, and a background worker folds
|
||||
-- the deltas into this column every 15 minutes. Reads return
|
||||
-- likes_count + the still-pending Redis delta, so the displayed total is
|
||||
-- always current.
|
||||
ALTER TABLE posts ADD COLUMN IF NOT EXISTS likes_count INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS post_likes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
post_id UUID NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE (post_id, user_id)
|
||||
);
|
||||
|
||||
-- Listing "who liked this post", newest first.
|
||||
CREATE INDEX IF NOT EXISTS post_likes_post_idx ON post_likes (post_id, created_at DESC);
|
||||
-- "Have I liked these posts?" — viewer-state hydration across a feed.
|
||||
CREATE INDEX IF NOT EXISTS post_likes_user_idx ON post_likes (user_id);
|
||||
@@ -0,0 +1,3 @@
|
||||
DROP INDEX IF EXISTS notifications_post_like_uq;
|
||||
ALTER TABLE notifications DROP COLUMN IF EXISTS actor_count;
|
||||
ALTER TABLE notifications DROP COLUMN IF EXISTS post_id;
|
||||
@@ -0,0 +1,14 @@
|
||||
-- Aggregated like notifications.
|
||||
--
|
||||
-- Likes are high-volume, so instead of one notification row per like we keep a
|
||||
-- single row per (recipient, post) and aggregate: actor_id holds the most
|
||||
-- recent liker, actor_count how many distinct likers have aggregated into it.
|
||||
-- The partial unique index lets the like path UPSERT that one row (bumping the
|
||||
-- count, refreshing the actor, re-marking unread) — so the activity list shows
|
||||
-- "X and N others liked your post", not a flood.
|
||||
ALTER TABLE notifications ADD COLUMN IF NOT EXISTS post_id UUID REFERENCES posts(id) ON DELETE CASCADE;
|
||||
ALTER TABLE notifications ADD COLUMN IF NOT EXISTS actor_count INTEGER NOT NULL DEFAULT 1;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS notifications_post_like_uq
|
||||
ON notifications (user_id, post_id)
|
||||
WHERE kind = 'post_like';
|
||||
Reference in New Issue
Block a user