Local Development
docs/architecture/LOCAL_DEVELOPMENT.md in the repository is the fuller guide; this is the
short path.
Prerequisites
Go 1.26+, Node 20+, pnpm 9.15.9, and a container runtime (Docker or Podman) for the stack.
Start the stack
cp .env.example .env
task up # Postgres/PostGIS, Redis, NATS, Keycloak, OpenFGA, MinIO, Temporal, OTel collector, Mailpit
task api:migrate # apply migrations
task api:run # API on :8080
The Keycloak container starts with --import-realm, so the bundled realm — with an audience
mapper and a demo user — is imported automatically on a first start. scripts/bootstrap-openfga.sh
provisions the OpenFGA store and model.
Note that the bundled realm is local-development only. It still carries the pre-hardening values that were changed on the production realm on 2026-08-28 (brute-force protection off, ROPC on, no enforced PKCE method) — see Security Baseline.
Portals
Eight portals live under apps/: web, admin, pro, seller, shelter, academy,
connect, provider. They are pnpm workspace packages installed from the single root
lockfile:
pnpm install # from the repository root
pnpm --filter web dev # or admin, pro, provider, academy, connect
apps/seller and apps/shelter are the exception — neither declares a workspace:*
dependency and both build with --ignore-workspace, matching their Dockerfiles:
cd apps/seller && pnpm install --ignore-workspace && pnpm dev
Mobile
cd apps/mobile && pnpm install && pnpm start # Expo
It authenticates only through the X-Debug-Actor development bypass, so it works against a
local API and cannot reach any non-development deployment (ADR-031).
Docs site
cd apps/docs && pnpm install --ignore-workspace && pnpm start
onBrokenLinks: "throw" means pnpm build fails on a broken internal link — that is the
broken-link check, and it also runs inside apps/docs/Dockerfile.
Tests
The single command that matters before pushing is scripts/verify.sh (23 checks) — see
Build and deployment. It is the real gate, because GitHub Actions does
not execute for this project.
scripts/verify.sh # everything that needs no database
scripts/verify.sh --with-db # also the integration suite, against DATABASE_URL
Individual Task targets, for a tighter loop:
task api:test # Go unit tests
task api:test:integration # integration tests, as the schema owner
task api:test:rls # the same suite as buddora_runtime, with RLS enforced
task api:lint # gofmt -l + go vet
api:test:rls is the one worth knowing about: api:test:integration connects as the schema
owner, which bypasses every row-level-security policy and therefore cannot fail on an
isolation mistake.