Zum Hauptinhalt springen

Mail

Zweck

Das Mail-Modul ist eine Single-Page-App mit Folder-Tree (links), Mail-Liste (Mitte) und Detail-Pane (rechts) auf Desktop, sowie einem Single-Pane-Navigator auf Mobile. Es verbindet sich mit Microsoft 365 über Mail-Konten, bietet einen Compose-Modal mit Rich-Text-Editor und AI-Draft, sowie einen Live-Sync über useMailStream() (WebSocket/SSE).

Voraussetzungen

- Mindestens ein verbundenes Microsoft-365-Konto (siehe [/mail-accounts](/mail-accounts)). - `MailboxEmployee`-Verknuepfung zwischen Mitarbeiter und Mailbox. - Berechtigung `view:Mail`. Für Versand zusaetzlich `create:Mail`.

Berechtigungen (CASL)

ActionSubjectWirkungKeycloak-Rolle
viewFE_Mail, MailMail-Modul aufrufbar
view/updateMailFolderFolder-Tree und ReorderAPP_SPEAMCORE_VIEW/UPDATE_MAIL_FOLDER
viewMailRecipient, MailEmployeeStateEmpfaenger und Lese-StatusAPP_SPEAMCORE_VIEW_MAIL_RECIPIENT, MAIL_EMPLOYEE_STATE
createMailMail versendenAPP_SPEAMCORE_CREATE_MAIL
updateMailDraft speichernAPP_SPEAMCORE_UPDATE_MAIL
deleteMailSoft-Delete (in Trash)APP_SPEAMCORE_DELETE_MAIL
viewAllMailAdmin-Override: sieht alle Postfaecher des Mandanten unabhaengig von MailboxEmployee-Zuweisung — gedacht fuer IT/Compliance/Audit. Ohne diese Permission greift der Standard-Scope (nur eigene + explizit zugewiesene Aliase).APP_SPEAMCORE_VIEW_ALL_MAIL

Routen

PfadVariante
/mailStandard im Modal-Modus
/mail/:mailIdDirektlink auf eine konkrete Mail
/mail-popoutEigenes Browserfenster ohne Modal-Wrapper
/mail-popout/:mailIdwie oben mit Mail-Vorauswahl

Schritt-für-Schritt-Anleitung

Mail lesen

  1. Mail (/mail) öffnen.
  2. Linke Sidebar zeigt den Folder-Tree (Inbox / Sent / Drafts / Trash + Custom-Folder).
  3. Folder anklicken → Mail-Liste in der Mitte.
  4. Mail anklicken → Detail-Pane rechts mit Volltext, Anhängen und Aktionen.

Mail schreiben

  1. Compose klicken — MailComposeModal öffnet sich.
  2. Empfaenger eingeben (Autocomplete via MailRecipientInput, mit Contact-Resolution).
  3. Subjekt und Body pflegen — Rich-Text-Editor mit HTML-Sanitization.
  4. Optional AI-Draft klicken (MailComposeAiButton) — generiert Body via LLM, anschliessend bearbeitbar.
  5. Anhänge per Drag-&-Drop (MailAttachmentZone) ergaenzen — max. 25 MB pro Datei (Graph-API-Limit).
  6. SendenPOST /api/mails/send.

Auf Mail antworten / weiterleiten

Aus dem Detail-Pane: Reply, ReplyAll oder Forward — jeweils öffnet MailComposeModal mit vorbefuelltem Body.

Folder umsortieren

In der Sidebar per Drag-&-Drop. Wirkt über useFolderReorder() und PATCH /api/mail-folders/:id/reorder.

Listenansicht — mail

UI-Elemente

Komponente: MailFolderSidebar

Folder-Tree mit Drag-&-Drop. Folder-Typen: inbox, sent, drafts, trash, custom.

Komponente: MailComposeModal

Rich-Text-Editor mit Recipient-Autocomplete, Anhang-Zone und AI-Draft-Button.

Button: „AI-Draft"

Generiert via LLM einen Mail-Body aus dem Kontext (Empfaenger, Betreff, vorhergehende Mails). Erfordert aktiven AI-Provider.

Hook: useMailStream

