Local Development
This section describes how to run Cashlytics locally for development.
Prerequisites
- Node.js 24 (see
.nvmrc; theenginesfield requires at least 22.14) - npm
- Docker (runs PostgreSQL 16 for local development)
- Git 2.32 or newer (the Husky pre-commit hook is installed by
npm install)
Setup
git clone https://github.com/aaronjoeldev/cashlytics-ai.git
cd cashlytics-ai
npm install
cp .env.example .env
.env.example uses the Docker network host postgres in DATABASE_URL. For local development, change it to localhost:
DATABASE_URL=postgresql://cashlytics:cashlytics_secret@localhost:5432/cashlytics
Also set AUTH_SECRET (for example openssl rand -base64 32); the app does not start without it. See Environment Variables for everything else.
Start Database and App
./scripts/dev.sh
The script starts only the postgres service from docker-compose.yml (container cashlytics-postgres), waits until it accepts connections, applies the migrations with npm run db:migrate, and then runs npm run dev. Open http://localhost:3000.
Database Migrations
The project uses versioned SQL migrations in drizzle/. Use these commands:
npm run db:migrate # apply pending migrations
npm run db:generate # create a new migration after changing src/lib/db/schema.ts
Do not use npm run db:push for normal work. It bypasses the migration history and can leave your schema out of step with what the Docker image applies on startup.
Demo Data
psql "$DATABASE_URL" -f scripts/seed-demo.sql
This deletes all data in the target database and creates the demo user demo@cashlytics.online with the password admin123456789. Never run it against a database with real data.
Commands
| Command | Purpose |
|---|---|
npm run dev | Development server |
npm test | Unit tests (node:test via tsx) |
npm run typecheck / npm run lint | TypeScript and ESLint |
npm run format:check | Prettier check |
npm run build / npm start | Production build and server |
npm run e2e:up / npm run e2e:down | Start / remove the end-to-end stack |
npm run test:e2e | End-to-end tests |
npm run e2e:up builds the production image from your checkout and starts it with PostgreSQL, a Mailpit mail catcher, and a fake OpenAI API. npm run test:e2e resets that stack's database to the demo data and drives the app with Chrome (set CHROME_PATH if Chrome is not found).
Developer Expectations
- Keep TypeScript strict-mode compatible.
- Use Server Actions for data mutations.
- Keep schema and validation changes aligned.
- Update documentation when feature behavior changes.