Developer setup
Prerequisites
| Tool | Version | How to get it |
|---|---|---|
| Node.js | 22.x | nvm install $(cat .nvmrc) |
| pnpm | 9.15.x | corepack enable && corepack prepare pnpm@9.15.0 --activate |
| Wrangler | via pnpm | Installed as a workspace dep — no global install needed |
| Xcode + iOS Simulator | latest | Mac App Store (mobile dev only) |
| Android Studio | latest | (optional, for Android emulator) |
| Maestro | latest | curl -fsSL "https://get.maestro.mobile.dev" | bash |
First-time setup
git clone https://github.com/emiliolanzalaco/gringo-pay.git
cd gringo-pay
pnpm install
You need environment/secret values for each app. Ask a maintainer for a .env bundle, or use test/sandbox credentials.
API (apps/api)
The API reads all config from Cloudflare bindings + secrets. For local dev, create apps/api/.dev.vars — full canonical list in ops/secrets, summarised here:
# Session + PII encryption (generate with `openssl rand -hex 32`)
SESSION_SECRET=<32-byte hex>
PII_ENCRYPTION_KEY=<32-byte hex>
# Infinia (sandbox)
INFINIA_API_USERNAME=<sandbox username>
INFINIA_API_PASSWORD=<sandbox password>
INFINIA_WEBHOOK_SECRET=<32-byte hex; register as callback_url secret on Infinia resources>
INFINIA_COMPANY_ID=<sandbox company id>
INFINIA_BASE_URL=https://app2test.infiniaweb.com/infinia_api
# Native OAuth (aud values used to verify incoming id_tokens)
APPLE_BUNDLE_ID=com.gringopay.dev
GOOGLE_OAUTH_CLIENT_ID=<dev OAuth client id>
# Postgres — a Neon branch DB for dev (must have pgcrypto extension enabled)
NEON_DB_URL=postgresql://<user>:<pw>@<host>/<db>?sslmode=require
# Tests use a LOCAL Postgres (see "Running tests" below) — no env var needed.
# Override only to point elsewhere:
# TEST_DATABASE_URL=postgres://postgres:postgres@localhost:5432/gringo_test
One-time DB setup — on the Neon branch you use for dev, enable pgcrypto
(the test database gets it automatically via migration 0009):
CREATE EXTENSION IF NOT EXISTS pgcrypto;
See ops/migrations for the why.
Tests run against a local Postgres container — start it before pnpm test:
cd apps/api && docker compose up -d --wait
Mobile (apps/mobile)
Copy apps/mobile/.env.example → apps/mobile/.env.local and fill in the API base URL plus the Apple / Google OAuth client identifiers (must match the API's APPLE_BUNDLE_ID and GOOGLE_OAUTH_CLIENT_ID):
EXPO_PUBLIC_API_BASE_URL=http://localhost:8787
EXPO_PUBLIC_APPLE_BUNDLE_ID=com.gringopay.dev
EXPO_PUBLIC_GOOGLE_OAUTH_CLIENT_ID=<dev OAuth client id>
Run everything locally
# API on http://localhost:8787
pnpm --filter @gringo-pay/api dev
# Mobile — Metro dev server
pnpm --filter @gringo-pay/mobile dev
# then press i (iOS simulator) or a (Android emulator)
# Docs on http://localhost:3000
pnpm --filter @gringo-pay/docs dev
# Web on http://localhost:4321
pnpm --filter @gringo-pay/web dev
Or use Turbo to run them all in parallel:
pnpm dev
Sanity checks before opening a PR
The same checks CI runs, in the order they'll fail:
pnpm lint # ESLint across all workspaces
pnpm typecheck # tsc --noEmit
pnpm build # Turbo build all workspaces
pnpm test # Vitest / Jest — API tests need the local Postgres (docker compose up -d --wait)
Or filter to what you touched:
pnpm --filter @gringo-pay/api typecheck
pnpm --filter @gringo-pay/mobile test
Editor setup
- VS Code recommended. Install the recommended workspace extensions if prompted (ESLint, Prettier, Tailwind CSS IntelliSense).
- On save: format with Prettier, run ESLint fix.
apps/api/worker-configuration.d.tsis generated bywrangler types— don't hand-edit. If you get type errors about missingEnvbindings, runpnpm --filter @gringo-pay/api types(orwrangler types).