WebSocket-/SSE-Subscription für eingehende Mails. Invalidiert die Mail-Queries automatisch.

Felder und Eingaben (Compose-Modal)

FeldnamePflichtDatentypWirkung beim AusfuellenVoraussetzung
tojaEmailAddress[]Empfaenger der Mail. Validation via RFC 5322.mind. ein gueltiger Empfaenger.
ccneinEmailAddress[]Kopie.gültige Adressen.
bccneinEmailAddress[]Blindkopie.gültige Adressen.
subjectneinString (max. 255)Betreff der Mail.
bodyjaHTML/TextHauptinhalt. Wird HTML-sanitiert vor dem Versenden.
attachmentDocumentIdsneinUUID[]Anhänge über das Document-Modell.Datei kleiner als 25 MB.

Modell-Felder (Mail)

FeldDatentypWirkung
mailboxIdUUIDMail-Zuordnung zur Mailbox.
microsoftMessageIdStringGraph-API-ID — Identifizierung in Microsoft 365.
conversationIdStringThreading.
internetMessageIdStringRFC-2822-ID.
subject, body, bodyTypeInhalt.
receivedAt, sentAtDateTimeZeitstempel.
isDraftBooleanDrafts werden lokal in SpeamCore gehalten.
recipientsnested[]From/To/CC/BCC mit MailAddress-Aufloesung zu Kontakt.
employeeStatesnested[]Pro Mitarbeiter Lese-Status, Folder-Zuweisung und seit Welle 139 isHandled/handledAt.
calendarEventnestediCal-Verknuepfung (Phase 1).
aiSummary (Welle 139)TEXTKI-Zusammenfassung in 2-3 Sätzen, max. 2000 Zeichen.
aiSummaryDurationMs (Welle 139)IntegerVerarbeitungs-Dauer für die UI-Anzeige („in 2,3 Sek erstellt").
aiCategory, aiNeedsReply, aiReplySuggestion, aiProcessedAt, linkedEntityType/-IdgemischtKI-Klassifizierung + Antwortvorschlag + Verknüpfung zu Auftrag/Beleg.

KI-Banner-Card und Erledigt-Workflow (Welle 139)

Im Detail-Panel erscheint über dem Mail-Body eine KI-Banner-Card mit:

  • Zusammenfassung (aiSummary) in 2–3 Sätzen plus Dauer-Hinweis
  • Key-Facts als Pills: aiCategory (lila), linkedEntityType (neutral), aiNeedsReply als „Handlung notwendig" (orange) oder „Erledigt" (grün, wenn isHandled = true)
  • Action-Chips:
    • „Antwortvorschlag übernehmen" — übernimmt aiReplySuggestion ins Reply-Formular
    • „Als erledigt markieren" — togglet isHandled (siehe unten)
  • „Erneut analysieren" (im AI-Assist-Menü oder Sidebar-Header) startet POST /api/mails/:id/reprocess-ai — der Query-Cache wird live gepatcht, kein Refresh nötig

Erledigt-Status (isHandled)

Pro Mail und Mitarbeiter speichert MailEmployeeState:

FeldWirkung
isHandledBoolean — User markiert die Mail als bearbeitet.
handledAtZeitstempel.

Sichtbarkeit:

  • Inbox, Smart-Folders, Custom-Folders: erledigte Mails werden über ?hideHandled=true ausgeblendet (Default in der Inbox-Sicht).
  • Trash, Sent, Drafts: erledigte Mails bleiben sichtbar.
  • Der Counter unreadCounts.needsAction zählt nur aiNeedsReply = true AND isHandled != true.

Mailbox-Override für KI-Zusammenfassung

MicrosoftConfig.aiAutoSummary (mandantenweit) und Mailbox.aiAutoSummaryOverride (pro Postfach) steuern, ob neue Mails automatisch eine aiSummary erhalten. Reprocess-Endpoint funktioniert unabhängig davon.

Liste — Datum-Sections + Quick-Range + Background-Preload (Welle 139)

Die Mail-Liste rendert seit Welle 139 Sticky-Section-Header zwischen den Zeilen:

SectionBedingung
HEUTEgleicher Kalendertag
GESTERNdayDiff = 1
DIESE WOCHEdayDiff ≤ aktueller ISO-Wochentag (ab Montag)
LETZTE WOCHEdayDiff ≤ Wochentag + 7
DIESEN MONATgleicher Monat und Jahr
ÄLTERFallback

Sections werden in Search/Trash/Drafts unterdrückt. Basis-Datum: receivedAtsentAtupdatedAtcreatedAt.

Zusätzlich:

  • Quick-Range-Dropdown im List-Header (schneller Wechsel zwischen typischen Zeiträumen).
  • Background-Preload der letzten 30 Tage (max. 6 Pages) bei aktiver Inbox-Sicht — beim Scrollen entsteht kein Loading-Spinner mehr.

Popout-only Mail-Fenster (Welle 139)

Das eingebettete Mail-Modal in der App wurde entfernt. Klick auf das Mail-Icon im Header öffnet jetzt immer das Popout-Fenster (separates Browser-Fenster). Vorteil: Mehrfenster-Workflow, die Mail bleibt sichtbar, während im Haupt-Tab andere Module bedient werden.

MailboxAlias-Blacklist + Per-User-Permissions (Welle 139)

Auf Mail-Konten sind zwei neue Mechanismen aktiv:

  • MailboxAlias.isBlacklisted — permanent ausgeschlossen, unabhängig von isActive. Aliase mit diesem Flag erscheinen in keiner Liste und keinem Counter.
  • MailboxEmployee.aliasPermissions — Map <emailAddress>'read' | 'write' | 'readwrite'. Im aliasMode = separate werden nur Aliase angezeigt, auf die der Mitarbeiter die passende Permission hat. unreadCounts respektiert die Permission-Map.

Wiederverwendbare Konzepte

Signatur-Editor (Welle 149)

Pro Mandant gibt es einen zentralen Signatur-Editor unter Customization → Mail-Signature (Route /customization/mail-signature). Drei Layout-Varianten zur Auswahl:

VarianteAufbau
compacteine Zeile mit Name + Titel, darunter Kontakt-Daten kompakt
classicklassischer Block mit Logo links, Daten rechts
stackedLogo oben, Name + Titel darunter, Kontakt darunter

Felder pro Toggle (Vorname / Nachname / Job-Titel / Telefon / Mobil / Email): jeder Wert kann ein-/ausgeblendet werden. Firmen-Daten (Adresse, USt-IdNr., Geschäftsführer) sind read-only aus /settings/company und können nicht im Editor überschrieben werden — die Konsistenz bleibt garantiert.

Personalisierung zur Renderzeit: Beim Versand jeder Mail lädt der Render-Service den Sender-Kontext und injiziert Name + Telefon + Mail des aktuellen Mitarbeiters. Eine Signatur — beliebig viele Sender.

Logo-Höhe: Slider 60–250 px für proportionales Logo. Bild aus dem Customization-Logo.

Disclaimer + Confidentiality: Frei editierbar im Legal-Bereich, wird unten an die Signatur angehängt.

Preview als anderer Mitarbeiter: Im Editor-Header gibt's einen Mitarbeiter-Picker (view:Employee-Check) — sehen Sie, wie die Signatur für Anna Müller aussieht, ohne sich als Anna einzuloggen.

Default-Auto-Load: Im Compose-Modal wird die Signatur automatisch angehängt, ohne dass der User einen Insert-Button drücken muss. Über das Settings-Toggle pro Mitarbeiter abschaltbar.

Output: Inline-HTML (keine CSS-Klassen) mit Outlook-Fallback-Strukturen.

Phishing-AI (Welle 149)

Zwei neue Mail-Felder klassifizieren eingehende Mails auf Phishing-Risiko:

FeldTypWerte
aiScamScoreENUMnone / low / medium / high
aiScamReasonsTEXTKI-Begründung in 1–3 Sätzen

Erkennung: Im selben KI-Call wie aiSummary / aiCategory — der Prompt prüft auf Domain-Spoofing, Login-Forderungen, Vorschussbetrug, Dringlichkeits-Drohungen.

Anzeige im Detail-Panel:

  • aiScamScore = "high"rote Warnbox über dem Mail-Body mit Empfehlung „IT kontaktieren, nicht klicken"
  • aiScamScore = "medium"orange Warnung mit Hinweis „Bitte zweimal lesen"
  • aiScamReasons wird unterhalb angezeigt — der User versteht, warum der Score so hoch ist

Config: MicrosoftConfig.aiScamDetectionEnabled mandantenweit, Mailbox.aiScamDetectionOverride pro Postfach. Standardmäßig aktiv.

Bidirektionaler MS↔SC State-Sync (Welle 149)

SpeamCore und Outlook (Microsoft 365) bleiben jetzt in beide Richtungen synchron — wenn ein User im Outlook Web eine Mail liest, wird sie sofort in SpeamCore als gelesen markiert (und umgekehrt). Details im Konzept: Mail Microsoft Graph-Sync.

Was synchronisiert wird:

  • isRead (gelesen / ungelesen)
  • flag (markiert)
  • parentFolderId (in welchem Ordner)
  • isTrashed (in den Papierkorb verschoben)
  • Folder-Tree-Updates (neue Ordner, Umbenennungen)

Technik: Microsoft Graph-Webhook-Subscriptions pro Mailbox, automatische Verlängerung über microsoft-subscription-renewal.worker.ts (Cron alle 12 h).

Auto-Erledigt (Welle 149)

Wenn Sie eine Mail mit der Action „Antworten" (oder „Allen antworten") beantworten, markiert SpeamCore automatisch alle bisherigen Mails im selben Thread (gleiche conversationId) als isHandled = true — sofern sie aiNeedsReply = true haben und noch nicht erledigt sind. Pro Mitarbeiter im MailEmployeeState-Team.

