feat(timeline): add GET /api/timeline endpoint + 8-test controller suite

TimelineController exposes GET /api/timeline with @RequirePermission(READ_ALL)
and @Validated so @Min(0) on generation fires a 400. Delegates to
TimelineService.assemble(TimelineFilter). DomainException 404/400 propagate
via GlobalExceptionHandler (no extra mapping needed).

Refs #777
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-06-13 16:22:44 +02:00
parent f08b09faeb
commit afd1f0b86b
2 changed files with 172 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
package org.raddatz.familienarchiv.timeline;
import jakarta.validation.constraints.Min;
import lombok.RequiredArgsConstructor;
import org.raddatz.familienarchiv.security.Permission;
import org.raddatz.familienarchiv.security.RequirePermission;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
@RestController
@RequestMapping("/api/timeline")
@Validated
@RequiredArgsConstructor
public class TimelineController {
private final TimelineService timelineService;
@GetMapping
@RequirePermission(Permission.READ_ALL)
public TimelineDTO getTimeline(
@RequestParam(required = false) UUID personId,
@RequestParam(required = false) @Min(0) Integer generation,
@RequestParam(required = false) EventType type,
@RequestParam(required = false) Integer fromYear,
@RequestParam(required = false) Integer toYear) {
return timelineService.assemble(new TimelineFilter(personId, generation, type, fromYear, toYear));
}
}