From 11d93919b2d9d9f2d1440e88f163131ba2cbe0d2 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 26 Apr 2026 15:40:53 +0200 Subject: [PATCH] refactor(audit): replace LIMIT :limit JPQL with Pageable in audit query Co-Authored-By: Claude Sonnet 4.6 --- .../familienarchiv/audit/AuditLogQueryRepository.java | 6 +++--- .../familienarchiv/audit/AuditLogQueryService.java | 5 ++++- .../audit/AuditLogQueryServiceTest.java | 11 +++++++---- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/backend/src/main/java/org/raddatz/familienarchiv/audit/AuditLogQueryRepository.java b/backend/src/main/java/org/raddatz/familienarchiv/audit/AuditLogQueryRepository.java index b04e39f6..8984d465 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/audit/AuditLogQueryRepository.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/audit/AuditLogQueryRepository.java @@ -1,5 +1,7 @@ package org.raddatz.familienarchiv.audit; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -198,7 +200,5 @@ public interface AuditLogQueryRepository extends JpaRepository { """, nativeQuery = true) List findRecentContributorsForDocuments(@Param("documentIds") List documentIds); - @Query("SELECT a FROM AuditLog a WHERE a.kind IN :kinds ORDER BY a.happenedAt DESC LIMIT :limit") - List findRecentByKinds(@Param("kinds") Collection kinds, - @Param("limit") int limit); + Page findByKindIn(Collection kinds, Pageable pageable); } diff --git a/backend/src/main/java/org/raddatz/familienarchiv/audit/AuditLogQueryService.java b/backend/src/main/java/org/raddatz/familienarchiv/audit/AuditLogQueryService.java index 5073b748..f1fcb5b1 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/audit/AuditLogQueryService.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/audit/AuditLogQueryService.java @@ -1,6 +1,8 @@ package org.raddatz.familienarchiv.audit; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import java.time.OffsetDateTime; @@ -56,7 +58,8 @@ public class AuditLogQueryService { } public List findRecentUserManagementEvents(int limit) { - return queryRepository.findRecentByKinds(Set.of(USER_CREATED, USER_DELETED, GROUP_MEMBERSHIP_CHANGED), limit); + PageRequest page = PageRequest.of(0, limit, Sort.by("happenedAt").descending()); + return queryRepository.findByKindIn(Set.of(USER_CREATED, USER_DELETED, GROUP_MEMBERSHIP_CHANGED), page).getContent(); } private Map> toContributorMap(List rows) { diff --git a/backend/src/test/java/org/raddatz/familienarchiv/audit/AuditLogQueryServiceTest.java b/backend/src/test/java/org/raddatz/familienarchiv/audit/AuditLogQueryServiceTest.java index 356c5ded..c7e78a3c 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/audit/AuditLogQueryServiceTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/audit/AuditLogQueryServiceTest.java @@ -7,6 +7,8 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.raddatz.familienarchiv.model.AppUser; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import java.util.Collection; import java.util.List; @@ -14,8 +16,8 @@ import java.util.Set; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyCollection; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; @@ -56,16 +58,17 @@ class AuditLogQueryServiceTest { @Test void findRecentUserManagementEvents_delegatesToRepositoryWithAllThreeKinds() { AuditLog entry = AuditLog.builder().id(UUID.randomUUID()).kind(AuditKind.USER_CREATED).build(); - when(queryRepository.findRecentByKinds(anyCollection(), eq(5))).thenReturn(List.of(entry)); + when(queryRepository.findByKindIn(anyCollection(), any(Pageable.class))) + .thenReturn(new PageImpl<>(List.of(entry))); List result = auditLogQueryService.findRecentUserManagementEvents(5); assertThat(result).containsExactly(entry); - verify(queryRepository).findRecentByKinds( + verify(queryRepository).findByKindIn( argThat((Collection kinds) -> kinds.contains(AuditKind.USER_CREATED) && kinds.contains(AuditKind.USER_DELETED) && kinds.contains(AuditKind.GROUP_MEMBERSHIP_CHANGED)), - eq(5)); + any(Pageable.class)); } }