Nicht für Forwards — die starten eine neue conversationId.

So bleibt die Smart-Folder-Sicht „Braucht Antwort" sauber, ohne dass Sie nachträglich Häkchen setzen.

Smart-Folder-Bulk-Aktionen (Welle 149)

Drei neue Endpoints für Massen-Aktionen auf einen kompletten Smart-Folder:

EndpointWirkung
POST /api/mail-employee-state/mark-folder-readAlle Mails im gewählten Folder als gelesen
POST /api/mail-employee-state/mark-folder-handledAlle Mails als erledigt
POST /api/mail-employee-state/mark-folder-unreadAlle als ungelesen (z. B. Übergabe an Kollegen)

Smart-Folder-Targets: inbox, sentitems, drafts, trash, needsAction, newsletters, attachments, calendar.

Realkosten-Anzeige (Welle 149)

Im Mailbox-Detail unter „KI-Kosten" zeigt die AiCostEstimateCard die echten KI-Kosten der letzten 30 Tage, sobald genug Daten vorhanden sind:

FeldQuelle
aiActualCostEur30dSumme AiUsageLog.costEur über 30 Tage (4 Dez.)
aiActualMailCount30dAnzahl Mails mit KI-Analyse
aiActualDaysAnzahl unterschiedlicher Tage mit Aktivität
aiActualCostPerMailMittelwert pro Mail (6 Dez.)
aiActualAvgPerDayMittelwert pro Tag (4 Dez.)

