fix(arcim-migration): dedup underlag per verifikat and sniff file type from bytes (#1065)

First production sweep of /import-documents (921 Bokio receipts) surfaced
two defects that together dropped 7 of 666 resolvable receipts:

- The idempotency key was company-wide (company_id, sha256), but the same
  file content legitimately backs several verifikat (one arrende contract
  attached to each year's arrende voucher, one insurance letter on two
  vouchers). The second and later verifikat silently lost their underlag.
  The key is now (company_id, sha256, journal_entry_id).

- Bokio's uploads list occasionally declares the wrong contentType (a JPEG
  stored as image/png); magic-byte validation then correctly rejects the
  mismatch, failing a perfectly good receipt. The importer now sniffs the
  real format from the bytes (detectFileMagic, now exported from the
  document service) and only falls back to the declared type when no
  signature is recognised. The synthesised filename extension follows the
  effective type.

Signed-off-by: Jonas Hagberg <jonas@lindan.se>
This commit is contained in:
Jonas Hagberg
2026-07-20 11:38:53 +02:00
committed by GitHub
parent 920400cfb5
commit 378611a2dc
3 changed files with 102 additions and 25 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ export function validateDocumentFile(file: { size: number; type?: string }): str
* placeholder or summary instead of the real binary file: those uploads
* succeed at the storage layer but the bytes are unreadable as a PDF/image.
*/
function detectFileMagic(bytes: Uint8Array): string | null {
export function detectFileMagic(bytes: Uint8Array): string | null {
if (bytes.length < 4) return null
// PDF: %PDF- anywhere in the first 1024 bytes. ISO 32000 readers accept a
// preamble before the header (Acrobat scans the first 1 KB), and real-world