Timeline: TimelineEvent CRUD API (#775) #822

Merged
marcel merged 12 commits from feat/issue-775-timeline-crud-api into main 2026-06-13 12:29:49 +02:00
Showing only changes of commit aca7e7cc17 - Show all commits

View File

@@ -0,0 +1,59 @@
package org.raddatz.familienarchiv.timeline;
import io.swagger.v3.oas.annotations.media.Schema;
import org.raddatz.familienarchiv.document.DatePrecision;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
/**
* Response view for the timeline event endpoints — returned by GET, POST, and PUT alike.
* Assembled inside the service transaction (after {@code saveAndFlush} on the write paths, so
* {@code version} is non-null) from the managed entity's already-loaded collections. The raw
* {@link TimelineEvent} is never serialized: its LAZY {@code persons}/{@code documents}
* collections under {@code open-in-view: false} would otherwise 500 (ADR-036/ADR-040 §2), and
* splatting the entities would leak curator-internal fields ({@code Person.notes},
* {@code provisional}, transcription data) to every READ_ALL reader. The explicit field
* allow-list below is that guarantee.
*/
public record TimelineEventView(
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) UUID id,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) String title,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) EventType type,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) LocalDate eventDate,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) DatePrecision precision,
LocalDate eventDateEnd,
String description,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) Long version,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) UUID createdBy,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) LocalDateTime createdAt,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) UUID updatedBy,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) LocalDateTime updatedAt,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) List<PersonView> persons,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) List<DocumentRef> documents
) {
/** Summarised person — exposes only id, firstName, and lastName. Mirrors GeschichteView.PersonView. */
public record PersonView(
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) UUID id,
String firstName,
String lastName
) {}
/**
* Summarised linked document — id, title, and the eager {@code documentDate} only (no lazy
* sender/receiver hop, no person-name leak through the document side).
*
* <p>timeline-local by design; do not promote to {@code document/} — see #775 R7. Reusing
* {@code geschichte.journeyitem.DocumentSummary} would force a cross-domain import of a
* package-private mapper plus duplicated name-assembly logic; a 3-field local record is the
* lower-coupling choice.
*/
public record DocumentRef(
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) UUID id,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) String title,
LocalDate documentDate
) {}
}