Skip to content

feat(NES-47): support Supabase migrations and session store over the pooler - #65

Merged
ericfisherdev merged 2 commits into
mainfrom
nes-47-supabase-migrations
Jun 21, 2026
Merged

feat(NES-47): support Supabase migrations and session store over the pooler#65
ericfisherdev merged 2 commits into
mainfrom
nes-47-supabase-migrations

Conversation

@ericfisherdev

@ericfisherdev ericfisherdev commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Summary

Makes the two stateful Postgres consumers — goose schema migrations and the scs/pgxstore session store — work correctly against Supabase (NES-47). Builds on the connection/exec-mode plumbing from NES-46.

Changes

  • config: new MIGRATE_DATABASE_URL (DBConfig.MigrateDSN). Empty means "reuse DATABASE_URL"; operators point it at the Supabase direct/session connection (port 5432) so DDL and goose version bookkeeping run on a session connection while the app server uses the transaction pooler (6543).
  • migrate: new variadic Option API with PoolerSafe(). The pooler-safe path opens the database/sql handle via stdlib.OpenDB configured for the simple query protocol, so goose's bookkeeping carries no named server-side prepared statements through a transaction pooler. The default path is unchanged.
  • cmd/migrate: migrateSettings resolves the effective DSN and enables pooler-safe only when migrations would otherwise run through the Supabase transaction pooler (no dedicated migrate DSN + DB_PROVIDER=supabase + DB_POOL_MODE=transaction). The preferred path is a direct/session MIGRATE_DATABASE_URL.
  • sessions: scs/pgxstore issues queries on the shared pool, so it inherits QueryExecModeExec from NES-46 — no code change. A DB-gated test pins create/read/refresh/delete under exec mode.
  • tests: unit tests for poolerSafeConnConfig (simple protocol), migrateSettings (DSN + option selection), and the MIGRATE_DATABASE_URL config capture; plus the DB-gated session-store test. No live DB required for the unit tests.
  • docs: README migrations section documents MIGRATE_DATABASE_URL and the session-connection requirement.

Acceptance criteria

  • migrate up|down|status|reset works against a Supabase database (direct/session); existing migrate_test.go round-trip runs against any NESTOVA_TEST_DATABASE_URL including Supabase.
  • MIGRATE_DATABASE_URL is used when set; otherwise DATABASE_URL, no behavior change for existing Postgres.
  • pgxstore create/read/refresh/delete succeed under exec mode (DB-gated test).
  • lint/fmt/CI clean; unit tests need no live database.

Jira: NES-47

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for separate migration database connection via MIGRATE_DATABASE_URL environment variable, enabling migrations to target a dedicated connection when required.
    • Automatic fallback to simplified query protocol for migrations when no separate connection is configured.
  • Documentation

    • Updated database migrations section with configuration details and override behavior.

…pooler

- config: add MIGRATE_DATABASE_URL (DBConfig.MigrateDSN); empty reuses
  DATABASE_URL, so operators can run migrations against the Supabase
  direct/session connection while the app server points at the transaction
  pooler.
- migrate: add a variadic Option API with PoolerSafe(), which opens the
  database/sql handle via stdlib.OpenDB with the simple query protocol so goose
  version bookkeeping does not rely on named server-side prepared statements
  through a transaction pooler. The default path is unchanged.
- cmd/migrate: resolve the effective migrate DSN and enable pooler-safe only when
  migrations would otherwise run through the Supabase transaction pooler (no
  dedicated migrate DSN, provider supabase, pool mode transaction).
- tests: unit-test the pooler-safe conn config, the migrateSettings decision, and
  the MIGRATE_DATABASE_URL config capture; add a DB-gated test that exercises
  scs/pgxstore create/read/refresh/delete under QueryExecModeExec.
- docs: document MIGRATE_DATABASE_URL and the session-connection requirement in
  the README migrations section.

Why: goose DDL/bookkeeping and pgxstore must work correctly against Supabase.
Migrations need a session connection; the app pool runs pooler-safe exec mode
(NES-46), and pgxstore inherits it, so this confirms and pins that behavior.
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ericfisherdev, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 49 minutes and 55 seconds. Learn how PR review limits work.

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 342f5c7a-8d66-42c2-bf73-d32b5de53cc4

📥 Commits

Reviewing files that changed from the base of the PR and between dae1ea6 and 75c695d.

📒 Files selected for processing (1)
  • README.md
📝 Walkthrough

Walkthrough

Adds MIGRATE_DATABASE_URL support: a new MigrateDSN field in DBConfig is read from the environment and used by cmd/migrate via a new migrateSettings helper. The migrate package gains a PoolerSafe() functional option that switches the goose connection to QueryExecModeSimpleProtocol via pgx/stdlib. A session store integration test validates CRUD under QueryExecModeExec. README documents both behaviors.

