Fix Follow System: Add missing follows table migration#486
Conversation
Greptile SummaryThis migration attempts to add a
Confidence Score: 1/5This migration will break the deployment pipeline on any environment where migrations have been applied sequentially — it cannot be applied without erroring. The The single changed file Important Files Changed
Sequence DiagramsequenceDiagram
participant Supabase as Supabase Migrations
participant Feb as 20260201090000_follow_system.sql
participant New as 20260615000000_add_user_follows.sql
Supabase->>Feb: Apply (already applied)
Note over Feb: CREATE TABLE IF NOT EXISTS follows<br/>+ id UUID PK, NOT NULL FKs<br/>+ RLS policies (SELECT/INSERT/DELETE)<br/>+ update_follow_counts trigger
Supabase->>New: Apply (this PR)
New-->>Supabase: ERROR: relation "follows" already exists
Note over New: Migration aborted — no IF NOT EXISTS guard<br/>Duplicate schema, duplicate policy names
Reviews (1): Last reviewed commit: "Add user follows migration" | Re-trigger Greptile |
| CREATE TABLE follows ( | ||
| follower_id UUID REFERENCES profiles(id) ON DELETE CASCADE, | ||
| following_id UUID REFERENCES profiles(id) ON DELETE CASCADE, | ||
| created_at TIMESTAMPTZ DEFAULT NOW(), | ||
| PRIMARY KEY (follower_id, following_id), | ||
| CHECK (follower_id != following_id) | ||
| ); |
There was a problem hiding this comment.
Duplicate table — migration will crash at runtime
The follows table was already created in supabase/migrations/20260201090000_follow_system.sql (line 5) using CREATE TABLE IF NOT EXISTS follows. This new migration uses a bare CREATE TABLE follows with no IF NOT EXISTS guard, so when Supabase applies migrations sequentially it will hit ERROR: relation "follows" already exists and abort, leaving the database in an inconsistent migration state. The PR description's premise that the table was missing is incorrect — it has existed since the Feb 1 migration.
| CREATE TABLE follows ( | ||
| follower_id UUID REFERENCES profiles(id) ON DELETE CASCADE, | ||
| following_id UUID REFERENCES profiles(id) ON DELETE CASCADE, | ||
| created_at TIMESTAMPTZ DEFAULT NOW(), | ||
| PRIMARY KEY (follower_id, following_id), | ||
| CHECK (follower_id != following_id) | ||
| ); |
There was a problem hiding this comment.
Schema incompatible with existing table
The existing follows table in 20260201090000_follow_system.sql has a surrogate id UUID PRIMARY KEY DEFAULT gen_random_uuid() with a separate UNIQUE(follower_id, following_id) constraint, and both FK columns declared NOT NULL. This migration removes the id column entirely, promotes (follower_id, following_id) to the primary key, and drops the NOT NULL constraints — meaning any application code or FK reference relying on the id column, or the count-maintenance trigger (on_follow_change), would break.
| CREATE POLICY "Follows are viewable by everyone" ON follows FOR SELECT USING (true); | ||
| CREATE POLICY "Users can manage their own follows" ON follows FOR ALL USING (auth.uid() = follower_id); |
There was a problem hiding this comment.
Duplicate RLS policy name will error;
FOR ALL without WITH CHECK weakens insert safety
The policy "Follows are viewable by everyone" already exists on the follows table (created in 20260201090000_follow_system.sql), so CREATE POLICY will throw ERROR: policy "Follows are viewable by everyone" for table "follows" already exists. Additionally, the FOR ALL USING (auth.uid() = follower_id) policy omits an explicit WITH CHECK clause; PostgreSQL will fall back to using the USING expression for insert checks, but the intent is ambiguous and diverges from the existing pattern of separate FOR INSERT WITH CHECK and FOR DELETE USING policies that make the authorization contract explicit.
The follow API route exists but the table was missing from the database migrations. This PR adds the migration with RLS policies.