package org.raddatz.familienarchiv.timeline;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

import org.raddatz.familienarchiv.document.DatePrecision;

import java.time.LocalDate;
import java.util.List;
import java.util.UUID;

/**
 * Flat input DTO for creating/updating a {@link TimelineEvent}. Bean Validation fires at the
 * controller boundary (via {@code @Valid}) and produces a 400 {@code VALIDATION_ERROR} for the
 * presence/size constraints below; cross-field rules (the RANGE invariant), date normalization,
 * id dedupe, and the title-length structured-error guard live in {@code TimelineEventService}.
 *
 * <p><strong>{@code createdBy}/{@code updatedBy} are intentionally absent.</strong> Authorship is
 * server-populated from the session principal only — accepting it from the body would be an
 * authorship-forgery / mass-assignment vector (CWE-639; see ADR-040 §7).
 *
 * @param version optional optimistic-lock concurrency token (the {@code @Version} the client last
 *                saw), applied on <em>update</em> only. This is a concurrency token, <strong>not</strong>
 *                an authorship field, so it is deliberately exempt from the §7 server-only audit rule.
 *                Null on update means "no concurrency check" (last-write-wins). No range validation —
 *                a stale/negative value is simply a mismatch the lock rejects at flush; the lock, not
 *                a validator, is the control.
 */
public record TimelineEventRequest(
        @NotBlank @Size(max = 255) String title,
        @NotNull EventType type,
        @NotNull LocalDate eventDate,
        DatePrecision precision,
        LocalDate eventDateEnd,
        @Size(max = 5000) String description,
        Long version,
        @Size(max = 50) List<UUID> personIds,
        @Size(max = 50) List<UUID> documentIds
) {}
