@startuml !include title Component Diagram: API Backend — Timeline (Zeitstrahl) ContainerDb(db, "PostgreSQL", "PostgreSQL 16") System_Boundary(backend, "API Backend (Spring Boot)") { Component(timelineRepo, "TimelineEventRepository", "Spring Data JPA", "Reads and writes TimelineEvent rows and their persons/documents join tables (timeline_event_persons, timeline_event_documents).") Component(timelineSvc, "TimelineEventService", "Spring Service", "Owns curated-event CRUD: assembles TimelineEventView inside the transaction (lazy ManyToMany + open-in-view=false, ADR-036/ADR-040), populates createdBy/updatedBy from the session principal, and translates optimistic-lock conflicts to DomainException.conflict. Also exposes assembleDerivedEvents(): computes Geburt/Tod/Heirat TimelineEntryDTOs on read from Person/PersonRelationship data — never persisted (ADR-043).") Component(timelineCtrl, "TimelineEventController", "Spring MVC", "Exposes /api/timeline reads (READ_ALL) and writes (WRITE_ALL). createdBy/updatedBy are never bound from request bodies (CWE-639).") } System_Ext(documentDomain, "Document domain", "Provides DatePrecision (shared value type) and Document references for linked letters") System_Ext(personDomain, "Person domain", "Provides Person references (PersonService.findAllFamilyMembers) and SPOUSE_OF edges (RelationshipService.findAllSpouseEdges) for derived-event assembly and curated-event links") Rel(timelineRepo, db, "SQL queries", "JDBC") Rel(timelineSvc, timelineRepo, "Reads / writes events") Rel(timelineCtrl, timelineSvc, "Delegates to") Rel(timelineRepo, personDomain, "References persons via join table") Rel(timelineRepo, documentDomain, "References documents via join table") Rel(timelineSvc, personDomain, "findAllFamilyMembers() + findAllSpouseEdges() for derived-event assembly") @enduml