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>
This commit is contained in:
2026-05-16 11:41:23 +02:00
parent ffa357775b
commit ad23616c7b
20 changed files with 764 additions and 0 deletions
@@ -0,0 +1,30 @@
package com.example.app.project;
import com.example.app.project.ProjectDtos.CreateProjectRequest;
import com.example.app.project.ProjectDtos.ProjectResponse;
import jakarta.validation.Valid;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/projects")
public class ProjectController {
private final ProjectService projectService;
public ProjectController(ProjectService projectService) {
this.projectService = projectService;
}
@GetMapping
public List<ProjectResponse> list() {
return projectService.findAll();
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public ProjectResponse create(@Valid @RequestBody CreateProjectRequest req) {
return projectService.create(req);
}
}