Files
familienarchiv/backend/src
Marcel 5cbb14d4a3 fix(bulk-edit): backend hardening — audit, caps, dedupe, CRLF, WRITE_ALL on /ids
Addresses Markus B1+B2, Nora C1+C4+C5, Tobias #1, Sara B1+B2+C2, Elicit S2+C4
from the cycle 1 review on PR #331.

Audit / version trail
  applyBulkEditToDocument now takes actorId, calls
  documentVersionService.recordVersion(saved), and emits an
  AuditKind.METADATA_UPDATED event tagged source=BULK_EDIT — restoring parity
  with the single-doc updateDocument path.

Caps
  /api/documents/batch-metadata: 500-ID cap (matches PATCH cap)
  /api/documents/ids: 5000 result cap with BULK_EDIT_TOO_MANY_IDS on overflow

Permission tightening
  /api/documents/ids re-gated WRITE_ALL — its only consumer is the bulk-edit
  fast path (least-privilege per Elicit S2 + Nora's defence-in-depth).

Audit log
  /ids and /batch-metadata now emit one log.info per call, mirroring the
  quickUpload + bulkEdit format.

Robustness
  Duplicates in PATCH documentIds are de-duplicated via LinkedHashSet so a
  double-clicked "Alle X editieren" cannot inflate the updated count.
  log.warn lines that interpolate Throwable.getMessage() now run through a
  CRLF-strip helper (CWE-117).

Tests added
  applyBulkEditToDocument_recordsVersion_andLogsAuditEvent_taggedSourceBulkEdit
  patchBulk_acceptsExactly500Ids_atTheCap (off-by-one fence)
  patchBulk_dedupesDuplicateDocumentIds_doesNotInflateUpdatedCount
  getDocumentIds_returns403_forUserWithoutWriteAll
  getDocumentIds_returns400_whenResultExceedsFilterCap
  batchMetadata_returns403_forUserWithoutReadAll
  batchMetadata_returns400_whenIdsExceedsCap

All 231 backend tests green.

Refs #225, PR #331

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 16:24:03 +02:00
..