diff --git a/backend/src/main/java/org/raddatz/familienarchiv/person/PersonRepository.java b/backend/src/main/java/org/raddatz/familienarchiv/person/PersonRepository.java index 6f431b74..1beebcc3 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/person/PersonRepository.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/person/PersonRepository.java @@ -41,7 +41,7 @@ public interface PersonRepository extends JpaRepository { SELECT p.id, p.title, p.first_name AS firstName, p.last_name AS lastName, p.person_type AS personType, p.alias, p.birth_year AS birthYear, p.death_year AS deathYear, p.notes, - p.family_member AS familyMember, + p.family_member AS familyMember, p.provisional AS provisional, (SELECT COUNT(*) FROM documents d WHERE d.sender_id = p.id) + (SELECT COUNT(*) FROM document_receivers dr WHERE dr.person_id = p.id) AS documentCount FROM persons p @@ -54,7 +54,7 @@ public interface PersonRepository extends JpaRepository { SELECT p.id, p.title, p.first_name AS firstName, p.last_name AS lastName, p.person_type AS personType, p.alias, p.birth_year AS birthYear, p.death_year AS deathYear, p.notes, - p.family_member AS familyMember, + p.family_member AS familyMember, p.provisional AS provisional, (SELECT COUNT(*) FROM documents d WHERE d.sender_id = p.id) + (SELECT COUNT(*) FROM document_receivers dr WHERE dr.person_id = p.id) AS documentCount FROM persons p @@ -63,7 +63,7 @@ public interface PersonRepository extends JpaRepository { OR LOWER(CONCAT(p.last_name,' ',COALESCE(p.first_name,''))) LIKE LOWER(CONCAT('%',:query,'%')) OR LOWER(p.alias) LIKE LOWER(CONCAT('%',:query,'%')) OR LOWER(a.last_name) LIKE LOWER(CONCAT('%',:query,'%')) - GROUP BY p.id, p.title, p.first_name, p.last_name, p.person_type, p.alias, p.birth_year, p.death_year, p.notes, p.family_member + GROUP BY p.id, p.title, p.first_name, p.last_name, p.person_type, p.alias, p.birth_year, p.death_year, p.notes, p.family_member, p.provisional ORDER BY p.last_name ASC, p.first_name ASC """, nativeQuery = true) @@ -75,7 +75,7 @@ public interface PersonRepository extends JpaRepository { SELECT p.id, p.title, p.first_name AS firstName, p.last_name AS lastName, p.person_type AS personType, p.alias, p.birth_year AS birthYear, p.death_year AS deathYear, p.notes, - p.family_member AS familyMember, + p.family_member AS familyMember, p.provisional AS provisional, (SELECT COUNT(*) FROM documents d WHERE d.sender_id = p.id) + (SELECT COUNT(*) FROM document_receivers dr WHERE dr.person_id = p.id) AS documentCount FROM persons p diff --git a/backend/src/main/java/org/raddatz/familienarchiv/person/PersonSummaryDTO.java b/backend/src/main/java/org/raddatz/familienarchiv/person/PersonSummaryDTO.java index 68cbbe1b..9a92d257 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/person/PersonSummaryDTO.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/person/PersonSummaryDTO.java @@ -18,6 +18,7 @@ public interface PersonSummaryDTO { Integer getDeathYear(); String getNotes(); boolean isFamilyMember(); + boolean isProvisional(); long getDocumentCount(); default String getDisplayName() { diff --git a/backend/src/test/java/org/raddatz/familienarchiv/person/PersonControllerTest.java b/backend/src/test/java/org/raddatz/familienarchiv/person/PersonControllerTest.java index e7767411..2dee3baa 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/person/PersonControllerTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/person/PersonControllerTest.java @@ -117,6 +117,7 @@ class PersonControllerTest { public Integer getDeathYear() { return null; } public String getNotes() { return null; } public boolean isFamilyMember() { return false; } + public boolean isProvisional() { return false; } public long getDocumentCount() { return 0; } }; } diff --git a/backend/src/test/java/org/raddatz/familienarchiv/person/PersonRepositoryTest.java b/backend/src/test/java/org/raddatz/familienarchiv/person/PersonRepositoryTest.java index 8ccf27ba..2de9f69f 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/person/PersonRepositoryTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/person/PersonRepositoryTest.java @@ -463,4 +463,46 @@ class PersonRepositoryTest { assertThat(result).hasSize(1); assertThat(result.get(0).getLastName()).isEqualTo("Gesellschafter des Verlages"); } + + // ─── #671: provisional must be SELECTed in all three native projections ─── + // Adding isProvisional() to the interface compiles even if a native query forgets + // to SELECT p.provisional — it then silently returns false. These tests are the only + // guard against that trap, so they must run against real Postgres. + + @Test + void findAllWithDocumentCount_projectsProvisionalTrue() { + personRepository.save(Person.builder() + .firstName("Inferred").lastName("Person").provisional(true).build()); + + List result = personRepository.findAllWithDocumentCount(); + + assertThat(result).anyMatch(PersonSummaryDTO::isProvisional); + } + + @Test + void searchWithDocumentCount_projectsProvisionalTrue() { + personRepository.save(Person.builder() + .firstName("Provisorisch").lastName("Müller").provisional(true).build()); + + List result = personRepository.searchWithDocumentCount("Provisorisch"); + + assertThat(result).hasSize(1); + assertThat(result.get(0).isProvisional()).isTrue(); + } + + @Test + void findTopByDocumentCount_projectsProvisionalTrue() { + Person provisional = personRepository.save(Person.builder() + .firstName("Top").lastName("Provisional").provisional(true).build()); + documentRepository.save(Document.builder() + .title("Brief").originalFilename("b.pdf") + .status(DocumentStatus.UPLOADED) + .sender(provisional).build()); + + List result = personRepository.findTopByDocumentCount(10); + + PersonSummaryDTO summary = result.stream() + .filter(p -> p.getId().equals(provisional.getId())).findFirst().orElseThrow(); + assertThat(summary.isProvisional()).isTrue(); + } }