Skip to content

v1.16.0 - #159

Merged
pataniaeli merged 13 commits into
mainfrom
dev
Sep 19, 2026
Merged

pataniaeli merged 13 commits into
mainfrom
dev

Conversation

@pataniaeli

Copy link
Copy Markdown
Collaborator

Releases #143: Chambers' database and login move from Supabase to Neon. See #143 for the full description.

  • Neon production (ep-polished-dew) was loaded at 19:07 UTC today. Every row count matches, and all 37 logins keep their passwords.
  • Production's Data API passes all 11 checks with the production key, and refuses the test key.
  • The Vercel production variables are set.
  • The deploy signs everyone out once. Passwords are unchanged.

🤖 Generated with Claude Code

pataniaeli and others added 12 commits September 17, 2026 11:42
- db/neon/0001_baseline.sql: production public schema from the live catalog,
  FKs to auth.users repointed at public.users, no RLS policies or Supabase
  helper functions, RLS left enabled as default deny.
- db/neon/0002_better_auth.sql: Better Auth mapped onto public.users, plus
  auth_sessions, auth_accounts and auth_verifications.
- scripts/neon/copy-data.mjs: copies every table in FK order in one
  transaction, imports Supabase logins with their bcrypt hashes, verifies
  row counts.
- lib/better-auth.ts, lib/auth-client.ts, lib/auth-admin.ts and
  /api/auth/[...all]: Better Auth with bcrypt passwords, sign-up disabled,
  password reset through Resend, deactivated users refused a session.
- lib/auth.ts, lib/authorization.ts, lib/shell-identity.ts read the Better
  Auth session and the users row through a pg pool.
- Client pages read roles from the shell identity instead of token metadata.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Login flows now run on Better Auth: sign-in, password reset (through
Resend), the signup code, onboarding, admin invites and resends,
deactivation and session revocation. The browser no longer queries the
database -- the login and onboarding pages ask three new API routes
instead -- and roles are read from the users row rather than copied into a
token.

Sessions last two days of inactivity, extended at most hourly while in
use, matching the dashboard's existing idle sign-out.

Row-level security is no longer part of access control (decided on #136).
Supabase cannot identify a Better Auth user, so the server clients use the
service role, and every route relies on the checks it already made in
application code before querying. The Neon schema keeps RLS enabled with
no policies, so anything other than the app's own role is denied by
default.

Also: proxy.ts and the browser Supabase client are gone, AuthedUser moved
to lib/auth-types.ts so browser-shared modules do not import server code,
the warm cron warms the Postgres pool, and .env.example documents
DATABASE_URL, BETTER_AUTH_SECRET and BETTER_AUTH_URL.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…y-schema script (#136)

The login import passed one parameter as both the uuid user_id and the text
account_id, which Postgres refuses. apply-schema.mjs applies db/neon/*.sql
to an empty database in one transaction.

Rehearsed against the new Neon project: schema applied (34 tables), dry run
and real copy both passed with every row count matching and 37 logins
imported.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…136)

The Data API switches to the Postgres role named in the request token. The
server will sign short-lived tokens as chambers_server with a private key
only it holds; public/data-api-jwks.json is the matching public key for
Neon to verify them. chambers_server gets full access to the app tables
through one permissive policy each, and none to the auth_* tables.

Adds jose and @supabase/postgrest-js as direct dependencies.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…#136)

Rehearsed on a Neon branch: nested selects, a nested-table filter, aliased
FK embeds, .or(), head counts, single(), and a restored write all work
through the Data API with a server-signed chambers_server token. Requests
with no token or an ordinary authenticated token get nothing, and the
auth_* tables stay closed.

after-data-api.sql grants chambers_server to authenticator, which only
exists once the Data API is enabled. The runbook now covers enabling it,
registering the key, and refreshing the schema cache, which Neon does not do
on its own after DDL.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… app (#136)

Every Supabase client -- the 54 service-role admin clients, the 53 routes
using lib/supabase/server, the homepage's anon client and the FAQ page --
is now lib/db/data-api.ts: a PostgREST client pointed at the Neon Data API
that signs its own ten-minute chambers_server token per request. The
queries themselves are unchanged; the Data API speaks the same protocol.

@supabase/supabase-js and @supabase/ssr are uninstalled, lib/supabase and
the realtime-js stub (and its bundler alias) are deleted. next.config gains
an empty turbopack block, which Next 16 requires beside next-pwa's webpack
config once no other turbopack option is set.

Checked: typecheck, production build (whose prerender queries Neon), and
the homepage and FAQ reading live data from the rehearsal branch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… a database (#136)

- scripts/neon/cutover.mjs loads a Neon branch from Supabase in one command:
  refuses unless --target-endpoint matches the URL and the Data API is
  enabled, drops existing tables only with --reset-target, then applies the
  schema, copies data and logins, and grants the Data API role. --check
  reports the plan without writing.
- scripts/neon/compare-counts.mjs, run after the deploy, lists tables with
  rows Supabase gained after the copy.
- public/data-api-jwks-production.json holds only the production key, so
  production's Data API never trusts the dev and rehearsal key.
- The database client reports a missing NEON_DATA_API_URL as a query error
  instead of throwing on first use, the FAQ falls back to role titles, and
  Better Auth gets a placeholder secret during next build only. Together
  these let CI build with no database or auth configuration; CI no longer
  passes the Supabase secrets.
- Runbook and .env.example updated for the Data API and the Sept 19 cutover.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Brings in #126 meeting time, #127 series space change, #120 audit detail,
#139 dismissable cancellations, #142 and #147. The tabling route's
admin client and the new lib/audit.ts type now use the Neon Data API
client like everything else.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
)

scripts/neon/generate-baseline.mjs rebuilds db/neon/0001_baseline.sql from
Supabase's live catalog, read-only, with the same rules as the hand-built
version: auth.users foreign keys repointed at public.users, no policies or
Supabase helper functions, RLS enabled as default deny.

Regenerated today to pick up the migrations that reached production since
Sept 17: audit_logs target/target_date/action/changes and their checks,
the Dismissed cancellation status, and audit_logs_booking_created_idx.
Nothing else differs from the previous hand-built file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@pataniaeli pataniaeli added the enhancement New feature or request label Sep 19, 2026
@vercel

vercel Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated
chambers Ready Ready Preview Sep 19, 2026 7:10pm UTC

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@pataniaeli pataniaeli changed the title Move Chambers to Neon (#136) v1.16.0 Sep 19, 2026
@pataniaeli
pataniaeli merged commit dfe5d69 into main Sep 19, 2026
5 checks passed
@pataniaeli pataniaeli added the massive Beyond a normal issue size label Sep 19, 2026
@pataniaeli pataniaeli self-assigned this Sep 19, 2026
@pataniaeli pataniaeli linked an issue Sep 19, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request massive Beyond a normal issue size

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate Chambers to Neon

1 participant