feat(#145): add IncompleteDocumentDTO and ?size= param to GET /api/documents/incomplete

Dashboard widget calls ?size=3 to cap the list. Response now returns
{id, title} DTO instead of full Document entity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-03-29 00:19:06 +01:00
parent 304359f67d
commit 968993c48e
7 changed files with 108 additions and 13 deletions

View File

@@ -13,6 +13,7 @@ import java.util.UUID;
import org.raddatz.familienarchiv.dto.DocumentUpdateDTO;
import org.raddatz.familienarchiv.dto.DocumentVersionSummary;
import org.raddatz.familienarchiv.dto.IncompleteDocumentDTO;
import org.raddatz.familienarchiv.exception.DomainException;
import org.raddatz.familienarchiv.exception.ErrorCode;
import org.raddatz.familienarchiv.model.Document;
@@ -164,8 +165,9 @@ public class DocumentController {
}
@GetMapping("/incomplete")
public List<Document> getIncomplete() {
return documentService.findIncompleteDocuments();
public List<IncompleteDocumentDTO> getIncomplete(
@RequestParam(defaultValue = "10") int size) {
return documentService.findIncompleteDocuments(size);
}
@GetMapping("/incomplete/next")

View File

@@ -0,0 +1,10 @@
package org.raddatz.familienarchiv.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.UUID;
public record IncompleteDocumentDTO(
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) UUID id,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) String title
) {}

View File

@@ -2,6 +2,8 @@ package org.raddatz.familienarchiv.repository;
import org.raddatz.familienarchiv.model.Document;
import org.raddatz.familienarchiv.model.DocumentStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
@@ -46,6 +48,8 @@ public interface DocumentRepository extends JpaRepository<Document, UUID>, JpaSp
List<Document> findByMetadataCompleteFalse(Sort sort);
Page<Document> findByMetadataCompleteFalse(Pageable pageable);
Optional<Document> findFirstByMetadataCompleteFalseAndIdNot(UUID id, Sort sort);
@Query("SELECT DISTINCT d FROM Document d " +

View File

@@ -4,11 +4,13 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.raddatz.familienarchiv.dto.DocumentUpdateDTO;
import org.raddatz.familienarchiv.dto.IncompleteDocumentDTO;
import org.raddatz.familienarchiv.model.Document;
import org.raddatz.familienarchiv.model.DocumentStatus;
import org.raddatz.familienarchiv.model.Person;
import org.raddatz.familienarchiv.model.Tag;
import org.raddatz.familienarchiv.repository.DocumentRepository;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.raddatz.familienarchiv.exception.DomainException;
@@ -313,8 +315,12 @@ public class DocumentService {
return documentRepository.countByMetadataCompleteFalse();
}
public List<Document> findIncompleteDocuments() {
return documentRepository.findByMetadataCompleteFalse(Sort.by(Sort.Direction.DESC, "createdAt"));
public List<IncompleteDocumentDTO> findIncompleteDocuments(int size) {
PageRequest pageable = PageRequest.of(0, size, Sort.by(Sort.Direction.DESC, "createdAt"));
return documentRepository.findByMetadataCompleteFalse(pageable)
.stream()
.map(doc -> new IncompleteDocumentDTO(doc.getId(), doc.getTitle()))
.toList();
}
public Optional<Document> findNextIncompleteDocument(UUID currentId) {