Skip to content

Commit 7ed3f4e

Browse files
committed
adopt local-first supabase workflow
1 parent bca4993 commit 7ed3f4e

25 files changed

Lines changed: 2039 additions & 79 deletions

.env.example

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
# Production: https://www.peels.app
44
NEXT_PUBLIC_SITE_URL=http://localhost:3000
55

6-
# Get these from your Supabase project settings
7-
# For contributors: Request access to the development database from maintainers
8-
# For forking: Create your own project at https://database.new
9-
NEXT_PUBLIC_SUPABASE_URL=
6+
# Local-first Supabase workflow:
7+
# 1. Run `npm run supabase:start`
8+
# 2. Copy the values from `npm run supabase:env`
9+
# 3. Paste NEXT_PUBLIC_SUPABASE_ANON_KEY below
10+
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54331
1011
NEXT_PUBLIC_SUPABASE_ANON_KEY=
1112

1213
# For contributors: Either follow the below forking instructions or ask the project maintainers for the shared development key
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Validate Supabase
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- "supabase/**"
7+
push:
8+
branches:
9+
- main
10+
paths:
11+
- "supabase/**"
12+
13+
jobs:
14+
replay:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Check out repository
19+
uses: actions/checkout@v4
20+
21+
- name: Set up Supabase CLI
22+
uses: supabase/setup-cli@v1
23+
with:
24+
version: latest
25+
26+
- name: Start local Supabase stack
27+
run: supabase start
28+
29+
- name: Replay migrations and seed data
30+
run: supabase db reset

README.md

Lines changed: 110 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@ npm run dev
3131

3232
### Core Requirements
3333

34-
| Requirement | Version |
35-
| ----------- | --------------------- |
36-
| Node.js | 18+ (LTS recommended) |
37-
| npm/yarn | Latest stable |
38-
| Git | Latest stable |
34+
| Requirement | Version |
35+
| ------------ | --------------------- |
36+
| Node.js | 18+ (LTS recommended) |
37+
| npm/yarn | Latest stable |
38+
| Git | Latest stable |
39+
| Docker | Latest stable |
40+
| Supabase CLI | Latest stable |
3941

40-
Deno and Docker are also required if you plan to work on Supabase edge functions.
42+
Deno is also required if you plan to work on Supabase edge functions.
4143

4244
### Required Services
4345

@@ -73,11 +75,22 @@ For minor improvements, feel free to just go ahead and create a pull request. Fo
7375

7476
### Environment Variables
7577