Realwerte ab: ≥ 10 Mails ODER ≥ 5 Tage Datengrundlage. Sonst zeigt die Karte eine hartkodierte Schätzung mit dem Hinweis „Basierend auf Standard-Annahmen — echte Werte ab Tag 5".

Alias-Switcher in der Sidebar (Welle 149)

Pro Mailbox können Aliase eingerichtet sein (z. B. info@, vertrieb@, support@). In der MailFolderSidebar sind sie als eingerückte Klick-Switcher unter der Mailbox sichtbar:

  • Pro Alias eigener Unread-Counter
  • Klick filtert die Liste auf den Alias (?aliasFilterAddress=...)
  • BE-Filter via recipientAliasEmail (JOIN-Query, ersetzt den alten URL-Killer mit 1000+ UUIDs)

Mehrere Aliase gleichzeitig? Aktuell nur einer als Filter. Für „alle anschauen": Filter zurücksetzen.

Gravatar + EmailAvatar (Welle 149)

Statt grauer Initial-Kacheln zeigen Mails jetzt das Gravatar-Bild des Absenders, sofern verfügbar:

  • Neuer Contact.profilePictureDocumentId + profilePictureSyncedAt
  • Sync über contact-enrichment-worker (kein Live-Call beim Anzeigen — wir laden das Bild einmalig in unser Document-Modul)
  • SHA-256(email) als Gravatar-Key, d=404 (nur echte Avatare, keine Identicons)
  • FE-Fallback: deterministisch hash-gefärbte Initialen client-seitig (nicht persistiert)
  • DSGVO-Hinweis: Beim Sync wird der E-Mail-Hash an Automattic übermittelt — User muss im Settings-Toggle gravatarEnabled opt-in. Beim Opt-Out werden keine Gravatare gezogen.

