5.8 KiB
Local Development Guide
Use this guide after the first quickstart bootstrap when you are working in the repository day to day. It keeps local setup explicit, avoids production secrets, and keeps browser, Playwright, Cypress, and other E2E checks as manual review unless a focused run is explicitly approved.
Local service prerequisites
Install and run these local services before starting the application:
- Node.js compatible with the repository runtime expectation.
- Corepack with the pinned package manager,
pnpm@10.33.0. - PostgreSQL for the Prisma-backed application database.
- Optional Redis only when queue or worker behavior is in scope.
Activate the pinned package manager from the repository root:
corepack enable
corepack prepare pnpm@10.33.0 --activate
pnpm install
Local environment placeholders
Create a local environment file from the example:
cp .env.example .env
Use placeholder-only values in .env. Do not copy production secrets, real deployment credentials, live API keys, OAuth secrets, Mailjet credentials, Stripe secrets, database passwords, or webhook signing secrets into local docs or examples.
Review these local values before running commands:
APP_NAME: local display name.SESSION_SECRET: local placeholder session secret.CRYPTO_SECRET: local placeholder encryption secret.DATABASE_URL: local PostgreSQL connection string consumed by Prisma.DIRECT_URL: optional direct Prisma connection placeholder for maintenance commands.APP_BASE_DOMAIN,WEB_APP_HOST,ADMIN_APP_HOST,API_HOST, andAPP_PROTOCOL: split-host local routing settings from.env.example.PORT: web listener bind port only; keep the default unless you need a different local port.WORKER_ENABLED: set totrueonly when intentionally running worker behavior.BULLMQ_REDIS_URL: local Redis placeholder for BullMQ when the worker is enabled.
PostgreSQL and Prisma workflow
Start PostgreSQL locally and confirm DATABASE_URL points to that database. Apply migrations during normal schema work:
pnpm exec prisma migrate dev
Check migration status when local schema or generated client state feels stale:
pnpm exec prisma migrate status
For disposable bootstrap databases where migrations are not enough, a local schema push may be used deliberately:
pnpm exec prisma db push
After schema changes or dependency updates, refresh generated Prisma client artifacts when needed:
pnpm exec prisma generate
Seed and run the web runtime
Seed local development data after the schema is ready:
pnpm seed
pnpm run permissions:sync
Start the @toolctrl/web React Router runtime from the root script; source lives in apps/web/app:
pnpm dev
Open http://app.localhost:3000 for the tenant app and http://admin.localhost:3000 for admin. The root pnpm dev command starts only the @toolctrl/web runtime; when API work is in scope, run pnpm --filter @toolctrl/api dev separately and open http://api.localhost:3001. Seeded accounts and placeholder credentials are development conveniences only and must not be reused in production.
Optional API and worker notes
The root script starts the @toolctrl/web React Router runtime. apps/api contains the runtime-wired Hono /v1 API app, but it is not required for the default local web loop unless the task explicitly targets API behavior.
The worker foundation is opt-in. Redis is not required for ordinary web development. To run worker-related behavior, start Redis locally, set WORKER_ENABLED=true, and set BULLMQ_REDIS_URL to a local placeholder such as redis://localhost:6379/0. Leave REDIS_URL as a platform-binding fallback unless that specific environment contract is under test.
Focused non-E2E verification
Use scoped checks that match the files or behavior you changed. Examples:
pnpm exec eslint docs/local-dev.md --max-warnings=0
node scripts/verify-production-docs.mjs
node -e "const fs=require('fs');const s=fs.readFileSync('docs/local-dev.md','utf8');for(const r of [/pnpm dev/,/DATABASE_URL/,/PostgreSQL/,/Prisma/,/WORKER_ENABLED/,/BULLMQ_REDIS_URL/,/manual/]) if(!r.test(s)) process.exit(1);"
Do not add browser, Playwright, Cypress, or test:e2e commands as automatic local development verification. Keep those flows manual unless a specific run is explicitly approved, and record the manual scenario and result in handoff notes.
Troubleshooting
PostgreSQL connection failures
Confirm PostgreSQL is running, the database exists, and DATABASE_URL uses local placeholder credentials. Re-run pnpm exec prisma migrate status to distinguish connectivity failures from migration drift.
Prisma schema or client drift
If generated types or local queries disagree with the schema, run pnpm exec prisma migrate status, apply the missing migration with pnpm exec prisma migrate dev, and regenerate the client with pnpm exec prisma generate when needed. For throwaway local databases, recreate the database and run the seed again instead of editing migrations manually.
Seed problems
Confirm migrations or pnpm exec prisma db push completed successfully before pnpm seed. Run pnpm run permissions:sync after role or permission changes. If seed data partially exists, reset only your disposable local database and keep production databases out of the workflow.
Redis or worker startup problems
If worker logs mention Redis or BullMQ, verify Redis is running locally and BULLMQ_REDIS_URL is set. If you are not working on queue behavior, unset WORKER_ENABLED or keep it false so the worker path remains opt-in.
Configuration drift
Compare .env with .env.example after pulling changes. Add missing local placeholders, remove accidental real secrets, and keep documentation examples generic.