Skip to content

fix: unblock CMS deploy and lock down member access - #206

Merged
joengy merged 4 commits into
mainfrom
fix/backend-deploy
Oct 12, 2026
Merged

joengy merged 4 commits into
mainfrom
fix/backend-deploy

Conversation

@joengy

@joengy joengy commented Oct 11, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Gets the backend (Payload CMS) deployable and closes some access gaps found along the way.

Why prod CMS hangs: someone ran pnpm dev against the prod DB, so payload_migrations has a dev row. prodMigrations then waits on an interactive "data loss?" prompt, and every /admin and /api/* request hangs. This PR stops that from happening again. A one-off DB cleanup (below) fixes the current state.

  • Disable dev schema push (push: false). Schema changes must go through pnpm migrate:create.
  • Users access rules. Before this, any signed-in member could PATCH their own role to admin and read every user. Now:
    • create/delete are admin-only
    • read/update are admin or the user themselves
    • only admins can change role, membershipStatus and membershipExpiryDate
  • Event registration
    • New migration 20261011_000001_members_only_events:
      • makes event_registrations.phone nullable. Since fix/event-rsvp-membership #202 registrations don't send a phone number, so every insert was failing.
      • drops priceType and events.non_member_price
      • uses IF EXISTS guards because prod's schema has drifted
    • Registering now requires an active membership. Pending (unpaid) and expired members get a 403.
    • The RSVP page warns non-active members up front, and event prices read "$X · Members only" or "Free · Members only".
  • Signup price comes from Stripe. New GET /stripe/checkout returns the STRIPE_PRICE_ID amount, replacing the hardcoded PAY $6. /signup now renders per request because the CMS isn't reachable during the Docker build.

Testing

Everything ran against a throwaway local Postgres, not prod:

  • All migrations apply, roll back and re-apply cleanly. migrate:create --skip-empty finds no schema drift.
  • CMS and web production builds, typecheck and lint all pass. New tests/int/users.int.spec.ts passes.
  • Ran the built CMS and called the real endpoints:
    • /admin, /api/sponsors, /api/globals/site-settings and /stripe/checkout all return 200.
    • A member's PATCH setting their own role: admin is ignored.
    • Anonymous create, patching another user and self-delete all return 403.
    • A pending member gets a 403 on registration. An active member registers successfully with a null phone.

Before deploying

The prod DB needs a one-off cleanup or the hang continues:

  • delete the dev row and the stale 20260526_190419 row from payload_migrations
  • mark baseline, event_rsvps, 20260929_000001_sponsors_category and 20261008_205511 as applied, after checking the schema matches

The new migration then runs automatically on deploy. Separately, GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET are still missing on Vercel.

Type of change

  • Feature
  • Bug fix
  • Chore / config
  • Hotfix

Checklist

  • My branch follows the naming convention (feature/, fix/, chore/, hotfix/)
  • My commit messages follow the conventional commits format
  • CI checks pass

Linked Issues

Related to #198, #202

A dev run with push enabled writes a 'dev' row to payload_migrations,
which makes prodMigrations block on an interactive prompt and hangs
every request in production. Schema changes go through migrations.
Create/delete are admin-only, read/update admin-or-self, and members
can no longer change role, membershipStatus or membershipExpiryDate.
Previously any signed-in member could promote themselves to admin.
- Migration makes event_registrations.phone nullable (registrations no
  longer send it, so every insert failed) and drops priceType and
  events.non_member_price, guarded with IF EXISTS for prod's drift
- Registration requires an active membership
- RSVP page warns non-active members; prices read 'Members only'
Adds GET /stripe/checkout returning the STRIPE_PRICE_ID amount and
renders it on the payment step instead of a hardcoded $6.
@vercel

vercel Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
ssa Ready Ready Preview Oct 11, 2026 7:42am UTC

@henryhlly henryhlly left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

lgtm

@joengy
joengy merged commit 54940cc into main Oct 12, 2026
7 checks passed

This branch was successfully deployed

1 active deployment
Preview — 7d0364c6 Deployed Oct 11, 2026 by vercel[bot]
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.

2 participants