Mobile-first event platform scaffold: Next.js (App Router) + Supabase + n8n hooks.
- Node 18+
- Docker Desktop (for local Supabase)
- Supabase CLI (
npx supabaseworks)
Copy .env.example to .env.local and fill in keys from local Supabase (supabase start prints API URL and anon/service keys).
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Supabase API URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Browser + server user-scoped client |
SUPABASE_SERVICE_ROLE_KEY |
Server-only admin client (auth admin API, onboard callback inserts) |
N8N_BASE_URL |
Base URL for outbound webhooks (ngrok in dev) |
N8N_SHARED_SECRET |
Shared HMAC secret (Next.js ↔ n8n) |
npx supabase start
npm run db:reset # migrations + seed.sqlYour Next app connects to whichever project URLs/keys live in .env.local. After pulling new migrations, apply them to that remote project — otherwise features that depend on new tables/policies (e.g. campus map locations, campus-map bucket) will 400 against PostgREST.
Option A — CLI (supabase v2+, PAT-only link)
- Create an access token (starts with
sbp_). - Put it in
.env.local:SUPABASE_ACCESS_TOKEN=sbp_... # optional if your project ref differs from the default UniPulse staging ref: # SUPABASE_PROJECT_REF=your_twenty_char_ref - From the repo root:
This runs
npm run db:push:cloud
supabase link, executesscripts/ensure-grid-for-seed.sql(setsgrid_nto at least 10 so campus seed pins in migration20250518120000succeed), thensupabase db push.
Option B — SQL Editor
If you prefer the dashboard: paste and run supabase/cloud_apply_bundle.sql once (it includes DELETE FROM public.events; registration rows CASCADE). Afterwards, when you switch back to the CLI on that project, reconcile migration history (supabase migration repair, etc.) so db push doesn’t attempt to replay the same SQL.
Smoke-test after either option: restart npm run dev and hit GET /api/locations — should return 200 JSON, not PostgREST PGRST205.
Default seed admin (login only; never via signup UI):
- Email:
admin@unipulse.local - Password:
ChangeMe_SeedAdmin123(matchsupabase/seed.sqland.env.example)
After schema changes, regenerate types (optional; repo includes hand-maintained types):
npm run gen:types- Students: University ID + password → synthetic email
<normalized-id>@students.unipulse.localvialib/auth/student-email.ts. Approved immediately. - Organizers: Real email + password;
account_status = pendinguntil an admin approves. - Admins: Created only via seed/SQL; use email + password on
/login. - Guests: No profile; can browse public events and call open-event upvote RPC.
RLS + API guards enforce approved organizers for event mutations and students for registrations / merch RPCs.
| Area | Route |
|---|---|
| Auth | POST /api/auth/signup/student, POST /api/auth/signup/organizer, POST /api/auth/login/student, POST /api/auth/login, POST /api/auth/logout |
| Events | GET/POST /api/events, GET/PATCH/DELETE /api/events/[id] |
| Campus map | GET /api/locations |
| Engagement | PATCH /api/events/[id]/upvote, POST /api/events/[id]/register, GET /api/events/[id]/ics (+ ?format=google) |
| Merch (V1 mock) | POST /api/events/[id]/merch/purchase, POST /api/events/[id]/merch/export-manifest |
| Onboarding | POST /api/onboard (multipart file → Storage → n8n), POST /api/onboard/callback (HMAC JSON → draft event) |
| Admin | GET /api/admin/organizers/pending, POST .../approve, POST .../reject, GET/PATCH /api/admin/config, POST /api/admin/locations, PATCH /api/admin/locations/[id], DELETE /api/admin/locations/[id], POST/DELETE /api/admin/map/background |
Outbound helpers live in lib/n8n.ts. Expected paths under N8N_BASE_URL:
/webhook/proposal-uploaded/webhook/organizer-approved/webhook/event-published/webhook/merch-manifest-export
Calls are non-throwing (slow tunnels must not break the UI). Inbound callbacks must send header X-N8N-Signature (hex HMAC-SHA256 of raw body with N8N_SHARED_SECRET). See lib/auth/hmac.ts.
Local tunnel example: ngrok http 5678 → paste HTTPS origin into N8N_BASE_URL.
Plain pages under app/ exercise the APIs before your designer UI lands. Look for SCAFFOLD comments.
- Stripe for merch + pinned promos
- Facebook Graph publishing from social caption staging
- Behavioral interest tagging
- Automated PDF certificates / feedback workflow depth
- Rich gallery / community timeline
(See spec § Version 2.0.)
npm run dev— Next.js dev servernpm run build— production buildnpm run lint— ESLintnpm run db:push:cloud—supabase link+db pushfor hosted DB (needsSUPABASE_ACCESS_TOKEN=sbp_...in.env.local)