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 c502a0db..b04e39f6 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/audit/AuditLogQueryRepository.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/audit/AuditLogQueryRepository.java @@ -197,4 +197,8 @@ public interface AuditLogQueryRepository extends JpaRepository { ORDER BY ranked.document_id, ranked.rn """, 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); } 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 192795bc..5073b748 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/audit/AuditLogQueryService.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/audit/AuditLogQueryService.java @@ -6,6 +6,10 @@ import org.springframework.stereotype.Service; import java.time.OffsetDateTime; import java.util.*; +import static org.raddatz.familienarchiv.audit.AuditKind.GROUP_MEMBERSHIP_CHANGED; +import static org.raddatz.familienarchiv.audit.AuditKind.USER_CREATED; +import static org.raddatz.familienarchiv.audit.AuditKind.USER_DELETED; + @Service @RequiredArgsConstructor public class AuditLogQueryService { @@ -51,6 +55,10 @@ public class AuditLogQueryService { return toContributorMap(queryRepository.findRecentContributorsForDocuments(documentIds)); } + public List findRecentUserManagementEvents(int limit) { + return queryRepository.findRecentByKinds(Set.of(USER_CREATED, USER_DELETED, GROUP_MEMBERSHIP_CHANGED), limit); + } + private Map> toContributorMap(List rows) { Map> result = new LinkedHashMap<>(); for (ContributorRow row : 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 4c469deb..356c5ded 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/audit/AuditLogQueryServiceTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/audit/AuditLogQueryServiceTest.java @@ -6,12 +6,17 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.raddatz.familienarchiv.model.AppUser; + +import java.util.Collection; import java.util.List; import java.util.Set; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; 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; import static org.mockito.Mockito.when; @@ -47,4 +52,20 @@ class AuditLogQueryServiceTest { verify(queryRepository).findRolledUpActivityFeed(eq(userId.toString()), eq(10), eq(AuditKind.ROLLUP_ELIGIBLE.stream().map(Enum::name).toList())); } + + @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)); + + List result = auditLogQueryService.findRecentUserManagementEvents(5); + + assertThat(result).containsExactly(entry); + verify(queryRepository).findRecentByKinds( + argThat((Collection kinds) -> + kinds.contains(AuditKind.USER_CREATED) && + kinds.contains(AuditKind.USER_DELETED) && + kinds.contains(AuditKind.GROUP_MEMBERSHIP_CHANGED)), + eq(5)); + } }