Changes

Pooler-safe migration support

Layer / File(s) Summary
DBConfig.MigrateDSN field and config loading
internal/platform/config/config.go, internal/platform/config/config_test.go
DBConfig gains an exported MigrateDSN field populated by Load() from MIGRATE_DATABASE_URL. Config tests add the new env key to allKeys and assert it is mapped correctly for a Supabase transaction pool configuration.
PoolerSafe option and openDB helper in migrate package
internal/platform/db/migrate/migrate.go, internal/platform/db/migrate/migrate_test.go
Up/Down/Status/Reset now accept variadic Option arguments. PoolerSafe() sets DefaultQueryExecMode to QueryExecModeSimpleProtocol via a new openDB/poolerSafeConnConfig helper path using pgx/v5/stdlib. TestPoolerSafeConnConfig verifies the mode and invalid-DSN error.
migrateSettings dispatch in cmd/migrate
cmd/migrate/main.go, cmd/migrate/main_test.go
Command dispatch now calls migrateSettings to resolve the migration DSN and options. It prefers MigrateDSN when set; otherwise falls back to the main DSN and appends PoolerSafe() when the provider is Supabase with transaction pool mode. TestMigrateSettings covers all four configuration branches.
Session store pooler-safe integration test and README
internal/auth/adapter/session_pooler_test.go, README.md
TestSessionStorePoolerSafe is a DB-gated test that resets/migrates the schema, opens a pgxpool with QueryExecModeExec and no statement caches, then exercises Commit/Find/refresh-Commit/Delete on the session store. README documents the MIGRATE_DATABASE_URL override and simple-protocol fallback.

Possibly related issues

  • NES-47 — This PR implements the full acceptance criteria for NES-47: MIGRATE_DATABASE_URL config, PoolerSafe() option in the migrate runner, migrateSettings() in cmd/migrate, and the DB-gated session store round-trip test under transaction pooler exec mode.
  • NES-46 — The PoolerSafe() option and Supabase transaction pool detection in migrateSettings build directly on the provider/pool-mode plumbing introduced in NES-46.

Possibly related PRs

  • ericfisherdev/nestova#11: Introduces the original cmd/migrate CLI and migrate.Up/Down/Status/Reset with sql.Open("pgx", dsn) — the exact entrypoints this PR extends with variadic options and migrateSettings.
  • ericfisherdev/nestova#64: Adds DB_PROVIDER and DB_POOL_MODE to DBConfig, which migrateSettings in this PR reads to conditionally enable PoolerSafe() for Supabase transaction pool mode.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.19% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly references the feature (Supabase migrations and session store over pooler) and correctly summarizes the main change to enable Supabase compatibility.
Linked Issues check ✅ Passed All NES-47 objectives are met: MIGRATE_DATABASE_URL added with fallback logic; cmd/migrate resolves DSN and applies pooler-safe options intelligently; PoolerSafe() option with simple query protocol implemented; pgxstore confirmed working via DB-gated test; comprehensive unit and integration tests included; README documented.
Out of Scope Changes check ✅ Passed All changes directly support NES-47 and NES-46 objectives: config, migration runner, CLI logic, tests, and documentation all address Supabase pooler compatibility with no unrelated modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@ericfisherdev
ericfisherdev marked this pull request as ready for review June 21, 2026 19:34
@ericfisherdev

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 137-146: The MIGRATE_DATABASE_URL configuration variable is
documented in the migration section but is missing from the configuration table
at lines 41-52. Add a new row to the configuration table after the DATABASE_URL
entry that documents MIGRATE_DATABASE_URL as an optional variable that defaults
to DATABASE_URL if not set, and include a brief description explaining its
purpose for running migrations against a different database connection (useful
for Supabase with session connections).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ab6fbd97-59e0-420b-82f6-6e6c804595d0

📥 Commits

Reviewing files that changed from the base of the PR and between 2697b0a and dae1ea6.

📒 Files selected for processing (8)
  • README.md
  • cmd/migrate/main.go
  • cmd/migrate/main_test.go
  • internal/auth/adapter/session_pooler_test.go
  • internal/platform/config/config.go
  • internal/platform/config/config_test.go
  • internal/platform/db/migrate/migrate.go
  • internal/platform/db/migrate/migrate_test.go

Comment thread README.md
@ericfisherdev
ericfisherdev merged commit 7beb837 into main Jun 21, 2026
1 check passed
@ericfisherdev
ericfisherdev deleted the nes-47-supabase-migrations branch June 21, 2026 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant