From 4245b821b9a2b302e70140c859ad81c14422058a Mon Sep 17 00:00:00 2001 From: Marcel Date: Sat, 13 Jun 2026 14:29:36 +0200 Subject: [PATCH] feat(timeline): add DerivedEventType enum and TimelineEntryDTO record DerivedEventType: BIRTH / DEATH / MARRIAGE discriminator for derived events. TimelineEntryDTO: unified String-id DTO for both curated and derived events; id is String (not UUID) to accommodate synthetic prefixed ids (birth:/death:/marriage:). Refs #776 Co-Authored-By: Claude Sonnet 4.6 --- .../timeline/DerivedEventType.java | 8 +++++ .../timeline/TimelineEntryDTO.java | 31 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 backend/src/main/java/org/raddatz/familienarchiv/timeline/DerivedEventType.java create mode 100644 backend/src/main/java/org/raddatz/familienarchiv/timeline/TimelineEntryDTO.java diff --git a/backend/src/main/java/org/raddatz/familienarchiv/timeline/DerivedEventType.java b/backend/src/main/java/org/raddatz/familienarchiv/timeline/DerivedEventType.java new file mode 100644 index 00000000..3616c678 --- /dev/null +++ b/backend/src/main/java/org/raddatz/familienarchiv/timeline/DerivedEventType.java @@ -0,0 +1,8 @@ +package org.raddatz.familienarchiv.timeline; + +/** Discriminator for derived life-events assembled from Person / PersonRelationship data. */ +public enum DerivedEventType { + BIRTH, + DEATH, + MARRIAGE +} diff --git a/backend/src/main/java/org/raddatz/familienarchiv/timeline/TimelineEntryDTO.java b/backend/src/main/java/org/raddatz/familienarchiv/timeline/TimelineEntryDTO.java new file mode 100644 index 00000000..9f729be9 --- /dev/null +++ b/backend/src/main/java/org/raddatz/familienarchiv/timeline/TimelineEntryDTO.java @@ -0,0 +1,31 @@ +package org.raddatz.familienarchiv.timeline; + +import io.swagger.v3.oas.annotations.media.Schema; +import org.raddatz.familienarchiv.document.DatePrecision; + +import java.time.LocalDate; + +/** + * Unified DTO for timeline entries — covers both curated {@link TimelineEvent} rows + * ({@code derived=false}) and derived life-events assembled from Person/relationship data + * ({@code derived=true}). + * + *

The {@code id} field is typed {@code String}, not {@code UUID}, because derived events + * carry synthetic prefixed ids ({@code birth:{uuid}}, {@code death:{uuid}}, + * {@code marriage:{uuid}}) that are structurally non-UUID by construction. Any write endpoint + * must reject ids that do not parse as {@code UUID} — enforced and tested in issue #5. + * + *

Callers of {@code TimelineService.assembleDerivedEvents()} must independently enforce + * {@code READ_ALL} authorization before invoking that method (see ADR-043). + */ +public record TimelineEntryDTO( + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) String id, + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) EventType type, + LocalDate eventDate, + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) DatePrecision precision, + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) boolean derived, + DerivedEventType derivedType, + String primaryPersonName, + String relatedPersonName +) { +}