feat(timeline): add PersonService.getPersonsByGeneration + DocumentService.getAllForTimeline
PersonRepository.findByGeneration(Integer) — boxed to match nullable entity field. DocumentRepository.findAllForTimeline() — Document.list entity-graph, single query. Both services delegate with one-liner methods. Refs #777 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -56,6 +56,11 @@ public interface DocumentRepository extends JpaRepository<Document, UUID>, JpaSp
|
|||||||
// Prüft effizient, ob ein Dateiname schon existiert (gibt true/false zurück)
|
// Prüft effizient, ob ein Dateiname schon existiert (gibt true/false zurück)
|
||||||
boolean existsByOriginalFilename(String originalFilename);
|
boolean existsByOriginalFilename(String originalFilename);
|
||||||
|
|
||||||
|
// Bulk-fetch for global timeline path — single query with sender+receivers eager-loaded.
|
||||||
|
@EntityGraph("Document.list")
|
||||||
|
@Query("SELECT d FROM Document d")
|
||||||
|
List<Document> findAllForTimeline();
|
||||||
|
|
||||||
// lazy – @BatchSize(50) fallback active; see ADR-022
|
// lazy – @BatchSize(50) fallback active; see ADR-022
|
||||||
@EntityGraph("Document.full")
|
@EntityGraph("Document.full")
|
||||||
List<Document> findBySenderId(UUID senderId);
|
List<Document> findBySenderId(UUID senderId);
|
||||||
|
|||||||
@@ -1051,6 +1051,10 @@ public class DocumentService {
|
|||||||
return documentRepository.findDocumentsWithoutVersions();
|
return documentRepository.findDocumentsWithoutVersions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Document> getAllForTimeline() {
|
||||||
|
return documentRepository.findAllForTimeline();
|
||||||
|
}
|
||||||
|
|
||||||
public List<Document> getDocumentsBySender(UUID senderId) {
|
public List<Document> getDocumentsBySender(UUID senderId) {
|
||||||
return documentRepository.findBySenderId(senderId);
|
return documentRepository.findBySenderId(senderId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,4 +242,7 @@ public interface PersonRepository extends JpaRepository<Person, UUID> {
|
|||||||
)
|
)
|
||||||
""", nativeQuery = true)
|
""", nativeQuery = true)
|
||||||
void insertMissingReceiverReference(@Param("source") UUID source, @Param("target") UUID target);
|
void insertMissingReceiverReference(@Param("source") UUID source, @Param("target") UUID target);
|
||||||
|
|
||||||
|
// Boxed Integer — matches the nullable person.generation column (primitive int would reject null rows).
|
||||||
|
List<Person> findByGeneration(Integer generation);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,6 +210,10 @@ public class PersonService {
|
|||||||
return personRepository.findByFamilyMemberTrueOrderByLastNameAscFirstNameAsc();
|
return personRepository.findByFamilyMemberTrueOrderByLastNameAscFirstNameAsc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Person> getPersonsByGeneration(Integer generation) {
|
||||||
|
return personRepository.findByGeneration(generation);
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public Person setFamilyMember(UUID personId, boolean familyMember) {
|
public Person setFamilyMember(UUID personId, boolean familyMember) {
|
||||||
Person person = getById(personId);
|
Person person = getById(personId);
|
||||||
|
|||||||
@@ -2943,4 +2943,17 @@ class DocumentServiceTest {
|
|||||||
assertThat(result.buckets()).isEmpty();
|
assertThat(result.buckets()).isEmpty();
|
||||||
verify(documentRepository, org.mockito.Mockito.never()).findAll(any(Specification.class));
|
verify(documentRepository, org.mockito.Mockito.never()).findAll(any(Specification.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- getAllForTimeline ---
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getAllForTimeline_delegates_bulk_fetch_to_repository() {
|
||||||
|
Document doc = Document.builder().id(UUID.randomUUID()).title("Brief").build();
|
||||||
|
when(documentRepository.findAllForTimeline()).thenReturn(List.of(doc));
|
||||||
|
|
||||||
|
List<Document> result = documentService.getAllForTimeline();
|
||||||
|
|
||||||
|
assertThat(result).containsExactly(doc);
|
||||||
|
verify(documentRepository).findAllForTimeline();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1105,4 +1105,25 @@ class PersonServiceTest {
|
|||||||
assertThat(result.direct()).hasSize(1);
|
assertThat(result.direct()).hasSize(1);
|
||||||
assertThat(result.partial()).isEmpty();
|
assertThat(result.partial()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- getPersonsByGeneration ---
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getPersonsByGeneration_delegates_to_repository() {
|
||||||
|
Person p = Person.builder().id(UUID.randomUUID()).lastName("Müller").generation(2).build();
|
||||||
|
when(personRepository.findByGeneration(2)).thenReturn(List.of(p));
|
||||||
|
|
||||||
|
List<Person> result = personService.getPersonsByGeneration(2);
|
||||||
|
|
||||||
|
assertThat(result).containsExactly(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getPersonsByGeneration_returns_emptyList_when_no_match() {
|
||||||
|
when(personRepository.findByGeneration(99)).thenReturn(List.of());
|
||||||
|
|
||||||
|
List<Person> result = personService.getPersonsByGeneration(99);
|
||||||
|
|
||||||
|
assertThat(result).isEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user