Files
2026-05-21 16:59:30 +02:00

121 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
> **AI disclosure:** Code in this application was written with the help of AI agents. Architecture
> decisions were still driven by the creator of this project, with agent engineering used to steer
> implementation.
## Features
- **Daily time entries** — date, project, duration (entered as h:mm), automatic cost from hourly rate; entries can be created, edited, and deleted
- **Weekly view** — navigate by ISO week; see total hours per day, individual entries, 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 and edit 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 and edit that user's name/default rate; 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.
```bash
# 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:
```bash
# 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`.
## Docker (all-in-one app + database)
Build and run the bundled app container plus PostgreSQL:
```bash
docker compose -f docker-compose.full.yml up --build
```
- App: http://localhost:8080
- API: http://localhost:8080/api
- Database: postgres://app:app@localhost:5432/app_dev
## Verify everything
```bash
mise run check # format-check + lint + test (both stacks)
```
Without mise:
```bash
# one-time setup
sudo apt install openjdk-21-jdk docker-compose-plugin
# Install Node 22 with your preferred Node version manager or distro-specific package.
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`.
Resource endpoints live under `/api/`: users can be listed and updated, projects can be listed,
created, and updated, and time entries can be listed by date range, created, updated, and deleted.
## 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`.