Compliance-Whitelist (Welle 149)

Vehicle-Recipient-Whitelist pro Mailbox — wer darf Mails von welchen Absendern verarbeiten:

  • Auf Mailbox-Ebene gepflegt
  • NULL = Rolle-basiert (Default — Standard-Permissions greifen)
  • Nicht-NULL = explizite Whitelist überschreibt Rollen-Permissions

Eingesetzt z. B. bei Personalrats-Postfach: nur HR-Leitung + Personalrat-Mitglieder dürfen Mails verarbeiten, normale HR-SB sind ausgeschlossen.

UX-Updates Compose (Welle 149)

Der Compose-Modal wurde komplett redesigned:

  • Schmaler Header mit kompakten An / Cc / Bcc / Betreff-Zeilen (keine eigene Toolbar pro Feld)
  • TipTap-BubbleMenu (Bold/Italic/Underline/Link/List) erscheint nur auf Text-Selektion
  • Footer-Action-Bar: großer Senden-Button in Mandantenfarbe mit Tastatur-Hinweis ⌘↵, daneben Icons für Anhang, Bild, Signatur, KI-Pill, Discard
  • Resizable über Bottom-Right-Handle, Größe in localStorage persistiert
  • Reply-Visualisierung: Attribution „Am 26.05.2026 schrieb Max Müller …" + tenant-gefärbter Quote-Block

Bulk-Toolbar bei Multi-Select

Sobald mehrere Mails markiert sind (Click+Shift, Cmd/Ctrl+A, Multi-Klick), schwebt eine Bulk-Action-Bar unten:

  • Markieren als gelesen / ungelesen / erledigt
  • In Papierkorb verschieben
  • Verschieben in Folder (Picker)

Tastatur-Shortcuts

TasteWirkung
/Search-Fokus in der Listen-Suchleiste
?Shortcut-Overlay (Cheatsheet-Modal)
yAktuelle Mail toggle-handled
uAktuelle Mail toggle-read
Cmd/Ctrl+EnterCompose senden
Cmd/Ctrl+AAlle Mails in Liste selektieren
EscCompose schließen / Multi-Select aufheben

Right-Click-Aktionen

Rechtsklick auf eine Mail in der Liste öffnet ein Context-Menü mit:

  • Antworten / Allen antworten / Weiterleiten
  • Toggle Erledigt / Gelesen / Markiert
  • Copy Sender / Copy Subject
  • In Folder verschieben
  • Löschen

Smart-Folder-Sidebar Rechtsklick: „Alle als gelesen / ungelesen / erledigt" auf den ganzen Folder.

Orphan-Cleanup + Archive-Folder (Welle 149)

Hintergrund-Service mailOrphanCleanup.service:

  • Prüft beim Sync: gibt Microsoft Graph für unsere Mail-ID einen 404 zurück → die Mail wurde auf MS-Seite endgültig gelöscht
  • $batch GET für parallele Prüfung (effizient)
  • Force-Delete in SpeamCore — Mail verschwindet aus der Liste
  • Trigger: Boot + nach jedem Sync

Archive-Folder: Neuer Folder-Typ MailFolder.type = 'archive' (Well-Known Outlook /archive). Über Smart-Folder-Aktionen oder Drag&Drop ablegen.

