feat(#248): enrich TagTreeNodeDTO with parentId and populate documentCount via single aggregate query
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,4 +3,4 @@ package org.raddatz.familienarchiv.dto;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public record TagTreeNodeDTO(UUID id, String name, String color, int documentCount, List<TagTreeNodeDTO> children) {}
|
||||
public record TagTreeNodeDTO(UUID id, String name, String color, int documentCount, List<TagTreeNodeDTO> children, UUID parentId) {}
|
||||
|
||||
@@ -141,12 +141,17 @@ public class TagService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all tags assembled into a tree. Document counts are not included here
|
||||
* (they are populated by the controller layer if needed, or set to 0).
|
||||
* Returns all tags assembled into a tree with document counts per node.
|
||||
* Uses a single aggregate query to avoid N+1 behaviour.
|
||||
*/
|
||||
public List<TagTreeNodeDTO> getTagTree() {
|
||||
List<Tag> all = tagRepository.findAll();
|
||||
return buildTree(all);
|
||||
Map<UUID, Long> counts = tagRepository.findDocumentCountsPerTag().stream()
|
||||
.collect(Collectors.toMap(
|
||||
row -> (UUID) row[0],
|
||||
row -> (Long) row[1]
|
||||
));
|
||||
return buildTree(all, counts);
|
||||
}
|
||||
|
||||
// ─── private helpers ─────────────────────────────────────────────────────
|
||||
@@ -195,7 +200,7 @@ public class TagService {
|
||||
}
|
||||
}
|
||||
|
||||
private List<TagTreeNodeDTO> buildTree(List<Tag> tags) {
|
||||
private List<TagTreeNodeDTO> buildTree(List<Tag> tags, Map<UUID, Long> counts) {
|
||||
Map<UUID, List<TagTreeNodeDTO>> childrenByParent = new HashMap<>();
|
||||
|
||||
for (Tag tag : tags) {
|
||||
@@ -206,14 +211,14 @@ public class TagService {
|
||||
}
|
||||
|
||||
for (Tag tag : tags) {
|
||||
int documentCount = counts.getOrDefault(tag.getId(), 0L).intValue();
|
||||
TagTreeNodeDTO node = new TagTreeNodeDTO(
|
||||
tag.getId(), tag.getName(), tag.getColor(), 0,
|
||||
childrenByParent.getOrDefault(tag.getId(), new ArrayList<>())
|
||||
tag.getId(), tag.getName(), tag.getColor(), documentCount,
|
||||
childrenByParent.getOrDefault(tag.getId(), new ArrayList<>()),
|
||||
tag.getParentId()
|
||||
);
|
||||
if (tag.getParentId() != null) {
|
||||
childrenByParent.get(tag.getParentId()).add(node);
|
||||
} else {
|
||||
childrenByParent.get(tag.getId()); // ensure root is tracked
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,9 +226,11 @@ public class TagService {
|
||||
List<TagTreeNodeDTO> roots = new ArrayList<>();
|
||||
for (Tag tag : tags) {
|
||||
if (tag.getParentId() == null) {
|
||||
int documentCount = counts.getOrDefault(tag.getId(), 0L).intValue();
|
||||
roots.add(new TagTreeNodeDTO(
|
||||
tag.getId(), tag.getName(), tag.getColor(), 0,
|
||||
childrenByParent.getOrDefault(tag.getId(), new ArrayList<>())
|
||||
tag.getId(), tag.getName(), tag.getColor(), documentCount,
|
||||
childrenByParent.getOrDefault(tag.getId(), new ArrayList<>()),
|
||||
null
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user