Zum Hauptinhalt springen

Briefe (Letter)

Zweck

Letter modelliert in SpeamCore physische Briefe — sowohl ausgehende (über ePost gedruckt und versendet) als auch eingehende (gescannt und mit KI klassifiziert). Im Unterschied zum Mail-Modul (digitale E-Mail über Microsoft 365) geht es hier um Papier-Post: Briefkopf mit Adressfenster, DIN-A4-konformer Druck, Einschreiben mit Rückschein, Zustellungs-Tracking — und beim Eingang die automatische KI-Erkennung von Absender, Betreff und passendem Kunden/Lieferanten/Hersteller.

Drei Verarbeitungs-Pfade:

  1. Ausgehend — Innendienst erstellt einen Brief, lässt ihn per ePost (DocuGuide) versenden. Optional Einschreiben mit Tracking + Rückschein.
  2. Eingehend (manuell) — Sekretariat scannt eingehende Post, lädt die PDFs in den SpeamCore-Posteingang. KI analysiert automatisch.
  3. Eingehend (Mail-Scan-to-Inbox) — eingehende E-Mails mit PDF-Anhängen (z. B. vom Anwalt, Steuerberater, Sachverständigen) werden automatisch in den Brief-Posteingang überführt.

Voraussetzungen

- Berechtigung `view:FE_Letter`, `view:Letter` (Standard für alle Innendienst-User). - Für ausgehende Briefe: `create:Letter` + `create:LetterSubmission` + `do:SubmitLetter`. - Für ePost-Versand: Mandanten-Konfiguration mit DocuGuide-Zugang (siehe Konzept-Seite [Brief vs. Mail vs. ePost](/konzepte/brief-vs-mail-vs-epost)). - Für Posteingang-Upload: PDF-Datei (idealerweise PDF/A oder normale PDF mit Text-Layer). - Für Mail-Scan-to-Inbox: konfigurierte Mailbox mit `scanToInboxEnabled = true`.

Berechtigungen (CASL)

ActionSubjectWirkung
viewFE_Letter, LetterBrief-Liste + Detail aufrufbar (eigene Briefe)
createLetterNeuen Brief anlegen
updateLetterFelder ändern (blockiert wenn isLocked = true)
deleteLetterSoft-Delete (blockiert wenn isLocked = true)
doViewDepartmentLettersBriefe der eigenen Abteilung sehen (Department-Lead)
doViewAllLettersBriefe aller Abteilungen sehen (Admin)
view / createLetterSubmissionePost-Submission-Liste sehen / anlegen
doSubmitLetterVersand via DocuGuide auslösen

Row-Level-Scope (Department-Truth-Source)

Drei-Stufen-Modell — wer welche Briefe sieht:

User-RolleFilter
StandardWHERE employeeId = current_employee — nur eigene Briefe
Department-LeadWHERE (employeeId IN colleagues OR departmentId = my_dept) — eigene + Abteilungs-Briefe
AdminWHERE 1=1 — alles

Wichtig: Mail-Scan-to-Inbox-Briefe haben employeeId = NULL und nur departmentId gesetzt — sie sind also nur über den Department-Lead-Scope sichtbar, nicht über Standard. Das ist gewollt: herrenlose Inbox gehört zentral der Abteilung.

Datenmodell

Letter

FeldPflichtTypWirkung
typejaENUM in | outout für ausgehende, in für eingehende Briefe. Default out.
statusjaENUMdraft / sent / received / open / in_progress / done / archived
branchIdneinUUID → BranchNiederlassungs-Zuordnung (für Briefkopf-Anschrift)
employeeIdneinUUID → EmployeeErstellender Mitarbeiter (bei Mail-Scan-to-Inbox null)
departmentIdneinUUID → DepartmentAbteilungs-Scope (Truth-Source für Row-Level-Sichtbarkeit)
parentTypeneinENUMCustomer / Supplier / Manufacturer / Location / Employee
parentIdneinUUIDVerknüpftes Stammdaten-Objekt
locationIdneinUUID → LocationBei parentType = Customer optional eine spezifische Standort-Adresse
parentName / parentStreet / parentZip / parentCity / parentCountryIdautoSnapshotWird beim Anlegen aus dem Parent gezogen und eingefroren — Adressänderungen am Stamm wirken nicht rückwirkend
documentDatejaDateOnlyBrief-Datum (Default: heute)
titleneinStringInterner Titel (für die Liste)
subjectneinStringBetreff im PDF-Header (bei eingehend von KI gesetzt)
bodyneinTEXTBrief-Text (HTML). Bei eingehend von KI als Zusammenfassung gesetzt.
qrLinkIdneinUUID → QrLinkOptional ein QR-Link, der unten rechts auf dem Briefpapier gedruckt wird
qrCodePngneinString (Base64)Vom FE generiertes QR-Code-Bild für die PDF-Engine
isLockedautoBooleantrue sobald aktive LetterSubmission läuft — Felder werden read-only
activeSubmissionIdautoUUID → LetterSubmissionVerweis auf laufende Submission
aiAnalysisStatusautoENUMpending / analyzing / done / failed (nur bei type = in)
aiAnalysisErrorautoTEXTFehlertext, wenn KI-Analyse scheiterte
aiAnalyzedAtautoDateTimeZeitstempel der KI-Analyse
customHeaderInfoneinJSON {label,value}[]Custom-Header-Felder im Briefkopf

