Skip to content

Local Development Setup ​

This tutorial walks you through getting the full TT Time Tracker stack running on your machine. By the end you will have:

  • PostgreSQL, Redis, and RustFS running in Docker
  • The NestJS API running with hot-reload on port 3000
  • The BullMQ worker running in the background
  • The Vue SPA running with hot-reload on port 5173

Prerequisites ​

Before you start, make sure you have:

  • Node.js 20+ — check with node -v
  • pnpm 10+ — install with npm install -g pnpm@latest
  • Docker + Docker Compose — check with docker compose version

Step 1 — Clone the repository ​

bash
git clone <repository-url> tt-time-tracker
cd tt-time-tracker

Step 2 — Install dependencies ​

bash
pnpm install

This installs dependencies for all packages and services in the monorepo.

Step 3 — Start the infrastructure ​

bash
pnpm db:up

This starts three Docker services in the background:

ServicePurposeDefault port
postgresPrimary database (PostgreSQL 16)5432
redisJob queue broker (Redis 7)6379
rustfsFile storage for invoices (S3-compatible)9000 (API), 9001 (console)

Wait a few seconds for the health checks to pass. You can verify they are running with docker compose ps.

Step 4 — Configure the environment ​

Copy the example environment file:

bash
cp .env.example .env

Open .env and set the required values. For local development the defaults work, but you must set a BETTER_AUTH_SECRET:

bash
# Generate a secure secret
openssl rand -base64 32

Paste the output as the value of BETTER_AUTH_SECRET in .env.

Optional: AI-powered invoice extraction

To use the invoice extraction feature locally, set OPENROUTER_KEY in .env (the worker requires it to boot). The API and client work without running the worker — invoices will stay unprocessed instead of being auto-filled.

Step 5 — Run database migrations ​

bash
pnpm db:migrate

This applies all Prisma migrations against the local PostgreSQL instance and generates the Prisma client.

Step 6 — Start the services ​

Open three terminal windows and run one command in each:

Terminal 1 — API:

bash
pnpm dev:api

The API starts on http://localhost:3000. Swagger UI is available at http://localhost:3000/docs.

Terminal 2 — Worker:

bash
pnpm dev:worker

Terminal 3 — Frontend:

bash
pnpm dev:client

The frontend starts on http://localhost:5173.

Step 7 — Verify everything is working ​

  1. Open http://localhost:5173 in your browser
  2. You should see the public landing page — go to http://localhost:5173/login for the login page
  3. Sign in with Google OAuth (requires GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET) or create a user directly via the Prisma Studio:
bash
pnpm db:studio

Prisma Studio opens at http://localhost:5555 where you can inspect and insert records directly.

Troubleshooting ​

pnpm db:migrate fails with "Connection refused" The PostgreSQL container is not ready yet. Wait 5–10 seconds and try again, or check docker compose ps to confirm the postgres service is healthy.

API fails to start with "Invalid AUTH_SECRET"BETTER_AUTH_SECRET must be at least 32 characters. Re-run openssl rand -base64 32 and update .env.

Port conflict on 5432/6379 You may already have a local PostgreSQL or Redis instance running. Either stop them, or change the host ports in docker-compose.yaml and update the connection strings in .env.

Next steps ​

TT Time Tracker — Internal Documentation