- 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>
Neuer Button „Cookies zurücksetzen“ neben „Status abrufen“. Er löscht
die gespeicherte Agrarmonitor-Session samt Cookie-Datei; beim nächsten
Zugriff meldet sich der Manager neu an.
Eine laufende Connector-Instanz wird über clearSession() zurückgesetzt
und verworfen, damit sie ihren alten Cookie-Jar nicht wieder in die
Datei schreibt. Während einer Lieferantennummern-Vergabe ist das
Zurücksetzen gesperrt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Neuer Bereich „Lieferantennummern überprüfen“ in den Agrarmonitor-
Einstellungen. Er vergibt allen aktiven Lieferanten ohne
Lieferantennummer eine fortlaufende Nummer im Schema 1555xxxx, ab der
höchsten vergebenen Nummer (Inaktive zählen mit, Altlasten werden
ignoriert).
- Vorschau „Lieferant → neue Nummer“, geschrieben wird erst nach
Bestätigung; Einzelmodus zum Testen an einem Lieferanten
- formData wird wie in der Weboberfläche aus #form_detail aufgebaut,
nur die Lieferantennummer ändert sich
- Dublettencheck über vorhanden.php, Erfolgskontrolle durch Neuladen
des Details, Abbruch beim ersten Fehler
- Lauf im Hintergrund mit Status-Abfrage (wegen Proxy-Timeouts),
Listenfilter werden danach zurückgesetzt
- HTML-Parsing mit cheerio, Unit-Tests für Parser und Vergabe-Ablauf
Co-Authored-By: Claude Opus 5.5 <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>
Der Button „Als ignoriert markieren“ war für alle mit VIEW_MAIL sichtbar,
der Aufruf (PATCH :id/status) verlangte aber MANAGE_ALL und scheiterte
mit 403. Neuer Endpunkt POST /api/emails/:id/ignore mit VIEW_MAIL, der nur
Status 3 setzen kann; bereits verarbeitete E-Mails werden abgelehnt. Das
allgemeine Statusändern bleibt Admins vorbehalten.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Der Import-Wizard ist für verarbeitete E-Mails gesperrt. Damit ließ sich
ein fehlerhaft abgeschlossener Vorgang bisher nicht korrigieren.
Administratoren können eine E-Mail in der Detailansicht nun wieder
freigeben (POST /api/emails/:id/reimport, MANAGE_ALL). Die Anhänge aus
der Datenbank werden weiterverwendet; ein erneuter Abruf vom IMAP-Server
findet nicht statt.
Die Freigabe setzt Status 4 ("Zur Nachbearbeitung") statt Status 0:
check-attachments prüft Mails mit Status 0, findet die Anhänge per
Checksumme in Paperless – dort liegen sie ja bereits – und würde die
Freigabe beim nächsten Lauf sofort wieder auf "Verarbeitet" zurückdrehen.
Status 4 bleibt davon unberührt. Da Status ein freies int ist, ist dafür
keine Migration nötig.
Erlaubt sind nur die Status 1, 2 und 3; liegt die E-Mail ohnehin im
Arbeitsvorrat, antwortet der Endpunkt mit 400, statt den Zustand still zu
überschreiben. Wer die Freigabe ausgelöst hat, steht im Log.
Der neue Status erscheint als eigener Tag sowie in beiden Filtern der
Mailpostfach-Übersicht, damit die freigegebenen Mails auffindbar bleiben.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Die tägliche E-Mail-Zusammenfassung zeigte Nutzern Bereiche, für die sie
keine Berechtigung haben. Zwei unabhängige Ursachen:
- Das Backend prüfte weiterhin die Altgruppe PM_Belege. Die Umbenennung
zu PM_Buchhaltung (ca1d371) war nur im Frontend angekommen, weshalb
der Digest "Manuell bearbeiten" und "In Agrarmonitor" anbot, während
die Oberfläche beide Bereiche sperrte.
- Der Cron-Versand wertet die Gruppen aus user_settings aus. Diese Spalte
wurde nur beim Aufruf der Benutzereinstellungen gefüllt; entzogene
Berechtigungen erreichten den Digest daher unter Umständen nie.
Behoben durch Angleichen des Gruppen-Mappings und den neuen
UserIdentitySyncService, der E-Mail, Benutzername und Gruppen bei jedem
authentifizierten Request aus dem Token spiegelt – ohne den Request zu
blockieren und ohne DB-Zugriff, solange sich das Token nicht ändert. Die
doppelte Identitätspflege im UserSettingsService entfällt.
WebDAV wird nicht eingesetzt und ist entfernt; Export-Ziele bieten nur
noch FTP. Damit verschwindet das ESM-Paket webdav, an dem zwei
Jest-Suites bereits beim Parsen scheiterten.
Veraltete Tests instand gesetzt: email.controller und settings.controller
mockten weniger Abhängigkeiten, als die Klassen inzwischen haben;
postprocessing.service.spec beschrieb noch das alte Regelmodell mit
Einzelfeldern statt FilterJson und ist gegen die heutige Filter-Engine
neu geschrieben (AND/OR, verschachtelte Gruppen, Fehlerprotokollierung).
Enthält außerdem den Arbeitsstand der E-Rechnungs-Mandantenzuordnung, da
sich beide Änderungen dieselben Dateien teilen (SettingsPage, package.json).
98 Tests in 12 Suites grün, Backend- und Frontend-Build sauber.
Co-Authored-By: Claude Opus 5 (1M context) <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>
Belege, die per E-Mail an Agrarmonitor gesendet werden, brauchen bis zu
10 Minuten bis zum Import in den Dateieingang. Bisher wurden sie im
Upload-Check sofort als "Manuell bearbeiten" + Tag 19 markiert, wenn sie
weder verbucht noch im Dateieingang waren – auch mitten im Import-Fenster.
Jetzt wird vor dem Markieren geprüft, ob die jüngste Notiz mit dem
konfigurierbaren Marker-Text jünger als die Wartezeit ist; falls ja, wird
der Beleg übersprungen und beim nächsten Lauf erneut geprüft. Wartezeit
(agrarmonitor_import_wartezeit_minuten, Standard 10) und Marker
(agrarmonitor_notiz_marker, Standard "Agrarmonitor") sind als Settings
konfigurierbar und in der Settings-Seite editierbar.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Zwei Lücken behoben, die bei abgelaufenem Access-Token (v.a. nach inaktivem
Tab, dessen Renew-Timer gedrosselt wurde) zu vollständigen Neuanmeldungen
führten:
- getAccessToken erneuert das Token jetzt proaktiv (signinSilent), wenn es
abgelaufen ist, statt ein abgelaufenes Token zu senden. Profitiert auch den
direkten fetch-Aufrufen (Bilder/PDFs).
- Der 401-Interceptor versucht zuerst einen stillen Refresh und wiederholt die
Anfrage einmal; erst wenn das scheitert (Refresh-Token ungültig), erfolgt der
Login-Redirect.
Gleichzeitige Refreshes werden dedupliziert (renewToken), um invalid_grant bei
Refresh-Token-Rotation zu vermeiden.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Webhook reiht eingehende Dokument-IDs nur noch in eine Warteschlange ein
und antwortet sofort (status "queued"). Ein separater Intervall-Prozess
(WebhookQueueService) arbeitet die IDs nacheinander ab – ohne Überschneidung,
falls ein Dokument mehrfach kurz hintereinander gespeichert wird:
- Jede ID kommt nur einmal in der Liste vor (Dedup).
- Beim Verarbeitungsstart wird die ID sofort entfernt; ein erneutes Feuern
während der Verarbeitung reiht sie wieder ein (ein weiterer Lauf folgt).
- Es läuft immer nur eine Verarbeitung gleichzeitig (isProcessing-Guard).
- Prüfintervall sehr kurz (WEBHOOK_QUEUE_INTERVAL_MS, Default 1000 ms).
Status-Recording (last_webhook_call) + GET /api/webhook/status wandern in den
Queue-Service und liefern zusätzlich die aktuelle Warteschlangen-Größe.
Frontend-Tab zeigt Status "In Warteschlange" und die Queue-Größe an.
Unit-Test deckt Dedup, Remove-on-start, Re-Enqueue und No-Parallel ab.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Neuer Tab "Webhook" in der SettingsPage zeigt den letzten Paperless-
Webhook-Aufruf (Zeitpunkt, Dokument-ID, Aktion, Ergebnis) über
GET /api/webhook/status an. Neue API-Datei src/api/webhook.ts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a payment step after document approval: PM_Freigabe approves
(Field 15 = "freigegeben"), then PM_Zahlung can mark as paid (Field 16).
- Backend: VIEW_ZAHLUNG permission mapped to PM_Zahlung OIDC group
- Backend: ZahlungModule with endpoints to list documents by filter
(ausstehend/freigegeben/alle), set Field 16, fetch options from Paperless
- Backend: setZahlung() throws ForbiddenException if Field 15 ≠ "freigegeben"
- Frontend: /zahlung route with 3-way filter, two status columns (Freigabe + Zahlung)
- Frontend: "Zahlung verbuchen" button disabled with tooltip for non-approved docs
- Frontend: Zahlung menu item with EuroOutlined icon
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Cleanup-Cron von EmailDownloadService in ImapFolderService verschoben,
damit er auch aus EmailController aufrufbar ist (zirkuläre Abhängigkeit vermieden)
- Beim Klick auf „Anhänge prüfen" wird der IMAP-Cleanup fire-and-forget gestartet
- Beim Klick auf „Bereits verarbeitete Anhänge prüfen" werden zusätzlich alle
E-Mails im IMAP-Posteingang, die in der DB als verarbeitet (Status 1) oder
ignoriert (Status 3) markiert sind, in den Ordner „importiert" verschoben
- Erfolgsmeldung zeigt Anzahl verschobener E-Mails an
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New steuertag_ids setting to mark tags as workflow-only (not editable)
- DocumentEditModal shows only content tags (non-Steuertags) as editable chips
- Backend preserves Steuertags when saving document tag changes
- ManuellBearbeitenPage renders content tag chips under document title
- New Steuertags settings tab with multi-select and color preview
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>
- New DailyDigestModule with scheduled summary email for open dashboard items
- Extract StatsService from StatsController for reuse in digest
- Add DailyDigestEnabled, UserEmail, UserPreferredUsername to UserSettings entity
- Sync email/username from OIDC token on each get/update call
- Add dailyDigestEnabled to UserSettingsDto and update API
- Notifications tab in UserSettingsPage with enable toggle and "Jetzt senden" button
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Renamed setting agrarmonitor_tag_posteingang → agrarmonitor_tag_manuell
- Documents not found in AM are now tagged as "Manuell bearbeiten"
instead of being moved back to Posteingang
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add agrarmonitor_tag_posteingang setting (default empty)
- When a document is not found in Agrarmonitor, move it back to Posteingang
tag instead of skipping (if tagPosteingang is configured)
- Expose tagPosteingang in polling config API and settings UI
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a dedicated approval view for PM_Freigabe users to release documents
for payment by setting Paperless custom field 15 to a predefined value.
- Backend: VIEW_FREIGABE permission mapped to PM_Freigabe OIDC group
- Backend: FreigabeErforderlich flag on DocumentType entity (auto-migrated)
- Backend: FreigabeModule with endpoints to list documents, fetch field
options dynamically from Paperless, and set the approval custom field
- Frontend: /freigabe route with filter (default: nicht freigegeben),
paginated table, and modal to select approval value
- Frontend: Settings checkbox to mark document types as requiring approval
- Frontend: Freigabe menu item visible only to PM_Freigabe/PM_Admin users
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Detect duplicates after sync (same AgrarmonitorId, multiple correspondents)
- Auto-merge duplicates with identical names (delete empty, move docs to larger)
- Expose conflicts with different names for manual resolution
- New mergeCorrespondents endpoint + service method
- Conflict resolution modal in SettingsPage with radio selection per conflict
- deleteCorrespondent added to PaperlessService
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Extract getOrCreateCorrespondent helper to deduplicate logic
- Add syncCorrespondentIds to match Paperless correspondents to
Agrarmonitor IDs via Lieferantennummer and persist in CorrespondentSetting
- New POST /api/agrarmonitor/sync-correspondents endpoint
- "Agrarmonitor-Abgleich" button in Correspondents settings tab
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New backend module (agrarmonitor) with status check and device registration
- Frontend settings tab with connection status display and registration form
- Environment variables for base URLs, credentials, cookie path and encryption key
- Docker Compose env passthrough for agrarmonitor config
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>