fix(dashboard): bulk-load document titles in getActivity to avoid N+1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -124,12 +124,11 @@ public class DashboardService {
|
||||
.toList();
|
||||
|
||||
Map<UUID, String> titleCache = new HashMap<>();
|
||||
for (UUID docId : docIds) {
|
||||
try {
|
||||
titleCache.put(docId, documentService.getDocumentById(docId).getTitle());
|
||||
} catch (Exception e) {
|
||||
titleCache.put(docId, "");
|
||||
}
|
||||
try {
|
||||
documentService.getDocumentsByIds(docIds)
|
||||
.forEach(d -> titleCache.put(d.getId(), d.getTitle()));
|
||||
} catch (Exception e) {
|
||||
log.warn("Activity: failed to bulk-load document titles", e);
|
||||
}
|
||||
|
||||
return rows.stream().map(row -> {
|
||||
|
||||
@@ -484,6 +484,10 @@ public class DocumentService {
|
||||
return doc;
|
||||
}
|
||||
|
||||
public List<Document> getDocumentsByIds(List<UUID> ids) {
|
||||
return documentRepository.findAllById(ids);
|
||||
}
|
||||
|
||||
public List<Document> getDocumentsWithoutVersions() {
|
||||
return documentRepository.findDocumentsWithoutVersions();
|
||||
}
|
||||
|
||||
@@ -12,13 +12,16 @@ import org.raddatz.familienarchiv.service.DocumentService;
|
||||
import org.raddatz.familienarchiv.service.TranscriptionService;
|
||||
import org.raddatz.familienarchiv.service.UserService;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.Instant;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@@ -65,4 +68,40 @@ class DashboardServiceTest {
|
||||
assertThat(result.collaborators()).hasSize(1);
|
||||
assertThat(result.collaborators().get(0).name()).isEqualTo("Schmidt");
|
||||
}
|
||||
|
||||
// ─── getActivity bulk-load ────────────────────────────────────────────────
|
||||
|
||||
@Test
|
||||
void getActivity_loadsDocumentTitles_withoutPerRowLookup() {
|
||||
UUID userId = UUID.randomUUID();
|
||||
UUID docId = UUID.randomUUID();
|
||||
|
||||
ActivityFeedRow row = mockFeedRow(docId, "ANNOTATION_CREATED");
|
||||
when(auditLogQueryService.findActivityFeed(userId, 5)).thenReturn(List.of(row, row));
|
||||
|
||||
Document doc = Document.builder()
|
||||
.id(docId).title("Familienbrief").originalFilename("f.pdf")
|
||||
.receivers(new HashSet<>())
|
||||
.build();
|
||||
when(documentService.getDocumentsByIds(List.of(docId))).thenReturn(List.of(doc));
|
||||
|
||||
List<ActivityFeedItemDTO> items = dashboardService.getActivity(userId, 5);
|
||||
|
||||
assertThat(items).hasSize(2);
|
||||
assertThat(items.get(0).documentTitle()).isEqualTo("Familienbrief");
|
||||
verify(documentService, never()).getDocumentById(docId);
|
||||
}
|
||||
|
||||
private ActivityFeedRow mockFeedRow(UUID docId, String kind) {
|
||||
return new ActivityFeedRow() {
|
||||
public String getKind() { return kind; }
|
||||
public UUID getActorId() { return null; }
|
||||
public String getActorInitials() { return ""; }
|
||||
public String getActorColor() { return ""; }
|
||||
public String getActorName() { return ""; }
|
||||
public UUID getDocumentId() { return docId; }
|
||||
public Instant getHappenedAt() { return Instant.now(); }
|
||||
public boolean isYouMentioned() { return false; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user