diff --git a/backend/src/main/java/org/raddatz/familienarchiv/dashboard/DashboardController.java b/backend/src/main/java/org/raddatz/familienarchiv/dashboard/DashboardController.java index 1869c2f4..b7b34b7e 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/dashboard/DashboardController.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/dashboard/DashboardController.java @@ -37,6 +37,6 @@ public class DashboardController { Authentication authentication, @RequestParam(defaultValue = "7") int limit) { UUID userId = SecurityUtils.requireUserId(authentication, userService); - return dashboardService.getActivity(userId, Math.min(limit, 20)); + return dashboardService.getActivity(userId, Math.min(limit, 40)); } } diff --git a/backend/src/main/resources/db/migration/V49__add_audit_log_rollup_index.sql b/backend/src/main/resources/db/migration/V49__add_audit_log_rollup_index.sql new file mode 100644 index 00000000..7327df6a --- /dev/null +++ b/backend/src/main/resources/db/migration/V49__add_audit_log_rollup_index.sql @@ -0,0 +1,7 @@ +-- Partial covering index for the session-style activity feed rollup (#285). +-- Matches the WHERE clause of AuditLogQueryRepository.findRolledUpActivityFeed +-- exactly. DESC on happened_at supports the outer ORDER BY without a sort step. +CREATE INDEX idx_audit_log_rollup + ON audit_log (actor_id, document_id, kind, happened_at DESC) + WHERE kind IN ('TEXT_SAVED','FILE_UPLOADED','ANNOTATION_CREATED', + 'BLOCK_REVIEWED','COMMENT_ADDED','MENTION_CREATED'); diff --git a/backend/src/test/java/org/raddatz/familienarchiv/dashboard/DashboardControllerTest.java b/backend/src/test/java/org/raddatz/familienarchiv/dashboard/DashboardControllerTest.java index 0f1e4922..1bfc37ce 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/dashboard/DashboardControllerTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/dashboard/DashboardControllerTest.java @@ -140,4 +140,18 @@ class DashboardControllerTest { .andExpect(status().isOk()) .andExpect(jsonPath("$").isArray()); } + + @Test + @WithMockUser(authorities = "READ_ALL") + void activity_clamps_limit_to_40() throws Exception { + UUID userId = UUID.randomUUID(); + when(userService.findByEmail(any())).thenReturn( + AppUser.builder().id(userId).email("u@test.com").password("pw").build()); + when(dashboardService.getActivity(any(UUID.class), anyInt())).thenReturn(List.of()); + + mockMvc.perform(get("/api/dashboard/activity").param("limit", "9999")) + .andExpect(status().isOk()); + + org.mockito.Mockito.verify(dashboardService).getActivity(any(UUID.class), org.mockito.ArgumentMatchers.eq(40)); + } }