Commit Graph

10 Commits

Author SHA1 Message Date
achim 1c33371e4d docs(readme): use Maven wrapper instead of bare mvn
No system Maven is installed; backend/mvnw is the correct entry point.
Updated run and verify-everything commands accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 12:17:13 +02:00
achim 00521afd18 fix(test): explicit type witness on List.of(Object[]) for Mockito inference
javac couldn't infer List<Object[]> from List.of(row) when row is Object[];
adding the explicit type witness List.<Object[]>of(row) resolves the
ambiguous overload that caused the compilation error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 12:07:55 +02:00
achim 7877dc0631 docs: update README with features and design notes; add NEXT_STEPS
README now covers features list, run instructions, design rationale
(integer money/duration, read-time cost resolution, soft budget
enforcement, Flyway-only schema, API shape).

NEXT_STEPS.md catalogs deferred work: user CRUD UI, rate snapshots,
notes field, CSV export, auth, pagination, Playwright e2e, i18n,
dark mode, bookmarkable URLs, full backend test pyramid.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 11:57:46 +02:00
achim bef6abdd2e test(frontend): add component tests — TimeEntryForm, WeeklyView, App smoke
- TimeEntryForm.test.tsx: fills date/project/h:mm, clicks submit,
  asserts fetch called with correct JSON body (mocked fetch)
- WeeklyView.test.tsx: renders with stubbed WeeklyReport fixture,
  asserts each day's h:mm and the week total display correctly
- App.test.tsx: smoke test — renders layout with TopBar and main content

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 11:57:07 +02:00
achim 416223e80b feat(frontend): implement all views and components
- TopBar: brand + nav links (NavLink active styling) + user dropdown
- TimeEntryForm: create + edit mode; date/project/h:mm inputs; pre-fills
  on edit; posts to /api/time-entries or PUTs /{id}
- WeeklyView: ISO week navigation (← →); 7-day list with entry rows,
  inline TimeEntryForm per day, delete; week total in header
- MonthlyView: year-month navigation; per-project table with time and
  cost progress bars; BudgetBanner for breached projects
- ProjectsView: project list with budget bars + create-project form
- BudgetBanner: red banner displayed when any project is over budget

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 11:48:00 +02:00
achim 02f0dc4241 feat(frontend): scaffold — Tailwind v4, routing, API layer, UserContext
- tailwindcss + @tailwindcss/vite, react-router-dom, date-fns, zod installed
- vite.config.ts: Tailwind v4 Vite plugin wired in
- index.css: single @import "tailwindcss" (zero-config v4)
- main.tsx: wrapped in <BrowserRouter>; imports index.css
- App.tsx: layout shell with <TopBar/> + <Routes> (/, /weekly, /monthly, /projects)
- lib/api.ts: Zod schemas for all API types + typed fetch wrapper; all
  responses validated before field access (per CLAUDE.md rule)
- lib/format.ts: minutesToHmm, hmmToMinutes, centsToEur, ISO week helpers,
  year-month helpers, formatDate
- lib/types.ts: z.infer<> re-exports from api.ts
- state/UserContext.tsx: selected user persisted in localStorage; auto-
  selects first user on load

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 11:43:35 +02:00
achim 6029085d1c test(backend): add happy-path test pyramid — repo, service, e2e
- TimeEntryRepositoryTest (@DataJpaTest): inserts entries across two weeks,
  asserts date-range query returns only the correct slice
- ReportServiceTest (@ExtendWith(MockitoExtension)): mocks repository,
  covers weekly aggregation, parseIsoWeekToMonday returning a Monday,
  and monthly breach detection (both time and cost thresholds)
- TimeEntryEndToEndTest (@SpringBootTest + MockMvc): POST a 90-min entry,
  GET /api/reports/weekly, assert weekTotalMinutes=90

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 11:42:42 +02:00
achim ad23616c7b feat(backend): implement domain — users, projects, time entries, reports
- User, Project, TimeEntry JPA entities with SLF4J logging in services
- Native SQL aggregate queries: per-day (weekly) and per-project (monthly)
  both using COALESCE(project_rate, user_rate) for cost calculation
- ReportService parses ISO week/month strings, fills zero-day gaps,
  computes timeBudgetPct / costBudgetPct / breached per project
- ProjectService piggybacks on aggregateAllByProject for budget status
  on GET /api/projects (no N+1)
- GlobalExceptionHandler maps validation errors → 400 ProblemDetail,
  EntityNotFoundException → 404, IllegalArgumentException → 400
- Lombok on pom.xml (optional, used for @Getter/@Setter/@NoArgsConstructor)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 11:41:23 +02:00
achim ffa357775b feat(db): add Flyway migrations — schema V1 and demo seed V2
V1 creates users, projects, time_entries with CHECK constraints and
three indexes (entry_date, project_id, user+date composite).
V2 seeds 3 users (Alice/Bob/Clara) and 3 projects, one with a
project-level hourly rate override (Acme Relaunch).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 11:37:23 +02:00
achim cc00c6c6ae scaffold: React 19 + Spring Boot 3.4 + PostgreSQL project
Sets up toolchain pinning, format/lint (Biome + Spotless), lefthook
pre-commit hooks, Docker Compose for Postgres, and trivial passing
tests for both stacks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 00:52:57 +02:00