Lock-Verhalten

Sobald eine LetterSubmission für einen Brief läuft, wird isLocked = true. Im beforeUpdate-Hook prüft der Service, dass dann nur isLocked, activeSubmissionId und status geändert werden dürfen — alle anderen Felder sind eingefroren. So bleibt der versendete PDF-Inhalt nachträglich nicht manipulierbar.

Schritt-für-Schritt-Anleitung

Ausgehender Brief

  1. Briefe (/letters) → + Neu.
  2. Empfänger wählen — über parentType + parentId einen Kunden, Lieferanten, Hersteller oder Mitarbeiter auswählen. Bei Kunde optional spezifische Filiale (locationId).
  3. Pflichtfelder pflegen: documentDate, title, subject, body.
  4. Optional: einen QR-Link hinterlegen — z. B. zur Wartungs-Portal-Seite oder zur Buchungsseite.
  5. PDF-Vorschau öffnen (Brief-PDF mit Briefpapier, Adressfenster, QR-Code) — visuell prüfen.
  6. „via ePost versenden" klicken → öffnet den Versand-Dialog (SpeamPost-Submit) mit Farbe, Duplexdruck, Einschreiben-Option.
  7. Bestätigen — der Brief wird locked, eine LetterSubmission läuft asynchron über DocuGuide.

Eingehender Brief (manueller Upload)

  1. Briefe (/letters) → Tab Posteingang+ Upload.
  2. Drag & Drop ein oder mehrere PDFs ins Modal (max. 3 parallel).
  3. SpeamCore antwortet sofort mit 202 (kein Warten) — der KI-Worker läuft im Hintergrund.
  4. Beobachten: jede Letter-Zeile zeigt aiAnalysisStatus = pending (Spinner) → analyzingdone oder failed.
  5. Sobald done: Brief hat automatisch Absender, Betreff, Datum, Priorität und ist mit dem richtigen Kunden/Lieferanten/Hersteller verknüpft.
  6. Status weiter pflegen: receivedopenin_progressdone (manuell oder automatisch bei beantwortetem ausgehenden Folge-Brief).

Eingehender Brief (Mail-Scan-to-Inbox)

  1. Im Postfach-Setup (siehe Mail-Konten) den Toggle Scan-to-Inbox aktivieren setzen.
  2. Optional pflegen: Absender-Whitelist / -Blocklist, Subject-Filter, „nur PDFs importieren".
  3. Sobald eine E-Mail mit PDF-Anhang in dieses Postfach kommt, wird der Anhang automatisch als Letter in den Posteingang gelegt — employeeId = null, departmentId = <Postfach-Department>. KI-Analyse läuft analog zum manuellen Upload.

QR-Code-Druck (Welle 137 + 148)

Wenn ein Brief mit einem QR-Link versehen wird, druckt SpeamCore unten rechts auf dem Briefpapier automatisch den QR-Code. Anwendungsfälle:

  • Wartungsprotokoll mit QR zur Anlage-Dokumentation
  • Rechnung mit QR zum Online-Zahlungs-Portal
  • Kundenbrief mit QR zur Visitenkarte des Sachbearbeiters
  • Mahnung mit QR zur Buchungsseite für ein Klärungsgespräch

Konfiguration des Codes (Style, Logo, Farben) läuft über das QR-Link-Modul.

Per-Mail senden (seit Juni 2026)

Ein Brief lässt sich – alternativ zum physischen Versand per ePost – auch direkt per E-Mail verschicken: Der Button Per Mail senden stellt das gerenderte Brief-PDF als Mail-Anhang bereit (GET /letters/:id/mail-attachment, CASL create:Mail) und übergibt es an den Mail-Verfassen-Dialog. So geht derselbe Brief wahlweise als Post oder als Mail raus.

