From 282c819e2ae2b73720ca1afe80fc28caccae927e Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 10 Jun 2026 00:01:09 +0200 Subject: [PATCH] feat(geschichte): carry updatedAt in GeschichteSummary projection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reader dashboard renders 'bearbeitet vor X' from updatedAt, but the summary projection dropped the field when the list endpoint moved off the entity — drafts have no publishedAt to fall back on. Co-Authored-By: Claude Fable 5 --- .../geschichte/GeschichteRepository.java | 2 +- .../geschichte/GeschichteSummary.java | 4 ++++ .../geschichte/GeschichteControllerTest.java | 1 + .../geschichte/GeschichteListProjectionTest.java | 13 +++++++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteRepository.java b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteRepository.java index 98c4bf13..6fe40a8e 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteRepository.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteRepository.java @@ -25,7 +25,7 @@ public interface GeschichteRepository extends JpaRepository, J */ @Query(""" SELECT g.id AS id, g.title AS title, g.status AS status, g.type AS type, - g.author AS author, g.publishedAt AS publishedAt, g.body AS body + g.author AS author, g.publishedAt AS publishedAt, g.updatedAt AS updatedAt, g.body AS body FROM Geschichte g WHERE g.status = :effectiveStatus AND (:authorId IS NULL OR g.author.id = :authorId) diff --git a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteSummary.java b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteSummary.java index ae9d0de7..e4bf9453 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteSummary.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteSummary.java @@ -31,6 +31,10 @@ public interface GeschichteSummary { LocalDateTime getPublishedAt(); + /** Always set (@UpdateTimestamp) — drives "bearbeitet vor X" on dashboard cards. */ + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + LocalDateTime getUpdatedAt(); + String getBody(); interface AuthorSummary { diff --git a/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteControllerTest.java b/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteControllerTest.java index 8a139e49..caf1a515 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteControllerTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteControllerTest.java @@ -401,6 +401,7 @@ class GeschichteControllerTest { public GeschichteType getType() { return GeschichteType.STORY; } public AuthorSummary getAuthor() { return null; } public LocalDateTime getPublishedAt() { return LocalDateTime.now(); } + public LocalDateTime getUpdatedAt() { return LocalDateTime.now(); } public String getBody() { return null; } }; } diff --git a/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteListProjectionTest.java b/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteListProjectionTest.java index ff2dc68d..3ab95cc1 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteListProjectionTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteListProjectionTest.java @@ -61,6 +61,19 @@ class GeschichteListProjectionTest { assertThat(result.get(0).getTitle()).isEqualTo("Veröffentlicht"); } + @Test + void findSummaries_carries_updatedAt_for_dashboard_relative_times() { + // ReaderDraftsModule renders "bearbeitet vor X" from updatedAt — the + // projection must carry it for drafts, where publishedAt is null. + geschichteRepository.save(draft("Mein Entwurf", author)); + + List result = geschichteRepository.findSummaries( + GeschichteStatus.DRAFT, author.getId(), sentinel(), 0, null); + + assertThat(result).hasSize(1); + assertThat(result.get(0).getUpdatedAt()).isNotNull(); + } + @Test void findSummaries_returns_empty_list_when_no_published_geschichten_exist() { geschichteRepository.save(draft("Nur Entwurf", author));