Prerequisites
Use the repository’s pnpm version (packageManager in the root manifest), a supported Node runtime (CI uses Node 24), Git and a local Postgres installation for integration tests. Native development additionally needs the platform toolchain and a compatible Expo development client.
Configure and start
pnpm 11 has built-in setup and doctor commands, so the repository's scripts need pnpm run. AutoFolio runs locally for now (ADR-0014): a local database, no deploys and no CI.
pnpm install --frozen-lockfile
pnpm run setup # identity, env files, auth secret
pnpm run doctorFor an existing clone, preserve its identity and credentials and repair only missing configuration. Point DATABASE_URL at a local PostgreSQL and set FIELD_ENCRYPTION_KEY (32 bytes, base64) so plates and VINs can be saved. Then apply the migrations and start the web with the demo garage:
pnpm run db:migrate
DEV_SEED_LOGIN=true pnpm dev:web # http://localhost:3005DEV_SEED_LOGIN mounts the dev-only seed sign-in (environments), which loads handoff/data/seed.json into one demo account per language.
Mobile dev client
EXPO_PUBLIC_SERVER_URL=http://127.0.0.1:3005 pnpm dev:mobile
pnpm --filter mobile ios # or android; builds and installs the dev clientUse the development build, not Expo Go. Open any board signed into the demo garage with autofolio://dev/<board>?lang=pt-BR|en-US|de-DE, for example:
xcrun simctl openurl booted "autofolio://dev/M-Garagem?lang=de-DE"Mobile app covers the dev link in detail.
End-to-end flows
node scripts/maestro.mjs F1 # Maestro flows F1–F5 and F7 from handoff/e2e/maestro, run against the dev client
npx playwright test # F6, the buyer passport at /p/demo-token; needs DEV_SEED_LOGIN=trueLocal PostgreSQL
Any PostgreSQL 16 or newer works; Neon is only one host. To develop without a hosted database, run one in Docker (or Homebrew) and connect as a table owner that can create roles:
docker run -d --name template-postgres -e POSTGRES_PASSWORD=postgres -p 127.0.0.1:5432:5432 postgres:17
docker exec template-postgres psql -U postgres \
-c "CREATE ROLE template_owner LOGIN CREATEROLE CREATEDB PASSWORD 'template'" \
-c "CREATE DATABASE template_dev OWNER template_owner"Set DATABASE_URL=postgresql://template_owner:template@127.0.0.1:5432/template_dev in apps/web/.env (and .dev.vars for wrangler dev), then pnpm db:migrate. Put it in the env file rather than the shell: pnpm run dev goes through Turbo, which does not pass undeclared shell variables to the dev server. The first migration creates the app_tenant role that row-level security switches to; connecting as the stock postgres superuser also works. If your role cannot create roles, the migration prints the two statements an administrator must run once.
For the built Worker, Hyperdrive needs a local override with a password, e.g. CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE=postgresql://template_owner:template@127.0.0.1:5432/template_dev, or localConnectionString on the hyperdrive entry of an uncommitted Wrangler config. Row-level security behaves the same with and without Hyperdrive; see tenant isolation.
Local runtime
The web dev server defaults to port 3005 and uses Nitro/Node, not workerd. The production build uses the Cloudflare plugin. A successful dev request alone does not validate Worker compatibility. Use the built-Worker checks for changes to server dependencies.
Parallel worktrees need separate ports and isolated databases. Set an explicit dev-server port, adjust the public server URL used by mobile, and stop only processes you started. Do not run migrations against another lane’s database.
Common setup failures
Missing credentials belong in the correct environment file. A stale development client needs rebuilding after native dependency changes. A database history mismatch needs investigation, not db:push. Start with pnpm run doctor and the existing setup skill before manually rewriting project identifiers.