From f75a9601796b07e19c22ba2ef29dab2b68d23acc Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 24 Apr 2026 21:12:02 +0200 Subject: [PATCH] fix(bulk-upload): include tagNames in quick-upload metadata payload Tags were silently dropped because the metadata object built in save() never included a tagNames field; they never reached the backend. Co-Authored-By: Claude Sonnet 4.6 --- .../document/BulkDocumentEditLayout.svelte | 3 ++- .../BulkDocumentEditLayout.svelte.spec.ts | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte b/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte index fa0e729e..594a9245 100644 --- a/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte +++ b/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte @@ -100,7 +100,8 @@ async function save() { titles: chunk.map((e) => e.title), senderId: senderId || null, receiverIds: selectedReceivers.map((r) => r.id), - documentDate: dateIso || null + documentDate: dateIso || null, + tagNames: tags.map((t) => t.name) }; formData.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' })); const res = await fetch('/api/documents/quick-upload', { method: 'POST', body: formData }); diff --git a/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte.spec.ts b/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte.spec.ts index 7195c3e3..e61bec16 100644 --- a/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte.spec.ts +++ b/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte.spec.ts @@ -116,6 +116,30 @@ describe('BulkDocumentEditLayout', () => { await vi.waitFor(() => expect(mockFetch).toHaveBeenCalledTimes(1), { timeout: 3000 }); }); + it('save() includes tagNames in metadata payload', async () => { + let capturedFormData: FormData | undefined; + const mockFetch = vi.fn().mockImplementation(async (_url: string, init: RequestInit) => { + capturedFormData = init?.body as FormData; + return { ok: true, json: async () => ({ created: [], updated: [], errors: [] }) }; + }); + vi.stubGlobal('fetch', mockFetch); + + const { container } = render(BulkDocumentEditLayout, {}); + await addFilesViaInput(container, [makeFile('doc.pdf')]); + + const saveBtn = container.querySelector( + 'button[data-testid="bulk-save-btn"]' + ) as HTMLButtonElement; + saveBtn.click(); + + await vi.waitFor(() => expect(mockFetch).toHaveBeenCalledTimes(1), { timeout: 3000 }); + + expect(capturedFormData).toBeDefined(); + const metadataBlob = capturedFormData!.get('metadata') as Blob; + const metadataJson = JSON.parse(await metadataBlob.text()); + expect(metadataJson).toHaveProperty('tagNames'); + }); + it('discard-all resets to N=0 state and shows drop zone', async () => { const { container } = render(BulkDocumentEditLayout, {}); await addFilesViaInput(container, [makeFile('a.pdf'), makeFile('b.pdf')]);