feat(reactions): per-user like/dislike on mangas
Add a private per-user reaction resource: a manga_reactions table (one row per user+manga, like/dislike, cascades) and endpoints PUT/DELETE /mangas/:id/reaction plus GET /me/reactions/:manga_id, wired on the existing per-user seam (mirrors bookmarks/read_progress). Unknown manga → 404 via the FK-violation mapping; an invalid reaction value → 422. Reactions are never exposed publicly — this is a taste signal for the upcoming content-based recommendations. Integration tests cover set/toggle/clear/read, per-user isolation, and the 404/422/401 paths. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
15
backend/migrations/0035_manga_reactions.sql
Normal file
15
backend/migrations/0035_manga_reactions.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- Per-user like/dislike reactions on mangas — a private taste signal that
|
||||
-- powers content-based recommendations. One row per (user, manga); the
|
||||
-- `reaction` column toggles between 'like' and 'dislike', and clearing a
|
||||
-- reaction deletes the row. Reactions are never exposed publicly (no counts).
|
||||
CREATE TABLE manga_reactions (
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
manga_id uuid NOT NULL REFERENCES mangas(id) ON DELETE CASCADE,
|
||||
reaction text NOT NULL CHECK (reaction IN ('like', 'dislike')),
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (user_id, manga_id)
|
||||
);
|
||||
|
||||
-- Recommendations aggregate a user's reacted mangas by tag; the PK covers
|
||||
-- per-user lookups, this covers the reverse (all reactions on a manga).
|
||||
CREATE INDEX manga_reactions_manga_idx ON manga_reactions (manga_id);
|
||||
Reference in New Issue
Block a user