From 1eb833f333cf10eb94c4f78a503df2a32a76f830 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 24 Apr 2026 20:28:12 +0200 Subject: [PATCH] refactor(documents): change DocumentBatchMetadataDTO.tags from String to List tagNames MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces comma-delimited String with a proper JSON array field — callers no longer need to pre-serialise. Service drops the split/trim/filter step and passes tagNames directly to updateDocumentTags(). Co-Authored-By: Claude Sonnet 4.6 --- .../dto/DocumentBatchMetadataDTO.java | 2 +- .../service/DocumentService.java | 6 ++--- .../controller/DocumentControllerTest.java | 24 +++++++++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/org/raddatz/familienarchiv/dto/DocumentBatchMetadataDTO.java b/backend/src/main/java/org/raddatz/familienarchiv/dto/DocumentBatchMetadataDTO.java index 93e17fbf..399105d9 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/dto/DocumentBatchMetadataDTO.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/dto/DocumentBatchMetadataDTO.java @@ -13,6 +13,6 @@ public class DocumentBatchMetadataDTO { private List receiverIds; private LocalDate documentDate; private String location; - private String tags; + private List tagNames; private Boolean metadataComplete; } diff --git a/backend/src/main/java/org/raddatz/familienarchiv/service/DocumentService.java b/backend/src/main/java/org/raddatz/familienarchiv/service/DocumentService.java index 01ea544d..dac82517 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/service/DocumentService.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/service/DocumentService.java @@ -166,11 +166,9 @@ public class DocumentService { if (metadata.getMetadataComplete() != null) { doc.setMetadataComplete(metadata.getMetadataComplete()); } - if (metadata.getTags() != null && !metadata.getTags().isBlank()) { - List tagNames = Arrays.stream(metadata.getTags().split(",")) - .map(String::trim).filter(s -> !s.isEmpty()).toList(); + if (metadata.getTagNames() != null && !metadata.getTagNames().isEmpty()) { UUID docId = doc.getId(); - updateDocumentTags(docId, tagNames); + updateDocumentTags(docId, metadata.getTagNames()); doc = documentRepository.findById(docId) .orElseThrow(() -> DomainException.notFound(ErrorCode.DOCUMENT_NOT_FOUND, "Not found after batch metadata: " + docId)); } diff --git a/backend/src/test/java/org/raddatz/familienarchiv/controller/DocumentControllerTest.java b/backend/src/test/java/org/raddatz/familienarchiv/controller/DocumentControllerTest.java index 828e8402..b80ed173 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/controller/DocumentControllerTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/controller/DocumentControllerTest.java @@ -886,6 +886,30 @@ class DocumentControllerTest { .andExpect(status().isBadRequest()); } + @Test + @WithMockUser(authorities = "WRITE_ALL") + void quickUpload_withMetadata_tagNamesJsonArray_parsedCorrectly() throws Exception { + Document doc = Document.builder().id(UUID.randomUUID()).title("brief").originalFilename("brief.pdf").build(); + when(userService.findByEmail(any())).thenReturn(AppUser.builder().id(UUID.randomUUID()).build()); + + org.mockito.ArgumentCaptor captor = + org.mockito.ArgumentCaptor.forClass(DocumentBatchMetadataDTO.class); + when(documentService.storeDocumentWithBatchMetadata(any(), captor.capture(), anyInt(), any())) + .thenReturn(new DocumentService.StoreResult(doc, true)); + + org.springframework.mock.web.MockMultipartFile file = + new org.springframework.mock.web.MockMultipartFile("files", "brief.pdf", "application/pdf", new byte[]{1}); + org.springframework.mock.web.MockMultipartFile metadata = + new org.springframework.mock.web.MockMultipartFile("metadata", "metadata", "application/json", + "{\"tagNames\":[\"Briefwechsel\",\"Krieg\"]}".getBytes()); + + mockMvc.perform(multipart("/api/documents/quick-upload").file(file).file(metadata)) + .andExpect(status().isOk()); + + org.assertj.core.api.Assertions.assertThat(captor.getValue().getTagNames()) + .containsExactly("Briefwechsel", "Krieg"); + } + @Test @WithMockUser(authorities = "WRITE_ALL") void quickUpload_returns400_whenBatchExceedsCap() throws Exception {