Repository navigation
feat(prisma): flatten migrations into single baseline (Supabase Phase 2) - #768
Conversation
…e Phase 2) Supabase migration Phase 2 (plan: .claude/plans/supabase-migration-2026-04-21.md; preview: .claude/plans/supabase-phase2-preview-2026-04-22.md). ## Why `prisma migrate deploy` against a fresh Postgres fails on migration #1 (20250128120000_add_twitch_notifications) because it assumes `guilds` and 20+ other tables already exist. Those tables were originally created by `prisma db push` in the pre-2025 era and never captured as a migration. Self-hosted prod has them; a fresh Supabase project doesn't. Two paths to fix: (A) add a baseline migration that creates the pre-existing tables, keeping the 18 historical migrations as later steps, or (B) flatten everything into one baseline and drop the 18. ## What this PR does — option B, flatten - Generates `prisma/migrations/20250101000000_baseline/migration.sql` via `prisma migrate diff --from-empty --to-schema=prisma/schema.prisma`. 864 lines of DDL: 1 schema, 1 enum, all tables in schema.prisma, every index, every FK constraint. - Deletes the 18 historical migration folders. Their schema state is entirely subsumed by the baseline. ## Deployment note — self-hosted prod needs one `migrate resolve` After merge, on the self-hosted prod DB (not on Supabase which has no data yet): ``` DIRECT_URL=<self-hosted-prod> npx prisma migrate resolve \ --applied 20250101000000_baseline ``` This inserts a single row into `_prisma_migrations` marking the baseline as applied without running the SQL (which would collide with existing tables). The 18 orphaned historical rows stay but are harmless — Prisma ignores entries without corresponding folders. ## Deployment note — Supabase On fresh `lucky-prod` / `lucky-staging`: ``` DIRECT_URL=<supabase-direct> npx prisma migrate deploy ``` Single baseline applies, schema matches `schema.prisma`. Done. ## Test plan - [x] `prisma migrate diff` ran clean against schema.prisma. - [x] Generated SQL scanned for credentials — none found (only column names like `accessToken` / `refreshToken` — Spotify link table). - [ ] CI: Quality Gates, SonarCloud, Security. - [ ] Merge blocker: depends on PR #764 (Prisma 7 `prisma.config.ts`) being merged first so Prisma CLI knows to use `DIRECT_URL`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 53 minutes and 31 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (20)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…deny) Supabase exposes the public schema via PostgREST's anon / authenticated roles by default, which tripped 39 ERROR-level `rls_disabled_in_public` advisor lints. Enable RLS on every table; don't add policies. Bot and backend use the postgres role which bypasses RLS, so behavior is unchanged. PostgREST traffic (anon/authenticated) is now default-deny. On non-Supabase self-hosted Postgres this is still safe: ENABLE RLS without any policies means only the owning role (our single DB user) can read/write, which matches current behavior. Applied live via Supabase MCP to both lucky-prod (uhfpqqraxlicmquejkkz) and lucky-staging (cirywcaamzqbujrdsfvu) this session. Advisor lints now INFO-level (`rls_enabled_no_policy`) instead of ERROR.
|
… 2) (#768) * feat(prisma): flatten migration history into single baseline (Supabase Phase 2) Supabase migration Phase 2 (plan: .claude/plans/supabase-migration-2026-04-21.md; preview: .claude/plans/supabase-phase2-preview-2026-04-22.md). ## Why `prisma migrate deploy` against a fresh Postgres fails on migration #1 (20250128120000_add_twitch_notifications) because it assumes `guilds` and 20+ other tables already exist. Those tables were originally created by `prisma db push` in the pre-2025 era and never captured as a migration. Self-hosted prod has them; a fresh Supabase project doesn't. Two paths to fix: (A) add a baseline migration that creates the pre-existing tables, keeping the 18 historical migrations as later steps, or (B) flatten everything into one baseline and drop the 18. ## What this PR does — option B, flatten - Generates `prisma/migrations/20250101000000_baseline/migration.sql` via `prisma migrate diff --from-empty --to-schema=prisma/schema.prisma`. 864 lines of DDL: 1 schema, 1 enum, all tables in schema.prisma, every index, every FK constraint. - Deletes the 18 historical migration folders. Their schema state is entirely subsumed by the baseline. ## Deployment note — self-hosted prod needs one `migrate resolve` After merge, on the self-hosted prod DB (not on Supabase which has no data yet): ``` DIRECT_URL=<self-hosted-prod> npx prisma migrate resolve \ --applied 20250101000000_baseline ``` This inserts a single row into `_prisma_migrations` marking the baseline as applied without running the SQL (which would collide with existing tables). The 18 orphaned historical rows stay but are harmless — Prisma ignores entries without corresponding folders. ## Deployment note — Supabase On fresh `lucky-prod` / `lucky-staging`: ``` DIRECT_URL=<supabase-direct> npx prisma migrate deploy ``` Single baseline applies, schema matches `schema.prisma`. Done. ## Test plan - [x] `prisma migrate diff` ran clean against schema.prisma. - [x] Generated SQL scanned for credentials — none found (only column names like `accessToken` / `refreshToken` — Spotify link table). - [ ] CI: Quality Gates, SonarCloud, Security. - [ ] Merge blocker: depends on PR #764 (Prisma 7 `prisma.config.ts`) being merged first so Prisma CLI knows to use `DIRECT_URL`. * feat(prisma): enable RLS on all public tables (no policies = default-deny) Supabase exposes the public schema via PostgREST's anon / authenticated roles by default, which tripped 39 ERROR-level `rls_disabled_in_public` advisor lints. Enable RLS on every table; don't add policies. Bot and backend use the postgres role which bypasses RLS, so behavior is unchanged. PostgREST traffic (anon/authenticated) is now default-deny. On non-Supabase self-hosted Postgres this is still safe: ENABLE RLS without any policies means only the owning role (our single DB user) can read/write, which matches current behavior. Applied live via Supabase MCP to both lucky-prod (uhfpqqraxlicmquejkkz) and lucky-staging (cirywcaamzqbujrdsfvu) this session. Advisor lints now INFO-level (`rls_enabled_no_policy`) instead of ERROR. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>



Summary
Phase 2 of the Supabase migration. Replaces the 18 incremental migrations with one consolidated baseline so `prisma migrate deploy` can run against an empty Postgres (fresh Supabase) without tripping on the missing pre-2025 schema.
Plan: `.claude/plans/supabase-migration-2026-04-21.md`
Preview + analysis: `.claude/plans/supabase-phase2-preview-2026-04-22.md`
Problem this solves
The 18 migrations in `prisma/migrations/` all `CREATE TABLE` or `ALTER TABLE` tables that they assume already exist (`guilds`, `users`, `guild_settings`, etc.). Those were originally created via `prisma db push` in the pre-2025 era. Self-hosted prod has them; a fresh Postgres doesn't. The 2026-03-26 FK-fix migration explicitly catches missing tables with `DO $$ ... EXCEPTION WHEN undefined_table ...` — the author knew.
What this PR does
Deploying to Supabase (fresh)
After this PR + PR #764 merge, on `lucky-staging` / `lucky-prod`:
```bash
DIRECT_URL='postgresql://postgres:@db..supabase.co:5432/postgres' \
npx prisma migrate deploy
```
Single baseline applies. Schema matches `schema.prisma`. No pre-existing state assumptions.
Deploying to self-hosted prod (has pre-existing state)
One-shot, idempotent:
```bash
DIRECT_URL='' \
npx prisma migrate resolve --applied 20250101000000_baseline
```
This inserts a row into `_prisma_migrations` marking the baseline as applied without running the SQL (which would collide with existing tables). The 18 orphaned historical rows are harmless; Prisma ignores entries without corresponding folders.
Risks + mitigations
Merge order
Test plan
🤖 Generated with Claude Code