- Scanner: Dateien von der Scan-Freigabe werden nur übernommen, wenn sie
reguläre Dateien in echten Verzeichnissen sind. chokidar folgt keinen
Symlinks mehr; beim Kopieren über Mount-Grenzen (/mnt/scans → /mnt/data)
wird mit O_NOFOLLOW geöffnet und nur exklusiv geschrieben. Bisher holte
ein Symlink wie scan.pdf -> /proc/self/environ die Zieldatei in den
Posteingang.
- Export: Dateinamen (enthalten u.a. Barcode-Werte) werden auf ein
Pfadsegment reduziert – „../“ verlässt den FTP-Zielordner nicht mehr.
- Belegnummer: {Jahr}/{Nummer} werden URL-kodiert in BELEGNUMMER_*_URL
eingesetzt (Nummer stammt aus Request bzw. gedrucktem Barcode);
belegnummer/release prüft die Typen im Body.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Neue Version nur, wenn die Belegnummer in Paperless eindeutig zu genau
diesem Dokument gehört (serverseitig geprüft)
- Auf die Paperless-Task der Version warten; Ablehnung → Fehler, Tag 21 weg
- Entscheidung im Posteingang nur zusammen mit processOnlyOne
- Vergleichsdialog im Posteingang zeigt die Seiten, die tatsächlich
hochgeladen werden
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Task-Status: getTask() normalisiert die paginierte v10-Antwort
(status klein, result_data, related_document_ids). Bisher wurde jede
Task als „nicht gefunden“ gelöscht, ohne Nachbearbeitung.
- Checksummen: Paperless ≥ 3.0 nutzt SHA-256 statt MD5. Duplikatprüfung
umgestellt; Migration verbreitert Attachments.Checksum und berechnet
Bestandswerte per SHA2() neu.
- Custom-Field-Suche über custom_field_query, der alte Filter wurde von
Paperless ignoriert.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Absender erzeugen PDFs beim erneuten Versand oft neu (andere
Erstellungszeit/Dokument-ID), dadurch unterscheidet sich die Checksumme
und die Duplikatprüfung griff nicht (z.B. Mail 7071 vs. 7072).
- Neuer Text-Fingerprint (SHA-256 über normalisierten PDF-Text via
pdf-parse) in Attachments.ContentFingerprint, inkl. Migration und Index
- Wird beim Mail-Abruf berechnet; Altbestand füllt ein Hintergrund-
Backfill beim Start auf, fehlende Werte werden bei Bedarf nachberechnet
- Duplikatprüfung und Import-Sperre berücksichtigen Anhänge mit gleichem
Inhalt, die importiert sind oder gerade importiert werden
- Jest braucht für pdf-parse --experimental-vm-modules (test-Skripte)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Wurde dieselbe Mail zweimal weitergeleitet, erkannte der Import-Assistent
das Duplikat nicht, solange Paperless das erste Dokument noch verarbeitete –
geprüft wurde nur die Checksumme in Paperless.
- checkDuplicate() berücksichtigt zusätzlich offene Paperless-Tasks von
Anhängen mit gleicher Checksumme (gleicher Seitenbereich)
- Assistent prüft erneut vor dem Abrufen der Belegnummern und vor dem
Import; Duplikate werden ignoriert, reservierte Nummern freigegeben
- executeImport prüft serverseitig vor Upload und Festlegen der Nummer,
sperrt laufende Importe gegen parallele Doppelimporte und meldet 409
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Anhänge mit '/' im Dateinamen (z.B. "Rechnung - 2026/002650322.PDF")
führten zu einem Fehler, weil '/' als Verzeichnistrenner interpretiert
wurde und der temp. Pfad nicht existierte.
- sanitizeFilename() ersetzt '/' und '\' durch '-', entfernt '..' und Null-Bytes
- Wird beim Speichern in die DB (email-download) und beim Aufbau des
temp. Pfads (email-import) angewendet (defense-in-depth)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
E-Mail-Import und External-Upload setzen ASN, Custom Fields (CF3/CF7/CF9),
Dokumenttyp, Tags, Owner und Belegdatum jetzt bereits beim post_document,
statt erst nachträglich über den Task-Processor-Cron (30 s + PATCH).
- Neu: deriveTaskMetadata() in task-metadata.util.ts als gemeinsame
Ableitung (Task-Felder → Paperless-Metadaten) für beide Upload-Pfade
und den Task-Processor – identische Parsing-Regeln, kein Copy-Paste
- Task-Processor nutzt den Helper (verhaltensidentischer Refactor) und
patcht weiterhin idempotent nach; zuständig bleibt er für alles
ID-Abhängige (CF8-Verknüpfungen, Anlage-Titel, Owner-Entfernung, Notizen)
- FAILURE-Zweig loggt Paperless-Fehlertext und Belegnummer vor dem
Löschen des Tasks (ASN-Kollision kann jetzt den Consume scheitern lassen)
- Tests: 18 Unit-Tests für deriveTaskMetadata, 3 Charakterisierungstests
pinnen den PATCH-Payload von processSuccessfulTask
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- New useIsMobile hook and MobileCardList component
- AppLayout: hamburger menu + Drawer navigation on mobile
- All list pages (Inbox, Posteingang, Manuell, Mail, Freigabe, Zahlung, TaskLog)
show card layout on mobile instead of tables
- CSS: responsive modal height, horizontal table scroll, text-size-adjust
- Backend: Agrarmonitor polling fixes, Zahlung service improvements,
IMAP folder service extended, misc controller fixes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Neuer ImapFolderService verschiebt E-Mails nach erfolgreichem Import in den
konfigurierbaren Ordner "importiert" (wird bei Bedarf automatisch erstellt)
- Täglicher Cron um 03:00 Uhr verschiebt E-Mails älter als 90 Tage in den
Papierkorb und leert ihn anschließend
- createImapClient()-Hilfsmethode im EmailDownloadService ausgelagert
- IMAP_IMPORTED_FOLDER und IMAP_TRASH_FOLDER in docker-compose ergänzt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New ImapFolderService moves emails to configurable "importiert" folder
after successful import, creating the folder if it doesn't exist
- Daily cron at 03:00 moves emails older than 90 days to trash and empties it
- Extract createImapClient() helper in EmailDownloadService
- Add ensurePageCache() with in-flight deduplication to BarcodeScannerService
- InboxService regenerates page cache on-demand when image file is missing
- IMAP_IMPORTED_FOLDER and IMAP_TRASH_FOLDER added to .env.example and docker-compose
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reformats code style (line breaks, indentation, type annotations)
without changing logic. Also includes minor feature additions bundled
in the same lint run (stats service, user-settings groups, agrarmonitor
polling improvements).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Store UserGroups from OIDC in UserSettings entity, sync on each request
- Filter daily digest tiles based on user's permission groups
- Add in-memory job status tracking to EmailImportService
- Poll import job status in MailImportWizard and show progress in Spin tip
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>