# Next Steps Items that were out of scope for the initial 6-hour build, with notes on how to approach each. ## Features ### User creation / deletion UI Users are seeded via Flyway (`V2__seed_demo_data.sql`) and the selected user's name/default rate can be edited from the top bar. A `POST /api/users` endpoint with a "New User" form, plus optional delete support, would complete the CRUD cycle. Straightforward to add following the same pattern as project creation. ### Time entry edit smoke coverage Editing existing time entries is implemented end-to-end (`PUT /api/time-entries/{id}`, `TimeEntryForm` edit mode, and the `WeeklyView` Edit button). Add explicit frontend and/or MockMvc smoke coverage for the edit path so regressions are caught. ### Notes / description field on time entries Add a `TEXT` column to `time_entries` (new Flyway migration), expose it in the DTOs, and add a textarea to `TimeEntryForm`. Straightforward schema change. ### Rate history — audit-stable costs Currently, cost is computed at read time from the current project/user hourly rate. If a rate changes, historical costs change retroactively. To fix: add `hourly_rate_cents_snapshot INTEGER NOT NULL` to `time_entries`, resolve and snapshot the rate in `TimeEntryService.create()`. Historical queries then use the snapshot instead of joining to current rates. ### CSV export of reports Add a `GET /api/reports/weekly.csv?userId=&week=` and `/monthly.csv` endpoint that streams `text/csv`. Frontend adds a "Download CSV" button that opens the URL in a new tab. ## Technical quality ### Full backend test pyramid The current tests cover the repository date-range query, service cost/budget logic, one end-to-end MockMvc flow, and a few validation cases for user/project updates. Gaps to fill: - Dedicated `@WebMvcTest` controller-slice tests for validation error responses (400 on invalid fields). - More `@DataJpaTest` cases (zero entries, multiple users, rate fallback). - `@SpringBootTest` with Testcontainers so tests do not depend on an externally-running PostgreSQL. ### Frontend end-to-end tests (Playwright) A Playwright suite covering the golden paths: 1. Log a time entry → verify it appears in the weekly view. 2. Create a project → verify it appears in the project list. 3. Exceed a project budget → verify the budget banner appears. ### Pagination of time entries `GET /api/time-entries` returns all entries in a date range. For large datasets, add Spring Data pagination (`Pageable` parameter) and a "Load more" button or cursor in the frontend. ## UX improvements ### Delete confirmation modal Currently `confirm()` is used for delete. Replace with a small Tailwind dialog / Headless UI `Dialog` for a consistent UX. ### Bookmarkable week/month URLs Weekly and monthly views use component state for the selected period. Moving the period to the URL (e.g., `/weekly/2026-W20`, `/monthly/2026-05`) enables bookmarking and browser back/forward. React Router v7 `useParams` + `useNavigate` is the implementation path. ### Validation error UI polish Form errors are shown as a banner above the form. Inline per-field errors (below each input) would be more discoverable. ## Architecture ### Authentication & per-user data isolation No auth in the current build — user is selected via a dropdown. For production, add Spring Security with JWT or session-based auth. The `user_id` on `time_entries` already supports per-user isolation; the API just needs to enforce it from the authenticated principal. ### Per-project currency Add `currency CHAR(3) NOT NULL DEFAULT 'EUR'` to `projects`. The aggregation queries then need currency-aware math; cross-currency totals on the monthly report would require a conversion rate or report per-currency totals separately. ### Time zone awareness `time_entries.entry_date` is a `LocalDate` (no zone). If users span time zones, "today" must be resolved from the user's local zone rather than the server's. Pass a `timeZone` parameter or derive it from the authenticated user's profile. ### Dark mode Tailwind v4 supports `prefers-color-scheme` media queries via the `dark:` variant. Add `@media (prefers-color-scheme: dark)` styles or a toggle stored in `localStorage`. ### i18n (de/en) Hardcoded strings are in English; currency formatting uses German locale (`de-DE`). Introduce `react-intl` or a similar library and extract string constants. Language preference lives in user settings or `Accept-Language`. ### Performance - N+1 in `ProjectService.findAll()`: one aggregate query for all projects avoids it (already done via `aggregateAllByProject`). No further action needed at small scale. - Large datasets: consider materialized views or a dedicated reporting aggregate table updated via a database trigger or scheduled job.