Verknüpfungen zu anderen Modulen

  • Mail-Konten — Quelle der Mailbox, KI-Feature-Toggles + Compliance-Whitelist.
  • Mail Microsoft Graph-Sync — Konzept-Hintergrund zum bidirektionalen Sync.
  • KontakteMailAddress-Auflösung, Gravatar-Sync.
  • MitarbeiterMailEmployeeState pro Mitarbeiter und Mail (isHandled, isRead, isStarred).
  • Dokumente — Anhänge über das Document-Modell + Gravatar-Bild-Storage.
  • Briefe — Mail-Scan-to-Inbox überführt eingehende Mails mit PDF-Anhang in den Brief-Posteingang.
  • KI-Chat-Architektur — Mail-Tools im MCP-Server für Auswertungen + Versand via KI.

Häufige Fehler und Lösungen

FehlerLösung
Mail kommt nicht anEmpfaenger prüfen; ggf. Spam-Filter beim Empfaenger; lastSyncAt der Mailbox prüfen.
AI-Draft-Button fehltKein AI-Provider aktiv.
Anhang wird abgelehntDatei größer als 25 MB (Graph-API-Limit).
Folder-Reorder bleibt nicht erhaltenMultiple-User-Edits — Lost-Update. Erneut versuchen.
Drafts gehen verlorenDrafts liegen nur in SpeamCore — bei MailboxEmployee-Loeschung gehen sie mit.

API/Schnittstellen

MethodeEndpointZweckCASL
GET/api/mailsListeview Mail
GET/api/mails/:idDetailview Mail
POST/api/mails/sendNeue Mail sendencreate Mail
POST/api/mails/:id/sendDraft versendenupdate Mail
POST/api/mails/:id/replyAntwortencreate Mail
POST/api/mails/:id/forwardWeiterleitencreate Mail
PATCH/api/mails/:idDraft-Updateupdate Mail
DELETE/api/mails/:idSoft-Delete (Trash)delete Mail
GET/api/mail-foldersFolder-Treeview MailFolder
PATCH/api/mail-folders/:id/reorderFolder-Reorderupdate MailFolder
GET/api/mail-employee-state/:employeeIdPer-Employee-State

Versionshinweise

  • 2026-04-29: Initiale Veröffentlichung mit FE-Tiefen-Standard.
  • 2026-05-21 (Welle 139): Massive Erweiterung des Mail-Moduls. KI-Banner-Card mit Summary + Key-Facts-Pills + Action-Chips, persistente aiSummary mit Dauer-Hinweis, „Erneut analysieren" via POST /:id/reprocess-ai mit Live-Cache-Patch. isHandled/handledAt auf MailEmployeeState, ?hideHandled=true-Param in listMails, needsAction-Counter im unread-counts. Datum-Sections (HEUTE / GESTERN / ÄLTER), Quick-Range-Dropdown, Background-Preload der letzten 30 Tage (max. 6 Pages). Eingebettetes Mail-Modal entfernt — Header-Icon öffnet immer das Popout-Fenster. MailboxAlias.isBlacklisted als permanente Sperre, MailboxEmployee.aliasPermissions als Per-User-Permission-Map. Quelle: ca. 20 FE-Commits + 9 BE-Commits zwischen 17.–21.05.
  • 2026-05-26 (Welle 149): Riesige Welle der Mail-Modul-Modernisierung. Signatur-Editor mit drei Layout-Varianten und Render-Zeit-Personalisierung. Phishing-AI mit aiScamScore/aiScamReasons und Warnboxen. Bidirektionaler MS↔SC State-Sync via Graph-Webhooks (siehe Konzept). Auto-Erledigt beim Antworten im Thread. Smart-Folder-Bulk-Aktionen (mark-folder-read/handled/unread). Realkosten-Anzeige ab 10 Mails / 5 Tage. Alias-Switcher in der Sidebar. Gravatar + EmailAvatar mit DSGVO-Opt-In. Compliance-Whitelist für Vehicle-Recipient. Compose-Redesign mit TipTap-BubbleMenu, Bulk-Toolbar, Tastatur-Shortcuts (/, ?, y, u, ⌘↵), Right-Click-Aktionen. Orphan-Cleanup + Archive-Folder. Quelle: FE 765c2b90, d524b351, 6581d2b4 + BE 903df669, 8a48cadb, 8d8968d8, ee260713, f9e22872 + Worker microsoft-subscription-renewal.worker.ts.