Beim Druck mehrerer Briefe in einem Vorgang steuert das Flag split, ob das Ergebnis als ein gemeinsames PDF oder als getrennte PDFs je Brief ausgegeben wird.

Verknüpfungen zu anderen Modulen

Sub-Listen pro Stammdatum

Jedes Stammdaten-Objekt (Kunde, Lieferant, Hersteller) hat eine Sub-Liste /post:

  • /customers/:id/post — alle Briefe an / von diesem Kunden
  • /suppliers/:id/post — analog
  • /manufacturers/:id/post — analog

Damit sehen Sie auf der Stammdaten-Detail-Seite die vollständige Brief-Korrespondenz, ohne erst in die globale Liste zu wechseln.

Häufige Fehler und Lösungen

FehlerLösung
Brief lässt sich nicht editierenisLocked = true — eine LetterSubmission läuft. Submission-Status prüfen (Letter-Submissions). Bei failed oder cancelled wird wieder editierbar.
KI-Analyse hängt auf pendingWorker-Status im Admin-Bereich prüfen. Bei Hängenbleiben: BullMQ-Job neu starten.
KI weist falschen Kunden zuDetail-Sicht öffnen, parentType/parentId manuell korrigieren. Beim nächsten ähnlichen Absender lernt die KI nicht automatisch — daher saubere Absender-Stammdaten pflegen.
Mail-Scan-Briefe sind nicht sichtbarStandard-User sieht nur eigene Briefe (employeeId). Mail-Scan setzt nur departmentId. Nur Department-Lead und Admin sehen das.
PDF-Vorschau ist leerLetterhead-Shell-Konfig fehlt — in Customization → Allgemein das Briefpapier konfigurieren.
ePost-Versand schlägt fehlDocuGuide-Token abgelaufen oder Konfiguration fehlt. Admin-Modul prüfen. Bei errorDetail in der Submission steht die DocuGuide-API-Antwort.
Adresse im PDF stimmt nichtSnapshot — beim Anlegen wurde die damalige Adresse eingefroren. Brief löschen und neu anlegen (oder Adresse manuell überschreiben — parentStreet/Zip/City sind editierbar bei nicht-locked Briefen).

API/Schnittstellen

CRUD

MethodeEndpointZweckCASL
GET/api/lettersListe (mit Row-Level-Scope)view Letter
POST/api/lettersBrief anlegencreate Letter
GET/api/letters/:idDetailview Letter
PUT/api/letters/:idUpdate (blockiert bei isLocked)update Letter
DELETE/api/letters/:idSoft-Delete (blockiert bei isLocked)delete Letter

PDF + Upload

MethodeEndpointZweckCASL
GET/api/letters/:id/pdfPDF/A-1b für DocuGuide-Versandview Letter
GET/api/letters/:id/inbox-pdfScan-PDF (eingehend)view Letter
POST/api/letters/upload-inboxMulti-File-Upload Posteingangcreate Letter
GET/api/letters/own-addressAbsender-Adresse aus Mandanten-Setupview Letter

Submissions (ePost)

MethodeEndpointZweckCASL
POST/api/letters/:id/submitVersand starten — 202 Accepteddo SubmitLetter
GET/api/letters/:id/submissionsSubmission-Historieview LetterSubmission
GET/api/letters/:id/submissions/:submitIdDetail einer Submissionview LetterSubmission
POST/api/letters/:id/submissions/:submitId/cancelAbbrechen (vor sent)do SubmitLetter
GET/api/letters/:id/mail-attachmentBrief-PDF als Mail-Anhang (Per Mail senden)create Mail

Versionshinweise

  • 2026-06-12: Per Mail senden (/letters/:id/mail-attachment) und Druck-split-Flag (gemeinsames vs. getrenntes PDF je Brief) dokumentiert. Verifiziert an letter.router.ts.
  • 2026-05-26 (Welle 148): Initiale Veröffentlichung. Quelle: BE-Commits 68248ac5 (Brief + Briefpapier + PDF), 5de6fbb3 (DocuGuide-Integration), b8096e48 (Status-Normalisierung), 34487c76 (Posteingang-KI + Mail-Scan-to-Inbox), ae114638 (Row-Level-Scope + Department-Truth-Source). FE-Commits c513dcbd (Post-Modul + Customization-Print), d5bdc79f (FE-ePost), aefa838f (Lock-Banner-Fix), f73f6286 (Posteingang-UI), b7225bdd (Filter-Panel + Multi-Upload + KI-Status-Spinner + Dashboard-Badge). Drei BE-Worker: epost-submit-worker, letter-inbox-worker, microsoft-subscription-renewal.worker. Komplett neues Modul, eigene Sub-Listen pro Stammdatum.