76-
Personal keys for [MapTiler](https://www.maptiler.com/cloud/) and [Protomaps](https://protomaps.com/account) will work just fine for local development. You’ll probably need the shared development keys for Supabase, so please introduce yourself and tell us how you plan to help on the [discussion board](https://github.com/dnywh/peels/discussions). We’ll go from there.
78+
Personal keys for [MapTiler](https://www.maptiler.com/cloud/) and [Protomaps](https://protomaps.com/account) will work just fine for local development.
7779

78-
> **Note**: We’re exploring ways to make local development work without a shared development key for Supabase, probably by [seeding example data](https://supabase.com/docs/guides/local-development/seeding-your-database) and doing something similar for authentication. We’d love your help with this.
80+
For local-first Supabase development:
7981

80-
Environmental variables can also be optionally added to [Supabase edge functions](https://github.com/dnywh/peels/blob/main/supabase/functions) for local testing. You’re unlikely to need these though, as each edge function currently requires user information and interaction.
82+
1. Copy `.env.example` to `.env.local`
83+
2. Run `npm run supabase:start`
84+
3. Run `npm run supabase:env`
85+
4. Make sure `.env.local` contains the local URL `NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54331`
86+
5. Copy the local `ANON_KEY` value into `NEXT_PUBLIC_SUPABASE_ANON_KEY` in `.env.local`
87+
88+
The repo defaults `NEXT_PUBLIC_SUPABASE_URL` to `http://127.0.0.1:54331` so local development does not need to point at the hosted Peels project. If you already had a `.env.local` from hosted development, update that value manually because copying `.env.example` later may not overwrite your existing file.
89+
Peels intentionally uses the `54331`-`54334` local port range so it can run alongside other Supabase projects that still use the CLI defaults.
90+
91+
If you need to serve [Supabase edge functions](https://github.com/dnywh/peels/blob/main/supabase/functions) locally, copy `supabase/.env.example` to `supabase/.env` and add only the secrets you actually need. Production secrets should remain dashboard-managed for now.
92+
93+
For the fuller operational walkthrough, including GitHub/Vercel dashboard setup and fresh-computer bootstrap, see [docs/supabase-local-first.md](./docs/supabase-local-first.md).
8194

8295
### Usage
8396

@@ -91,14 +104,99 @@ Environmental variables can also be optionally added to [Supabase edge functions
91104

92105
2. Populate environment variables:
93106
- Copy `.env.example` to `.env.local`
94-
- Request development credentials via our [discussions board](https://github.com/dnywh/peels/discussions)
107+
- Start local Supabase with `npm run supabase:start`
108+
- Run `npm run supabase:env`
109+
- Confirm `.env.local` uses `NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54331`
110+
- Copy the local `ANON_KEY` into `NEXT_PUBLIC_SUPABASE_ANON_KEY`
95111

96112
3. Start development:
97113

98114
```bash
115+
npm run supabase:start
99116
npm run dev
100117
```
101118

119+
### Supabase Local-First Workflow
120+
121+
Use the Supabase CLI as the default path for schema work:
122+
123+
```bash
124+
# Start the local backend
125+
npm run supabase:start
126+
127+
# See local connection details
128+
npm run supabase:env
129+
130+
# Rebuild the local database from migrations + seed
131+
npm run supabase:reset
132+
```
133+
134+
For day-to-day development:
135+
136+
1. Make schema or policy changes locally
137+
2. Capture them in SQL migrations under `supabase/migrations/`
138+
3. Replay everything with `npm run supabase:reset`
139+
4. Smoke-test the app with `npm run dev`
140+
5. Commit code and migration files together
141+
142+
Use local Studio, `psql`, or the hosted Supabase dashboard for browsing rows and running ad hoc queries. Use the CLI for schema lifecycle, not as the main data browser.
143+
144+
### Supabase Buckets and Seed Data
145+
146+
- Bucket configuration lives in `supabase/config.toml`
147+
- Local reset data lives in `supabase/seed.sql`
148+
- Local placeholder static assets live in `supabase/storage/static/`
149+
150+
Keep all local and preview data sanitized. Do not export or commit production data.
151+
152+
### One-Time Production Bootstrap for Maintainers
153+
154+
Peels already had schema history in the hosted project before migrations were committed to Git. If you need to re-bootstrap the repo from production, use this order:
155+
156+
```bash
157+
supabase login
158+
supabase link --project-ref mfnaqdyunuafbwukbbyr
159+
supabase migration fetch
160+
supabase db dump --schema public --file supabase/migrations/20251026060000_baseline_schema.sql
161+
supabase migration repair 20251026060000 --status applied --linked
162+
```
163+
164+
The important bit is that the baseline migration must exist in Git before the first fetched remote migration, and the hosted project must be marked as already having that baseline. That keeps local resets reproducible without asking production to replay the whole schema.
165+
166+
If you have custom `auth` or `storage` schema objects beyond the defaults, audit and pull those explicitly after the public baseline:
167+
168+
```bash
169+
supabase db pull auth_schema --schema auth
170+
supabase db pull storage_schema --schema storage
171+
```
172+
173+
Do not use the Supabase dashboard for routine schema changes once a migration exists in Git. If an emergency dashboard hotfix is unavoidable, pull it back into the repo immediately before making the next change.
174+
175+
### Supabase Branching
176+
177+
One-time manual setup in Supabase/GitHub should be:
178+
179+
1. Enable the Supabase GitHub integration for this repo
180+
2. Set the scope to `supabase/**`
181+
3. Turn on `Automatic branching`
182+
4. Turn on `Supabase changes only`
183+
5. Keep `main` as the production branch
184+
6. Require the `Supabase Preview` check before merge
185+
186+
The repo also includes a GitHub Actions workflow that replays the local Supabase setup on PRs touching `supabase/**`.
187+
188+
If Peels preview deployments run on Vercel, make sure the preview environment uses the branch-specific `NEXT_PUBLIC_SUPABASE_URL` and `NEXT_PUBLIC_SUPABASE_ANON_KEY` values that Supabase provides for each preview branch instead of production credentials.
189+
190+
### Outside-the-Repo Setup
191+
192+
Some setup still lives in web dashboards because Git cannot store everything:
193+
194+
1. In the Supabase dashboard, connect the GitHub repo and turn on preview branches for changes under `supabase/**`
195+
2. In GitHub branch protection, require the `Supabase Preview` check before merge
196+
3. In Vercel project settings, set preview environment variables to the Supabase branch credentials instead of the production project credentials
197+
198+
In plain English: the repo now tells Supabase and the app how to behave, but Supabase, GitHub, and Vercel still each need one “please use preview mode for PRs” switch turned on in their own settings pages.
199+
102200
You might need to clear out and restart your Next.js development server in the case that you add environment variables after the above steps. Here’s how to do that:
103201

104202
```bash
@@ -151,7 +249,8 @@ Check out the [Next.js and Supabase Starter Kit](https://github.com/supabase/sup
151249
3. Initialize and run:
152250

153251
```bash
154-
npx supabase db push
252+
npm run supabase:start
253+
npm run supabase:reset
155254
npm run dev
156255
```
157256

docs/supabase-local-first.md

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
# Supabase Local-First Guide
2+
3+
This is the operational guide for running Peels with the Supabase CLI, preview branches, and local mock data.
4+
5+
## What Lives Where
6+
7+
- Git repo: schema migrations, local bucket config, local seed data, and app code
8+
- Supabase dashboard: GitHub integration, preview branches, and hosted project settings
9+
- GitHub settings: required PR checks on `main`
10+
- Vercel settings: preview environment variables
11+
12+
If you remember one thing, make it this: we now treat `supabase/` in Git as the source of truth for schema work, but a few platform toggles still have to be enabled once in Supabase, GitHub, and Vercel.
13+
14+
## One-Time Dashboard Setup
15+
16+
### 1. Connect Supabase to GitHub
17+
18+
Official reference: [Supabase GitHub integration docs](https://supabase.com/docs/guides/deployment/branching/github-integration)
19+
20+
1. Open the Peels project in the Supabase dashboard.
21+
2. Go to `Project Settings` -> `Integrations`.
22+
3. Under `GitHub Integration`, click `Authorize GitHub`.
23+
4. Complete the GitHub authorisation flow and return to Supabase.
24+
5. Choose the Peels GitHub repository.
25+
6. Set the Supabase directory path to `supabase`.
26+
7. Turn on `Automatic branching`.
27+
8. Turn on `Supabase changes only`.
28+
9. Leave `main` as the production branch.
29+
10. Do not turn on `Deploy to production` until you are happy with preview-branch behaviour.
30+
11. Save or enable the integration.
31+
32+
What this does:
33+
34+
- A PR branch that changes `supabase/**` gets its own Supabase preview branch.
35+
- That preview branch runs migrations and bucket config from Git.
36+
- Seed data comes from `supabase/seed.sql`, not from production data.
37+
38+
### 2. Require the Supabase PR Check in GitHub
39+
40+
Official reference: [GitHub branch protection docs](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule)
41+
42+
1. Open the Peels GitHub repository.
43+
2. Go to `Settings` -> `Branches`.
44+
3. Edit the existing rule for `main`, or create one if there is not already a rule.
45+
4. Turn on `Require status checks to pass before merging`.
46+
5. In the check list, select `Supabase Preview` once it has appeared at least once on a PR.
47+
6. Keep `Require branches to be up to date before merging` on if you want stricter protection.
48+
7. Save the branch rule.
49+
50+
What this does:
51+
52+
- GitHub will block merging a PR into `main` if Supabase could not build the preview branch cleanly.
53+
54+
### 3. Point Vercel Preview Deployments at Preview Supabase Branches
55+
56+
Official reference: [Vercel environment variable docs](https://vercel.com/docs/environment-variables/manage-across-environments)
57+
58+
1. Open the Peels project in Vercel.
59+
2. Go to `Settings` -> `Environment Variables`.
60+
3. Check what is currently set for:
61+
- `NEXT_PUBLIC_SUPABASE_URL`
62+
- `NEXT_PUBLIC_SUPABASE_ANON_KEY`
63+
4. Keep the production values for the `Production` environment.
64+
5. Set `Preview` values so preview deployments use the Supabase branch credentials instead of production credentials.
65+
6. If you want branch-specific overrides, add them for the matching Git branch in Vercel.
66+
7. Redeploy a preview deployment after changing the variables.
67+
68+
What this does:
69+
70+
- Your preview frontend talks to the preview Supabase branch instead of the live Peels database.
71+
72+
## Local Development on Your Current Computer
73+
74+
### Start from scratch
75+
76+
```bash
77+
npm install
78+
cp .env.example .env.local
79+
npm run supabase:start
80+
npm run supabase:reset
81+
npm run supabase:env
82+
```
83+
84+
Then make sure `.env.local` has:
85+
86+
```bash
87+
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54331
88+
NEXT_PUBLIC_SUPABASE_ANON_KEY=<paste the ANON_KEY value here>
89+
```
90+
91+
Do not mix the hosted project URL with the local anon key. That combination fails with `Invalid API key`.
92+
93+
Finally:
94+
95+
```bash
96+
npm run dev
97+
```
98+
99+
### Local URLs
100+
101+
- App: `http://127.0.0.1:3000`
102+
- Supabase API: `http://127.0.0.1:54331`
103+
- Supabase Studio: `http://127.0.0.1:54333`
104+
- Mailpit: `http://127.0.0.1:54334`
105+
106+
Peels intentionally uses the `54331`-`54334` range so you can run it alongside other Supabase projects that still use the default local ports.
107+
108+
### Demo accounts
109+
110+
Both local demo accounts use the password `peels-demo-password`.
111+
112+
- Host account: `demo-host@peels.local`
113+
- Donor account: `demo-donor@peels.local`
114+
115+
The seed also creates:
116+
117+
- 3 public listings
118+
- 1 chat thread
119+
- 2 chat messages
120+
- a sample static bucket object at `static/promo-kit.zip`
121+
122+
The demo data is synthetic and safe to keep in Git.
123+
124+
## Fresh Computer Setup
125+
126+
Use this when setting up Peels on a new machine.
127+
128+
### Prerequisites
129+
130+
- Node.js
131+
- npm
132+
- Docker Desktop
133+
- Supabase CLI
134+
135+
### Steps
136+
137+
1. Clone the repo.
138+
2. Run `npm install`.
139+
3. Copy `.env.example` to `.env.local`.
140+
4. Run `npm run supabase:start`.
141+
5. Run `npm run supabase:reset`.
142+
6. Run `npm run supabase:env`.
143+
7. Set `NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54331` in `.env.local`.
144+
8. Copy the printed `ANON_KEY` into `NEXT_PUBLIC_SUPABASE_ANON_KEY` in `.env.local`.
145+
9. Run `npm run dev`.
146+
10. Sign in with one of the demo accounts above.
147+
148+
If the app still shows old environment values, clear the build cache and restart:
149+
150+
```bash
151+
rm -rf .next
152+
npm run dev
153+
```
154+
155+
## Daily Workflow
156+
157+
1. Start local Supabase with `npm run supabase:start`.
158+
2. Make schema changes locally.
159+
3. Add or edit SQL migrations under `supabase/migrations/`.
160+
4. Rebuild from scratch with `npm run supabase:reset`.
161+
5. Run `npm run dev`.
162+
6. Test the flow locally.
163+
7. Commit app and migration changes together.
164+
165+
Use local Studio, `psql`, or the hosted dashboard for browsing rows. Use the CLI for schema lifecycle.
166+
167+
## How to Merge the Current Rollout Changes
168+
169+
Right now the changes are only in your working tree on `main`. The safe path is:
170+
171+
1. Create a feature branch from the current state.
172+
2. Stage only the Supabase local-first rollout files.
173+
3. Commit them together.
174+
4. Push the feature branch.
175+
5. Open a PR into `main`.
176+
6. Enable the required `Supabase Preview` check once it appears on the PR.
177+
178+
Suggested branch name:
179+
180+
```bash
181+
git switch -c dnywh/supabase-local-first
182+
```
183+
184+
Then review what is staged before committing:
185+
186+
```bash
187+
git status
188+
git diff --cached
189+
```
190+
191+
This keeps `main` clean and makes the rollout easy to review.

0 commit comments

Comments
 (0)