Skip to main content

Local setup

From clone to http://localhost:3000 in ~10 minutes.

Prerequisites

  • Docker Desktop (for the local Supabase stack)
  • Node 22required, not just >=20. The engines field is loose, but Node 24+ breaks at startup with Cannot read properties of undefined (reading 'prototype') from buffer-equal-constant-time (it accesses SlowBuffer.prototype, removed in Node 24). Install via brew install fnm && fnm install 22 && fnm use 22 and add eval "$(fnm env --shell zsh)" to ~/.zshrc.
  • Homebrew (macOS) for installing fnm and gh if you don't already have them.

Verify:

node -v # expect v22.x
docker --version

First-time setup

git clone git@github.com:aimabel/Platform.git
cd Platform

# 1. Storage bucket dir must exist before supabase start (config.toml references it)
mkdir -p supabase/storage/list-uploads

# 2. Local Supabase stack (Postgres, Studio, Mailpit, etc.)
npx supabase start

# 3. Env file
cp .env.example .env
# Paste anon and service_role keys from the previous command's output, or run:
npx supabase status -o env
# Copy ANON_KEY → SUPABASE_ANON_KEY and SERVICE_ROLE_KEY → SUPABASE_SERVICE_ROLE_KEY in .env

# 4. Dependencies
npm install

# 5. Apply all migrations + seeds
npm run reset

# 6. Run the dev server
npm run dev

The app is now at http://localhost:3000.

WhatWhere
Apphttp://localhost:3000
Supabase Studiohttp://localhost:54323/project/default/editor
Mailpit (email inbox)http://localhost:54324/monitor
Postgrespostgresql://postgres:postgres@127.0.0.1:54322/postgres

Login

The seed creates three users with the same password:

EmailPassword
henric@aimabel.aihenricmalmberg
dev@aimabel.ai(see supabase/seed/main.sql)
tom@aimabel.ai(see supabase/seed/main.sql)

To get super-admin access on your dev user, set account_user.account_role = 'super_admin' on the row where user_id = account_id (the personal account).

Common gotchas

  • open supabase/storage/list-uploads: no such file or directory — the bucket source dir isn't checked in. Run mkdir -p supabase/storage/list-uploads. npm run init does this for you.
  • Port 54321 in use — another repo is running Supabase. Stop it (npx supabase stop from that project, or docker ps --format '{{.Names}}' | grep '_<other-id>$' | xargs docker stop).
  • Cannot read properties of undefined (reading 'prototype') — you're on Node 24+. Switch to Node 22 (see Prerequisites).
  • RLS violation on a new table you added — every new public table needs ALTER TABLE … ENABLE ROW LEVEL SECURITY and an access policy. See architecture.md.

Useful commands

npm run dev # vite dev server
npm run reset # drop + re-apply all migrations + seed
npm run test # run supabase/tests/database/*.sql
npm run gentypes # regen app/types/supabase/index.d.ts
npm run gendocs # regen docs/schema/*.md
npm run migr <name> # create a new migration file
npm run precommit # full workflow: fix → reset → test → gentypes → gendocs → fix → build
npm run scaffold-esrs # list ESRS disclosures
npm run scaffold-esrs S2-2 # generate seed for a specific disclosure