Time Tracker

A browser-based time-tracking app: log daily work against projects, review totals in weekly and monthly views, and track project budgets with automatic cost calculation and soft breach warnings.

Stack: React 19 + Vite 6 (TypeScript strict) — Spring Boot 3.4 (Java 21) — PostgreSQL 17 via Docker Compose — Flyway for schema migrations — Tailwind CSS v4 — Biome 1.9 — Vitest.

Features

  • Daily time entries — date, project, duration (entered as h:mm), automatic cost from hourly rate
  • Weekly view — navigate by ISO week; see total hours per day and a running week total
  • Monthly view — per-project summary with time and cost progress bars; red banner when a budget is exceeded
  • Project management — create projects with time and cost budgets; set a project-level hourly rate or fall back to the user's default
  • Multi-user — pick any seeded user from the dropdown; cost is calculated using that user's rate when no project rate is set
  • Soft budget enforcement — entries always save; over-budget projects are highlighted with a warning banner and colored bars

Quick start

Requires a full Java 21 JDK (not just a JRE) for Maven compilation. mise install below handles this and sets JAVA_HOME when commands are run through mise. Without mise: sudo apt install openjdk-21-jdk, then ensure java -version reports 21 and JAVA_HOME points at that JDK.

# 1. Pin toolchain — installs Java 21 JDK, Node 22, Maven, lefthook, gitleaks
mise install

# 2. Install deps, git hooks, .env, and validate Java + Maven wrapper
mise run setup

# 3. Start the database
docker compose up -d

Open two terminals:

# Backend → http://localhost:8080
mise run backend

# Frontend → http://localhost:5173  (proxies /api → :8080)
mise run frontend

If you have activated mise in your shell, the direct commands also work: backend/mvnw -f backend/pom.xml spring-boot:run and cd frontend && npm run dev.

Verify everything

mise run check       # format-check + lint + test (both stacks)

Without mise:

# one-time setup
sudo apt install openjdk-21-jdk nodejs npm docker-compose-plugin
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64  # adjust if your JDK is elsewhere
npm --prefix frontend install
cp -n .env.example .env
backend/mvnw -f backend/pom.xml -v                 # primes the Maven wrapper cache

# checks
backend/mvnw -f backend/pom.xml spotless:check -q
cd frontend && npx biome check src
backend/mvnw -f backend/pom.xml test -q
cd frontend && npx vitest run

Design notes

Money and duration are stored as integers (cents and minutes respectively) to avoid floating-point drift. Cost for a time entry is computed at read time: duration_minutes × effective_rate_cents / 60, where the effective rate is the project's hourly_rate_cents if set, otherwise the user's default_hourly_rate_cents. This means changing a rate retroactively updates all historical cost totals — a deliberate trade-off for simplicity (see NEXT_STEPS.md for a snapshot-based alternative).

Budget warnings are soft: any entry saves regardless of budget status. Breach is detected in the reporting layer by comparing aggregated totals to the project's time_budget_minutes and cost_budget_cents. The monthly view renders a red warning banner and saturated progress bars for any over-budget project.

Schema migrations are managed exclusively by Flyway (V1__init.sql for schema, V2__seed_demo_data.sql for demo users and projects). Hibernate is set to validate — it never modifies the schema.

API shape — aggregation is done server-side via two dedicated endpoints: GET /api/reports/weekly?userId=&week=YYYY-Www and GET /api/reports/monthly?userId=&month=YYYY-MM. All other CRUD endpoints follow standard REST conventions under /api/.

Environment

.env.example documents all env vars. mise run setup copies it to .env automatically on first run.

Troubleshooting

  • backend/mvnw: ... exec: .../apache-maven-3.9.9/bin/mvn: not found — run mise run setup again. The setup task primes the Maven wrapper cache. If it still fails, remove the broken cache with rm -rf ~/.m2/wrapper/dists/apache-maven-3.9.9* and rerun mise run setup.
  • JAVA_HOME environment variable is not defined correctly — install a Java 21 JDK and set JAVA_HOME, or use the mise tasks (mise run backend, mise run check) after mise install.
S
Description
No description provided
Readme 121 KiB
Languages
TypeScript 57.7%
Java 41.2%
Dockerfile 0.8%
HTML 0.3%