Skip to content

feat(prisma): flatten migrations into single baseline (Supabase Phase 2) - #768

Merged
LucasSantana-Dev merged 9 commits into
mainfrom
feature/supabase-phase2-baseline
Apr 22, 2026
Merged

LucasSantana-Dev merged 9 commits into
mainfrom
feature/supabase-phase2-baseline

Conversation

@LucasSantana-Dev

Copy link
Copy Markdown
Owner

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

  • Adds `prisma/migrations/20250101000000_baseline/migration.sql` — 864 lines of DDL generated via `prisma migrate diff --from-empty --to-schema=prisma/schema.prisma --script --config=prisma/prisma.config.ts`. Contains 1 `CREATE SCHEMA`, 1 `CREATE TYPE` (`AutoplayMode`), all ~44 tables declared in `schema.prisma`, every index, every FK constraint.
  • Deletes all 18 historical migration folders. Their schema state is fully captured in the baseline.

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

Risk Mitigation
Self-hosted devs pull this PR and `prisma migrate dev` tries to re-run the baseline `migrate resolve --applied` step documented above; also works on developer machines
Baseline diverges from live self-hosted prod schema Baseline was generated from `schema.prisma`, which is the committed source of truth. If prod has drifted from schema, that's a separate incident. Running `prisma migrate diff --from-schema-datamodel=prisma/schema.prisma --to-config-datasource=prisma/prisma.config.ts` after merge would show any drift.
Cosmetic bug in historical migration `20260307220000` (camelCase table names) not preserved Confirmed via analysis that those `ALTER TABLE IF NOT EXISTS` statements were silent no-ops — columns never landed. Baseline reflects the actual schema.

Merge order

  1. PR feat(prisma): Prisma 7 config + DIRECT_URL fallback (Supabase Phase 1) #764 (Prisma 7 `prisma.config.ts` + `DIRECT_URL` fallback) — required for the CLI to know where to run migrations.
  2. This PR (baseline).
  3. Then on self-hosted: `prisma migrate resolve --applied 20250101000000_baseline`.
  4. Then on Supabase: `prisma migrate deploy` — full Phase 2/4 schema apply.

Test plan

  • Baseline SQL generated successfully (864 lines, 0 errors).
  • Credential scan of the generated SQL — only column names (`accessToken`, `refreshToken`) appear, no actual secrets.
  • CI: Quality Gates, SonarCloud, portability, Security.
  • After merge + `migrate resolve` on self-hosted: `prisma migrate status` should report "Database schema is up to date!".
  • After applying on `lucky-staging`: `list_tables` via Supabase MCP should show ~44 tables in `public`, matching `schema.prisma`.

🤖 Generated with Claude Code

…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>
@vercel

vercel Bot commented Apr 22, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lucky Ready Ready Preview, Comment Apr 22, 2026 11:53am

Request Review

@coderabbitai

coderabbitai Bot commented Apr 22, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@LucasSantana-Dev has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 53 minutes and 31 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0ce4e461-6de5-4bee-88f2-2c3b2a4940a2

📥 Commits

Reviewing files that changed from the base of the PR and between ced4a07 and b587185.

📒 Files selected for processing (20)
  • prisma/migrations/20250101000000_baseline/migration.sql
  • prisma/migrations/20250101000001_enable_rls_no_policies/migration.sql
  • prisma/migrations/20250128120000_add_twitch_notifications/migration.sql
  • prisma/migrations/20250129120000_add_lastfm_links/migration.sql
  • prisma/migrations/20260307210000_add_moderation_case_fields/migration.sql
  • prisma/migrations/20260307220000_add_missing_service_fields/migration.sql
  • prisma/migrations/20260311110000_add_guild_role_grants/migration.sql
  • prisma/migrations/20260311193000_add_guild_automation_manifest/migration.sql
  • prisma/migrations/20260326000000_fix_user_sessions_guild_fkey/migration.sql
  • prisma/migrations/20260330000000_add_automod_link_exempt_channels/migration.sql
  • prisma/migrations/20260331000000_add_live_boards/migration.sql
  • prisma/migrations/20260407000000_add_moderation_cases_guild_created_at_index/migration.sql
  • prisma/migrations/20260410000000_add_auto_roles/migration.sql
  • prisma/migrations/20260411000000_add_autoplay_mode/migration.sql
  • prisma/migrations/20260412000000_add_autoplay_genres/migration.sql
  • prisma/migrations/20260412100000_add_spotify_link/migration.sql
  • prisma/migrations/20260414000000_add_guild_feature_toggles/migration.sql
  • prisma/migrations/20260414100000_add_user_artist_preferences/migration.sql
  • prisma/migrations/20260420000000_add_member_birthdays/migration.sql
  • prisma/migrations/20260420030000_add_premium_tier_schema/migration.sql
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/supabase-phase2-baseline

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@LucasSantana-Dev
LucasSantana-Dev marked this pull request as ready for review April 22, 2026 05:48
@LucasSantana-Dev
LucasSantana-Dev enabled auto-merge (squash) April 22, 2026 05:48
LucasSantana-Dev and others added 2 commits April 22, 2026 03:03
…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.
@sonarqubecloud

Copy link
Copy Markdown

@LucasSantana-Dev
LucasSantana-Dev merged commit d903d21 into main Apr 22, 2026
12 checks passed
LucasSantana-Dev added a commit that referenced this pull request May 13, 2026
… 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>
@LucasSantana-Dev
LucasSantana-Dev deleted the feature/supabase-phase2-baseline branch May 14, 2026 02:02

This branch was successfully deployed

1 active deployment
Preview — b5871852 Deployed Apr 22, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant