From bd8a20fee0528bcd8dcb11d7b94f93ded898c8c8 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 7 May 2026 22:16:34 +0200 Subject: [PATCH] feat(stats): add totalStories to StatsDTO via GeschichteService.countPublished() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses @Elicit review concern: stories stat tile was permanently showing "—" because StatsDTO had no published-story count. Now wired end-to-end. Co-Authored-By: Claude Sonnet 4.6 --- .../raddatz/familienarchiv/dashboard/StatsDTO.java | 7 ++++++- .../familienarchiv/dashboard/StatsService.java | 4 +++- .../geschichte/GeschichteService.java | 4 ++++ .../dashboard/StatsControllerTest.java | 4 ++-- .../familienarchiv/dashboard/StatsServiceTest.java | 13 +++++++++++++ 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/org/raddatz/familienarchiv/dashboard/StatsDTO.java b/backend/src/main/java/org/raddatz/familienarchiv/dashboard/StatsDTO.java index 37ac36d1..52ff3836 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/dashboard/StatsDTO.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/dashboard/StatsDTO.java @@ -1,7 +1,12 @@ package org.raddatz.familienarchiv.dashboard; +import io.swagger.v3.oas.annotations.media.Schema; + /** * Aggregate counts for the dashboard/persons stats bar. */ -public record StatsDTO(long totalPersons, long totalDocuments) { +public record StatsDTO( + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) long totalPersons, + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) long totalDocuments, + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) long totalStories) { } diff --git a/backend/src/main/java/org/raddatz/familienarchiv/dashboard/StatsService.java b/backend/src/main/java/org/raddatz/familienarchiv/dashboard/StatsService.java index 3c42855c..cac398fe 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/dashboard/StatsService.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/dashboard/StatsService.java @@ -2,6 +2,7 @@ package org.raddatz.familienarchiv.dashboard; import lombok.RequiredArgsConstructor; import org.raddatz.familienarchiv.document.DocumentService; +import org.raddatz.familienarchiv.geschichte.GeschichteService; import org.raddatz.familienarchiv.person.PersonService; import org.raddatz.familienarchiv.dashboard.StatsDTO; import org.springframework.stereotype.Service; @@ -12,8 +13,9 @@ public class StatsService { private final PersonService personService; private final DocumentService documentService; + private final GeschichteService geschichteService; public StatsDTO getStats() { - return new StatsDTO(personService.count(), documentService.count()); + return new StatsDTO(personService.count(), documentService.count(), geschichteService.countPublished()); } } diff --git a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteService.java b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteService.java index 1b0cfc78..53443cf4 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteService.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteService.java @@ -56,6 +56,10 @@ public class GeschichteService { // ─── Read API ──────────────────────────────────────────────────────────── + public long countPublished() { + return geschichteRepository.count(GeschichteSpecifications.hasStatus(GeschichteStatus.PUBLISHED)); + } + public Geschichte getById(UUID id) { Geschichte g = geschichteRepository.findById(id) .orElseThrow(() -> DomainException.notFound( diff --git a/backend/src/test/java/org/raddatz/familienarchiv/dashboard/StatsControllerTest.java b/backend/src/test/java/org/raddatz/familienarchiv/dashboard/StatsControllerTest.java index db18630d..bd6767cc 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/dashboard/StatsControllerTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/dashboard/StatsControllerTest.java @@ -44,7 +44,7 @@ class StatsControllerTest { @Test @WithMockUser(authorities = "READ_ALL") void getStats_returns200_withCorrectCounts() throws Exception { - when(statsService.getStats()).thenReturn(new StatsDTO(4L, 12L)); + when(statsService.getStats()).thenReturn(new StatsDTO(4L, 12L, 2L)); mockMvc.perform(get("/api/stats")) .andExpect(status().isOk()) @@ -55,7 +55,7 @@ class StatsControllerTest { @Test @WithMockUser(authorities = "READ_ALL") void getStats_returns200_withZeroCounts() throws Exception { - when(statsService.getStats()).thenReturn(new StatsDTO(0L, 0L)); + when(statsService.getStats()).thenReturn(new StatsDTO(0L, 0L, 0L)); mockMvc.perform(get("/api/stats")) .andExpect(status().isOk()) diff --git a/backend/src/test/java/org/raddatz/familienarchiv/dashboard/StatsServiceTest.java b/backend/src/test/java/org/raddatz/familienarchiv/dashboard/StatsServiceTest.java index f462f43e..52489515 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/dashboard/StatsServiceTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/dashboard/StatsServiceTest.java @@ -7,6 +7,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.raddatz.familienarchiv.document.DocumentService; import org.raddatz.familienarchiv.dashboard.StatsDTO; +import org.raddatz.familienarchiv.geschichte.GeschichteService; import org.raddatz.familienarchiv.person.PersonService; import static org.assertj.core.api.Assertions.assertThat; @@ -17,6 +18,7 @@ class StatsServiceTest { @Mock PersonService personService; @Mock DocumentService documentService; + @Mock GeschichteService geschichteService; @InjectMocks StatsService statsService; @Test @@ -30,6 +32,17 @@ class StatsServiceTest { assertThat(stats.totalDocuments()).isEqualTo(12L); } + @Test + void getStats_includes_totalStories() { + when(personService.count()).thenReturn(3L); + when(documentService.count()).thenReturn(7L); + when(geschichteService.countPublished()).thenReturn(5L); + + StatsDTO stats = statsService.getStats(); + + assertThat(stats.totalStories()).isEqualTo(5L); + } + @Test void getStats_returnsZero_whenNoEntities() { when(personService.count()).thenReturn(0L);