From b964fd0af8d7008e9bf3a5601dce1e395779ad1b Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Sun, 15 Mar 2026 07:49:09 +0000 Subject: [PATCH 1/4] [#78] Add ratings schema, RLS policy, and Database types - Migration 00005_ratings.sql: creates ratings table with score 1-5, unique constraint on (storyline_id, rater_address) for upsert pattern - RLS: public read (FOR SELECT USING (true)), no public write - Database type in lib/supabase.ts updated with ratings Row/Insert/Update - Added Rating convenience type alias Fixes #78 Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/supabase.ts | 30 +++++++++++++++++++++++++++ supabase/migrations/00005_ratings.sql | 17 +++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 supabase/migrations/00005_ratings.sql diff --git a/lib/supabase.ts b/lib/supabase.ts index ff32ad32..9e739d56 100644 --- a/lib/supabase.ts +++ b/lib/supabase.ts @@ -166,6 +166,35 @@ export interface Database { indexed_at?: string; }; }; + ratings: { + Row: { + id: number; + storyline_id: number; + rater_address: string; + score: number; + comment: string | null; + created_at: string; + updated_at: string; + }; + Insert: { + id?: never; + storyline_id: number; + rater_address: string; + score: number; + comment?: string | null; + created_at?: string; + updated_at?: string; + }; + Update: { + id?: never; + storyline_id?: number; + rater_address?: string; + score?: number; + comment?: string | null; + created_at?: string; + updated_at?: string; + }; + }; }; }; } @@ -174,3 +203,4 @@ export interface Database { export type Storyline = Database["public"]["Tables"]["storylines"]["Row"]; export type Plot = Database["public"]["Tables"]["plots"]["Row"]; export type Donation = Database["public"]["Tables"]["donations"]["Row"]; +export type Rating = Database["public"]["Tables"]["ratings"]["Row"]; diff --git a/supabase/migrations/00005_ratings.sql b/supabase/migrations/00005_ratings.sql new file mode 100644 index 00000000..d6c3ee26 --- /dev/null +++ b/supabase/migrations/00005_ratings.sql @@ -0,0 +1,17 @@ +-- Ratings table: one rating per user per storyline (upsert pattern) +-- Public read, no public write (writes via service role only) + +CREATE TABLE ratings ( + id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, + storyline_id BIGINT NOT NULL REFERENCES storylines(id), + rater_address TEXT NOT NULL, + score SMALLINT NOT NULL CHECK (score >= 1 AND score <= 5), + comment TEXT, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + UNIQUE (storyline_id, rater_address) +); + +ALTER TABLE ratings ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "Public read" ON ratings FOR SELECT USING (true); From b8ae70a2d05f3806cd877dbe63db61b23340c9a3 Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Sun, 15 Mar 2026 07:50:38 +0000 Subject: [PATCH 2/4] [#78] Fix ratings FK to reference storylines(storyline_id) + add index - FK now references storylines(storyline_id) matching existing pattern - Added idx_ratings_storyline index Co-Authored-By: Claude Opus 4.6 (1M context) --- supabase/migrations/00005_ratings.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/supabase/migrations/00005_ratings.sql b/supabase/migrations/00005_ratings.sql index d6c3ee26..55020862 100644 --- a/supabase/migrations/00005_ratings.sql +++ b/supabase/migrations/00005_ratings.sql @@ -3,7 +3,7 @@ CREATE TABLE ratings ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, - storyline_id BIGINT NOT NULL REFERENCES storylines(id), + storyline_id BIGINT NOT NULL REFERENCES storylines(storyline_id), rater_address TEXT NOT NULL, score SMALLINT NOT NULL CHECK (score >= 1 AND score <= 5), comment TEXT, @@ -12,6 +12,8 @@ CREATE TABLE ratings ( UNIQUE (storyline_id, rater_address) ); +CREATE INDEX idx_ratings_storyline ON ratings (storyline_id); + ALTER TABLE ratings ENABLE ROW LEVEL SECURITY; CREATE POLICY "Public read" ON ratings FOR SELECT USING (true); From 25872e98ebec14e989f727d544353d869e424c2d Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Sun, 15 Mar 2026 07:51:35 +0000 Subject: [PATCH 3/4] [#78] Rename score to rating to match issue spec Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/supabase.ts | 4 ++-- supabase/migrations/00005_ratings.sql | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/supabase.ts b/lib/supabase.ts index 9e739d56..aa31e288 100644 --- a/lib/supabase.ts +++ b/lib/supabase.ts @@ -171,7 +171,7 @@ export interface Database { id: number; storyline_id: number; rater_address: string; - score: number; + rating: number; comment: string | null; created_at: string; updated_at: string; @@ -180,7 +180,7 @@ export interface Database { id?: never; storyline_id: number; rater_address: string; - score: number; + rating: number; comment?: string | null; created_at?: string; updated_at?: string; diff --git a/supabase/migrations/00005_ratings.sql b/supabase/migrations/00005_ratings.sql index 55020862..d7af25f9 100644 --- a/supabase/migrations/00005_ratings.sql +++ b/supabase/migrations/00005_ratings.sql @@ -5,7 +5,7 @@ CREATE TABLE ratings ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, storyline_id BIGINT NOT NULL REFERENCES storylines(storyline_id), rater_address TEXT NOT NULL, - score SMALLINT NOT NULL CHECK (score >= 1 AND score <= 5), + rating SMALLINT NOT NULL CHECK (rating >= 1 AND rating <= 5), comment TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), From 1e96588739891464ddb83e319a71a86ac4d1086a Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Sun, 15 Mar 2026 07:52:15 +0000 Subject: [PATCH 4/4] [#78] Fix last score -> rating rename in Update type Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/supabase.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/supabase.ts b/lib/supabase.ts index aa31e288..61927afd 100644 --- a/lib/supabase.ts +++ b/lib/supabase.ts @@ -189,7 +189,7 @@ export interface Database { id?: never; storyline_id?: number; rater_address?: string; - score?: number; + rating?: number; comment?: string | null; created_at?: string; updated_at?: string;