Local Development

Local development

- Node.js 22 or later - pnpm 11 or later - Docker with Compose support

Use this when...

Use this when changing, testing, or deploying the system.

Prerequisites

  • Node.js 22 or later
  • pnpm 11 or later
  • Docker with Compose support

First run

cp .env.example .env
# Replace every placeholder in .env and generate a random BETTER_AUTH_SECRET.
docker compose up -d postgres
pnpm install
pnpm db:migrate
pnpm db:seed
pnpm dev

Open http://localhost:3000/login for the dashboard and http://localhost:3001 for docs. Sign in with SEED_ADMIN_EMAIL and SEED_ADMIN_PASSWORD from your untracked .env.

Database scripts and the web application both load this shared root .env; no app-local environment file is required.

For phone or tablet testing on the same local network, run pnpm dev:lan and read Mobile/LAN Login Troubleshooting. Local development auth accepts localhost:3000, 127.0.0.1:3000, and private LAN IP hosts on port 3000; keep BETTER_AUTH_URL=http://localhost:3000 for normal desktop development unless that exact environment changes.

Set SEED_CRM_SAMPLE_DATA=true before pnpm db:seed to add local-only CRM examples. The seed refuses sample CRM data when NODE_ENV=production and requires the development administrator variables.

After signing in, open http://localhost:3000/crm. CRM pages require crm.view; create and edit controls require crm.manage.

Set SEED_AUDIT_SAMPLE_DATA=true before pnpm db:seed to add local-only audit/load-assessment examples. The seed refuses sample audit data when NODE_ENV=production and requires the development administrator variables.

After signing in, open http://localhost:3000/audits. Audit pages require audits.view; create, edit, load-item, and finding-resolution controls require audits.manage.

Set SEED_INVENTORY_SAMPLE_DATA=true before pnpm db:seed to add local-only inventory/product examples. For richer quote, project, and support links, enable the earlier CRM, audit, quote, finance, project, and support sample flags too.

After signing in, open http://localhost:3000/inventory. Inventory pages require inventory.view; create/edit controls require inventory.manage; activations and high-risk approvals require inventory.approve.

Set SEED_COMMAND_CENTER_SAMPLE_DATA=true before pnpm db:seed to add local-only command-center examples. For richer cross-module cards, alerts, actions, and customer 360 records, enable the earlier CRM, audit, quote, finance, project, support, and inventory sample flags too.

After signing in, open http://localhost:3000/command-center. Command-center pages require command_center.view; refresh, snapshot, and preference controls require command_center.manage; alert and required-action updates require their dedicated manage permissions.

Set SEED_KNOWLEDGE_SAMPLE_DATA=true before pnpm db:seed to add local-only knowledge, SOP, decision, entity-link, document-index, and search-index examples. Source-of-truth and data-dictionary foundation records are seeded by default.

After signing in, open http://localhost:3000/search and http://localhost:3000/knowledge. Search requires search.view; knowledge pages require knowledge.view; edits require knowledge.manage; approvals require knowledge.approve; source registry management requires source_truth.manage.

Set SEED_IMPORT_SAMPLE_DATA=true before pnpm db:seed to add local-only import mappings, dry-run rows, validation issues, duplicate candidates, and approval requests. Baseline source-of-truth/import-source registry records seed by default. Sprint 13 Google Drive variables are placeholders only; no live Google Drive sync runs locally.

After signing in, open http://localhost:3000/imports. Import staging pages require imports.view; staging create/edit controls require imports.manage; approval decisions require imports.approve; drive/legacy registries use drive_sources.*; migration audit log uses migration.view.

Useful commands

pnpm db:generate
pnpm db:migrate -- --name descriptive-change
pnpm db:migrate:deploy
pnpm db:seed
pnpm db:studio
pnpm typecheck
pnpm lint
pnpm test
pnpm build
docker compose stop

pnpm typecheck runs the active TypeScript quality gate across the workspace through Turbo. pnpm lint runs package-level lint scripts only when real lint infrastructure is configured; at present it reports that no lint runner is configured and does not type-check as a substitute. pnpm test follows the same rule for package-level test scripts and currently reports that no test runner is configured.

To remove all local database data, explicitly remove the Compose volume. That operation is destructive and should never be used against non-local infrastructure.

Troubleshooting

  • Connection refused: wait for docker compose ps to show PostgreSQL healthy.
  • Login rejected: rerun seed and verify all SEED_ADMIN_* values were present.
  • Missing generated client: run pnpm db:generate.
  • Cookie/URL errors: keep BETTER_AUTH_URL=http://localhost:3000 locally, restart pnpm dev:lan, and check /api/dev/auth-diagnostics from the same host that is failing.
  • New route returns 404 during local dev: restart pnpm dev and confirm the current branch contains the route.
Developer Details
Source
apps/docs/content/local-development.md
Owner
Module Owner
Status
Current
Module
Local Development
Related route
None