This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/docs/klausur-modul/UNIFIED-INBOX-SPECIFICATION.md
Benjamin Admin bfdaf63ba9 fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.

This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).

Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:51:32 +01:00

68 KiB

BreakPilot Unified Inbox - Erweiterte Spezifikation

Version: 2.0.0 Datum: 2026-01-10 Status: Entwicklungsspezifikation Priorität: P0 - Kernprodukt


1. Executive Summary

1.1 Das Problem

Eine Schulleiterin in Niedersachsen muss 4 verschiedene dienstliche E-Mail-Adressen verwalten:

┌─────────────────────────────────────────────────────────────────┐
│                    AKTUELLE SITUATION                           │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  📧 schulleitung@grundschule-xy.de                             │
│     └── Landesschulbehörde, Schulträger                        │
│                                                                 │
│  📧 vorname.nachname@schule.niedersachsen.de                   │
│     └── Bildungsportal Niedersachsen                           │
│                                                                 │
│  📧 personal@grundschule-xy.de                                 │
│     └── Personalverwaltung, Vertretungsplanung                 │
│                                                                 │
│  📧 verwaltung@grundschule-xy.de                               │
│     └── Schulträger (Kommune), Haushalt                        │
│                                                                 │
│  PROBLEME:                                                      │
│  ❌ 4 verschiedene Logins                                       │
│  ❌ Fristen werden übersehen                                    │
│  ❌ Keine einheitliche Übersicht                                │
│  ❌ Keine KI-Unterstützung                                      │
│  ❌ Kein gemeinsamer Kalender                                   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.2 Die Lösung: BreakPilot Unified Inbox

┌─────────────────────────────────────────────────────────────────┐
│                    BREAKPILOT UNIFIED INBOX                     │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │              EINHEITLICHES FRONTEND                      │   │
│  │                                                         │   │
│  │  📥 Posteingang (alle Konten)                          │   │
│  │  📋 Arbeitsvorrat (KI-extrahierte Aufgaben)            │   │
│  │  📅 Kalender (Jitsi-integriert)                        │   │
│  │  💬 Chat (Matrix E2EE)                                 │   │
│  │  📹 Meetings (Jitsi)                                   │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                           │                                     │
│                           ▼                                     │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │              KI-ASSISTENZ-LAYER                         │   │
│  │                                                         │   │
│  │  🤖 Absender-Erkennung (welche Behörde?)               │   │
│  │  📆 Fristen-Extraktion (Deadline-Tracking)             │   │
│  │  ✍️  Antwort-Vorschläge (vorformuliert)                │   │
│  │  🏷️  Automatische Kategorisierung                      │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                           │                                     │
│                           ▼                                     │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │              MULTI-ACCOUNT AGGREGATOR                   │   │
│  │                                                         │   │
│  │  IMAP/SMTP ──► schulleitung@grundschule-xy.de          │   │
│  │  IMAP/SMTP ──► vorname.nachname@schule.nds.de          │   │
│  │  IMAP/SMTP ──► personal@grundschule-xy.de              │   │
│  │  IMAP/SMTP ──► verwaltung@grundschule-xy.de            │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

1.3 Zielgruppen

Zielgruppe Nutzung Priorität
BreakPilot GmbH intern Interne Kommunikation, Proof-of-Concept P0
Schulleitungen Multi-Account-Aggregation, KI-Assistenz P0
Lehrkräfte Optionales Angebot, funktionale Mailboxen P1
Schulträger White-Label-Lösung für ihre Schulen P2

2. Kern-Features

2.1 Multi-Account Aggregation

┌─────────────────────────────────────────────────────────────────┐
│                    ACCOUNT-AGGREGATION                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  UNTERSTÜTZTE PROTOKOLLE:                                      │
│  ├── IMAP/IMAPS (Lesen)                                        │
│  ├── SMTP/SMTPS (Senden)                                       │
│  ├── OAuth2 (Microsoft 365, Google)                            │
│  └── Exchange Web Services (EWS)                               │
│                                                                 │
│  PRO KONTO GESPEICHERT:                                        │
│  ├── Server-Konfiguration (verschlüsselt)                      │
│  ├── Credentials (Vault-verschlüsselt)                         │
│  ├── Display-Name und Farbe                                    │
│  ├── Absender-Identität                                        │
│  └── Signatur (HTML/Text)                                      │
│                                                                 │
│  SYNCHRONISATION:                                               │
│  ├── Polling-Intervall: 1-5 Minuten (konfigurierbar)          │
│  ├── Push: IMAP IDLE (wenn unterstützt)                       │
│  └── Full-Sync: 1x täglich (Konsistenzprüfung)                │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

2.2 KI-Assistenz-Features

┌─────────────────────────────────────────────────────────────────┐
│                    KI-ASSISTENZ                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  1. ABSENDER-ERKENNUNG                                         │
│     ┌─────────────────────────────────────────────────────┐    │
│     │ Von: info@landesschulbehoerde.niedersachsen.de      │    │
│     │                                                     │    │
│     │ 🏛️ Erkannt als: Landesschulbehörde Niedersachsen   │    │
│     │ 📁 Kategorie: Behördliche Mitteilung               │    │
│     │ ⚠️  Priorität: Hoch (enthält Fristsetzung)         │    │
│     └─────────────────────────────────────────────────────┘    │
│                                                                 │
│  2. FRISTEN-EXTRAKTION                                         │
│     ┌─────────────────────────────────────────────────────┐    │
│     │ "...bitten wir um Rückmeldung bis zum 15.02.2026"  │    │
│     │                                                     │    │
│     │ 📆 Erkannte Frist: 15. Februar 2026                │    │
│     │ ⏰ Erinnerung: 3 Tage vorher                       │    │
│     │ ✅ Zum Arbeitsvorrat hinzufügen                    │    │
│     └─────────────────────────────────────────────────────┘    │
│                                                                 │
│  3. ANTWORT-VORSCHLÄGE                                         │
│     ┌─────────────────────────────────────────────────────┐    │
│     │ Betreff: Bestätigung Terminvorschlag               │    │
│     │                                                     │    │
│     │ 💡 Vorschlag 1: "Hiermit bestätige ich den..."    │    │
│     │ 💡 Vorschlag 2: "Ich bitte um einen Alternativ..." │    │
│     │ 💡 Vorschlag 3: "Aufgrund von ... ist mir ..."    │    │
│     └─────────────────────────────────────────────────────┘    │
│                                                                 │
│  4. KATEGORISIERUNG                                            │
│     ├── 🏛️ Behörde (Landesschulbehörde, Kultusministerium)   │
│     ├── 🏢 Schulträger (Kommune, Kreis)                       │
│     ├── 👥 Personal (Vertretung, Krankheit, Fortbildung)      │
│     ├── 📚 Pädagogik (Curricula, Prüfungen)                   │
│     ├── 💰 Haushalt (Budget, Beschaffung)                     │
│     └── 📋 Sonstiges                                          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

2.3 Arbeitsvorrat (Task-Management)

┌─────────────────────────────────────────────────────────────────┐
│                    ARBEITSVORRAT                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ 🔴 ÜBERFÄLLIG (2)                                       │   │
│  ├─────────────────────────────────────────────────────────┤   │
│  │ ☐ Statistik-Meldung Schülerzahlen      Frist: 05.01.  │   │
│  │   └── Von: Landesschulbehörde          ⚠️ 5 Tage über  │   │
│  │ ☐ Haushaltsentwurf 2026                Frist: 08.01.  │   │
│  │   └── Von: Stadt Musterstadt           ⚠️ 2 Tage über  │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ 🟡 DIESE WOCHE (3)                                      │   │
│  ├─────────────────────────────────────────────────────────┤   │
│  │ ☐ Fortbildungsanträge genehmigen       Frist: 12.01.  │   │
│  │ ☐ Elternbrief Halbjahreszeugnis        Frist: 14.01.  │   │
│  │ ☐ Rückmeldung Prüfungstermine          Frist: 15.01.  │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ 🟢 SPÄTER (5)                                           │   │
│  ├─────────────────────────────────────────────────────────┤   │
│  │ ☐ Jahresbericht erstellen              Frist: 31.01.  │   │
│  │ ☐ Medienkonzept aktualisieren          Frist: 28.02.  │   │
│  │ ...                                                     │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  FEATURES:                                                      │
│  ├── Automatische Frist-Erkennung aus E-Mails                  │
│  ├── Manuelle Aufgaben hinzufügen                              │
│  ├── Erinnerungen (E-Mail, Push, Matrix)                       │
│  ├── Delegation an Kollegium                                   │
│  ├── Verknüpfung mit Original-E-Mail                           │
│  └── Export nach iCal/Outlook                                  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

2.4 Integrationen

┌─────────────────────────────────────────────────────────────────┐
│                    INTEGRATIONEN                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  📅 KALENDER (CalDAV)                                          │
│  ├── Termine aus E-Mails extrahieren                           │
│  ├── Meeting-Einladungen erstellen                             │
│  ├── Jitsi-Link automatisch hinzufügen                         │
│  ├── Sync mit externen Kalendern                               │
│  └── Fristübersicht im Kalender                                │
│                                                                 │
│  📹 JITSI (Video-Meetings)                                     │
│  ├── Ein-Klick-Meeting aus E-Mail                              │
│  ├── Einladung an alle Beteiligten                             │
│  ├── Warteraum für externe Teilnehmer                          │
│  └── Aufzeichnung (optional, mit Consent)                      │
│                                                                 │
│  💬 MATRIX (E2EE Chat)                                         │
│  ├── Schnelle Rückfragen an Kollegium                          │
│  ├── Kanal pro Thema/Fachbereich                               │
│  ├── E-Mail zu Chat: "Dazu besprechen wir uns kurz"           │
│  └── Verschlüsselung für sensible Themen                       │
│                                                                 │
│  🤖 KI-SERVICES                                                │
│  ├── Fristen-Extraktion (NLP)                                  │
│  ├── Absender-Klassifikation                                   │
│  ├── Antwort-Generierung (optional)                            │
│  └── Zusammenfassung langer E-Mails                            │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

3. Architektur

3.1 System-Übersicht

┌────────────────────────────────────────────────────────────────────────┐
│                     BREAKPILOT UNIFIED INBOX                            │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│  ┌──────────────────────────────────────────────────────────────────┐ │
│  │                       FRONTEND LAYER                              │ │
│  ├──────────────────────────────────────────────────────────────────┤ │
│  │  ┌────────────────┐  ┌────────────────┐  ┌────────────────┐      │ │
│  │  │   Web App      │  │  Mobile PWA    │  │  Desktop App   │      │ │
│  │  │   (Next.js)    │  │  (React)       │  │  (Electron)    │      │ │
│  │  │   :3000        │  │  PWA           │  │  Optional      │      │ │
│  │  └────────┬───────┘  └────────┬───────┘  └────────┬───────┘      │ │
│  └───────────┼───────────────────┼───────────────────┼──────────────┘ │
│              │                   │                   │                 │
│              └───────────────────┼───────────────────┘                 │
│                                  │                                     │
│  ┌──────────────────────────────┴───────────────────────────────────┐ │
│  │                      API GATEWAY (Go)                             │ │
│  │                      :8088                                        │ │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐               │ │
│  │  │ Auth        │  │ Rate Limit  │  │ Logging     │               │ │
│  │  │ (JWT/OIDC)  │  │             │  │ (Audit)     │               │ │
│  │  └─────────────┘  └─────────────┘  └─────────────┘               │ │
│  └──────────────────────────────┬───────────────────────────────────┘ │
│                                 │                                      │
│  ┌──────────────────────────────┴───────────────────────────────────┐ │
│  │                     APPLICATION LAYER                             │ │
│  ├───────────────────┬───────────────────┬──────────────────────────┤ │
│  │                   │                   │                          │ │
│  │  ┌─────────────┐  │  ┌─────────────┐  │  ┌─────────────┐        │ │
│  │  │ Mail        │  │  │ AI          │  │  │ Task        │        │ │
│  │  │ Aggregator  │  │  │ Service     │  │  │ Service     │        │ │
│  │  │ (Python)    │  │  │ (Python)    │  │  │ (Python)    │        │ │
│  │  │ :8089       │  │  │ :8090       │  │  │ :8091       │        │ │
│  │  └──────┬──────┘  │  └──────┬──────┘  │  └──────┬──────┘        │ │
│  │         │         │         │         │         │                │ │
│  │  ┌──────┴──────┐  │  ┌──────┴──────┐  │  ┌──────┴──────┐        │ │
│  │  │ IMAP/SMTP   │  │  │ LLM         │  │  │ PostgreSQL  │        │ │
│  │  │ Connectors  │  │  │ Gateway     │  │  │ Tasks DB    │        │ │
│  │  └─────────────┘  │  └─────────────┘  │  └─────────────┘        │ │
│  │                   │                   │                          │ │
│  └───────────────────┴───────────────────┴──────────────────────────┘ │
│                                 │                                      │
│  ┌──────────────────────────────┴───────────────────────────────────┐ │
│  │                       DATA LAYER                                  │ │
│  ├───────────────────┬───────────────────┬──────────────────────────┤ │
│  │  ┌─────────────┐  │  ┌─────────────┐  │  ┌─────────────┐        │ │
│  │  │ PostgreSQL  │  │  │ Redis       │  │  │ MinIO       │        │ │
│  │  │ (Main DB)   │  │  │ (Cache)     │  │  │ (Attachm.)  │        │ │
│  │  │ :5432       │  │  │ :6379       │  │  │ :9000       │        │ │
│  │  └─────────────┘  │  └─────────────┘  │  └─────────────┘        │ │
│  │                   │                   │                          │ │
│  │  ┌─────────────┐  │  ┌─────────────┐  │  ┌─────────────┐        │ │
│  │  │ Vault       │  │  │ Qdrant      │  │  │ Stalwart    │        │ │
│  │  │ (Secrets)   │  │  │ (Vectors)   │  │  │ (Own Mail)  │        │ │
│  │  │ :8200       │  │  │ :6333       │  │  │ :25/143     │        │ │
│  │  └─────────────┘  │  └─────────────┘  │  └─────────────┘        │ │
│  └───────────────────┴───────────────────┴──────────────────────────┘ │
│                                                                        │
│  ┌──────────────────────────────────────────────────────────────────┐ │
│  │                    EXTERNAL CONNECTIONS                           │ │
│  ├──────────────────────────────────────────────────────────────────┤ │
│  │                                                                  │ │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │ │
│  │  │ Externe     │  │ Jitsi       │  │ Matrix      │              │ │
│  │  │ IMAP/SMTP   │  │ :8443       │  │ :8008       │              │ │
│  │  │ Server      │  │             │  │             │              │ │
│  │  └─────────────┘  └─────────────┘  └─────────────┘              │ │
│  │                                                                  │ │
│  └──────────────────────────────────────────────────────────────────┘ │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘

3.2 Mail Aggregator Service

# unified_inbox/services/mail_aggregator.py

"""
Mail Aggregator Service

Aggregiert E-Mails aus mehreren externen IMAP-Konten und
stellt sie in einer einheitlichen Inbox bereit.

WICHTIG: Credentials werden niemals im Klartext gespeichert!
         Alle Zugangsdaten liegen verschlüsselt in Vault.
"""

from dataclasses import dataclass
from datetime import datetime
from typing import List, Optional, Dict, Any
from enum import Enum
import asyncio
import aioimaplib
import aiosmtplib

class AccountType(str, Enum):
    IMAP = "imap"
    OAUTH_MICROSOFT = "oauth_microsoft"
    OAUTH_GOOGLE = "oauth_google"
    EWS = "ews"

@dataclass
class ExternalAccount:
    """Externes E-Mail-Konto"""
    id: str
    user_id: str  # BreakPilot User

    # Identität
    email_address: str
    display_name: str
    color: str  # Für UI-Unterscheidung

    # Server-Konfiguration
    account_type: AccountType
    imap_host: str
    imap_port: int
    smtp_host: str
    smtp_port: int
    use_ssl: bool

    # Credentials (Vault-Referenz, nicht Klartext!)
    vault_secret_path: str

    # Sync-Status
    last_sync: Optional[datetime]
    sync_state: str  # UIDVALIDITY, HIGHESTMODSEQ

    # Features
    supports_idle: bool
    signature_html: Optional[str]
    signature_text: Optional[str]

@dataclass
class AggregatedEmail:
    """E-Mail aus einem externen Konto"""
    id: str
    account_id: str  # Welches Konto

    # E-Mail-Daten
    message_id: str
    subject: str
    from_address: str
    from_name: str
    to_addresses: List[str]
    cc_addresses: List[str]
    date: datetime
    body_text: str
    body_html: Optional[str]
    has_attachments: bool

    # Aggregator-Metadaten
    fetched_at: datetime
    is_read: bool
    is_flagged: bool
    folder: str

    # KI-Analyse (später befüllt)
    ai_category: Optional[str]
    ai_priority: Optional[str]
    ai_sender_type: Optional[str]
    ai_extracted_deadline: Optional[datetime]
    ai_summary: Optional[str]

class MailAggregator:
    """
    Aggregiert E-Mails aus mehreren externen Konten.

    Prinzipien:
    1. Credentials niemals im Speicher halten (nur kurz während Verbindung)
    2. E-Mail-Inhalte werden verschlüsselt gecacht
    3. Vollständiger Audit-Trail
    """

    def __init__(
        self,
        db: AsyncSession,
        vault_client: VaultClient,
        cache: RedisClient,
        ai_service: AIService
    ):
        self.db = db
        self.vault = vault_client
        self.cache = cache
        self.ai = ai_service
        self._connections: Dict[str, aioimaplib.IMAP4_SSL] = {}

    async def add_account(
        self,
        user_id: str,
        account_config: ExternalAccountConfig
    ) -> ExternalAccount:
        """
        Fügt ein externes E-Mail-Konto hinzu.

        1. Validiert Credentials (Test-Verbindung)
        2. Speichert Credentials in Vault
        3. Erstellt Account-Eintrag in DB
        """
        # 1. Test-Verbindung
        await self._test_connection(account_config)

        # 2. Credentials in Vault speichern
        vault_path = f"secret/mail-accounts/{user_id}/{account_config.email_address}"
        await self.vault.write(vault_path, {
            "username": account_config.username,
            "password": account_config.password,
            "oauth_token": account_config.oauth_token,
        })

        # 3. Account in DB (ohne Credentials!)
        account = ExternalAccount(
            id=str(uuid.uuid4()),
            user_id=user_id,
            email_address=account_config.email_address,
            display_name=account_config.display_name,
            color=account_config.color or self._generate_color(),
            account_type=account_config.account_type,
            imap_host=account_config.imap_host,
            imap_port=account_config.imap_port,
            smtp_host=account_config.smtp_host,
            smtp_port=account_config.smtp_port,
            use_ssl=account_config.use_ssl,
            vault_secret_path=vault_path,
            last_sync=None,
            sync_state="",
            supports_idle=False,  # Wird beim ersten Sync ermittelt
            signature_html=account_config.signature_html,
            signature_text=account_config.signature_text,
        )

        await self._save_account(account)

        # Initial-Sync anstoßen
        asyncio.create_task(self.sync_account(account.id))

        return account

    async def sync_account(self, account_id: str) -> SyncResult:
        """
        Synchronisiert ein E-Mail-Konto.

        Verwendet IMAP IDLE wenn verfügbar, sonst Polling.
        """
        account = await self._get_account(account_id)

        # Credentials aus Vault holen (nur für diese Operation)
        credentials = await self.vault.read(account.vault_secret_path)

        try:
            async with self._get_imap_connection(account, credentials) as imap:
                # Neue E-Mails abrufen
                new_emails = await self._fetch_new_emails(imap, account)

                # KI-Analyse für jede neue E-Mail
                for email in new_emails:
                    email.ai_analysis = await self.ai.analyze_email(email)

                # In lokale DB speichern
                await self._save_emails(new_emails)

                # Sync-Status aktualisieren
                account.last_sync = datetime.utcnow()
                await self._save_account(account)

                return SyncResult(
                    success=True,
                    new_count=len(new_emails),
                    account_id=account_id
                )
        finally:
            # Credentials sofort aus Speicher löschen
            credentials = None

    async def send_email(
        self,
        account_id: str,
        to: List[str],
        subject: str,
        body_html: str,
        body_text: str,
        cc: Optional[List[str]] = None,
        attachments: Optional[List[Attachment]] = None
    ) -> SendResult:
        """
        Sendet eine E-Mail über das angegebene Konto.

        Die E-Mail wird im Namen des externen Kontos gesendet,
        nicht über den BreakPilot Mail-Server.
        """
        account = await self._get_account(account_id)
        credentials = await self.vault.read(account.vault_secret_path)

        try:
            message = self._build_message(
                account=account,
                to=to,
                subject=subject,
                body_html=body_html,
                body_text=body_text,
                cc=cc,
                attachments=attachments
            )

            async with aiosmtplib.SMTP(
                hostname=account.smtp_host,
                port=account.smtp_port,
                use_tls=account.use_ssl
            ) as smtp:
                await smtp.login(credentials["username"], credentials["password"])
                await smtp.send_message(message)

            # Audit-Log
            await self._log_sent_email(account_id, to, subject)

            return SendResult(success=True, message_id=message["Message-ID"])
        finally:
            credentials = None

    async def get_unified_inbox(
        self,
        user_id: str,
        filters: Optional[InboxFilters] = None,
        page: int = 1,
        per_page: int = 50
    ) -> UnifiedInboxResponse:
        """
        Gibt die vereinheitlichte Inbox zurück.

        Alle Konten werden zusammengeführt, aber
        das Quell-Konto ist immer erkennbar (Farbe, Icon).
        """
        accounts = await self._get_user_accounts(user_id)
        account_ids = [a.id for a in accounts]

        # E-Mails aus allen Konten laden
        query = """
            SELECT * FROM aggregated_emails
            WHERE account_id = ANY($1)
        """

        if filters:
            if filters.unread_only:
                query += " AND is_read = false"
            if filters.account_id:
                query += f" AND account_id = '{filters.account_id}'"
            if filters.category:
                query += f" AND ai_category = '{filters.category}'"
            if filters.has_deadline:
                query += " AND ai_extracted_deadline IS NOT NULL"

        query += " ORDER BY date DESC"
        query += f" LIMIT {per_page} OFFSET {(page - 1) * per_page}"

        emails = await self.db.fetch_all(query, account_ids)

        # Account-Info hinzufügen
        account_map = {a.id: a for a in accounts}
        for email in emails:
            email.account = account_map[email.account_id]

        return UnifiedInboxResponse(
            emails=emails,
            total=await self._count_emails(user_id, filters),
            page=page,
            per_page=per_page
        )

3.3 KI-Analyse-Service

# unified_inbox/services/ai_service.py

"""
AI Service für E-Mail-Analyse

Funktionen:
1. Absender-Erkennung (Behörde, Schulträger, etc.)
2. Fristen-Extraktion
3. Antwort-Vorschläge
4. Kategorisierung
"""

from dataclasses import dataclass
from datetime import datetime
from typing import List, Optional, Dict
import re

@dataclass
class EmailAnalysis:
    """Ergebnis der KI-Analyse"""
    # Absender-Klassifikation
    sender_type: str  # "behoerde", "schultraeger", "eltern", "sonstige"
    sender_organization: Optional[str]  # z.B. "Landesschulbehörde Niedersachsen"

    # Kategorisierung
    category: str  # "personal", "haushalt", "paedagogik", "verwaltung"
    priority: str  # "hoch", "mittel", "niedrig"

    # Fristen
    has_deadline: bool
    deadline_date: Optional[datetime]
    deadline_text: Optional[str]  # Original-Text mit Frist

    # Zusammenfassung
    summary: str  # 1-2 Sätze
    action_required: bool
    suggested_action: Optional[str]

    # Antwort-Vorschläge
    response_suggestions: List[str]

    # Confidence
    confidence: float  # 0.0 - 1.0

class AIEmailService:
    """
    KI-gestützte E-Mail-Analyse.

    Verwendet lokales LLM oder API (konfigurierbar).
    """

    # Bekannte Absender-Muster für Niedersachsen
    SENDER_PATTERNS = {
        "landesschulbehoerde": {
            "domains": ["nlschb.niedersachsen.de", "landesschulbehoerde.niedersachsen.de"],
            "type": "behoerde",
            "organization": "Landesschulbehörde Niedersachsen"
        },
        "kultusministerium": {
            "domains": ["mk.niedersachsen.de"],
            "type": "behoerde",
            "organization": "Kultusministerium Niedersachsen"
        },
        "bildungsportal": {
            "domains": ["schule.niedersachsen.de", "nibis.de"],
            "type": "behoerde",
            "organization": "Bildungsportal Niedersachsen"
        },
        # Schulträger werden dynamisch aus Domain erkannt
    }

    # Frist-Erkennungsmuster
    DEADLINE_PATTERNS = [
        r"bis zum (\d{1,2}\.\d{1,2}\.\d{4})",
        r"bis spätestens (\d{1,2}\.\d{1,2}\.\d{4})",
        r"Frist[:\s]+(\d{1,2}\.\d{1,2}\.\d{4})",
        r"Rückmeldung bis (\d{1,2}\.\d{1,2}\.\d{4})",
        r"Abgabetermin[:\s]+(\d{1,2}\.\d{1,2}\.\d{4})",
        r"innerhalb von (\d+) (Tagen|Wochen)",
    ]

    def __init__(self, llm_client: LLMClient):
        self.llm = llm_client

    async def analyze_email(self, email: AggregatedEmail) -> EmailAnalysis:
        """
        Analysiert eine E-Mail vollständig.
        """
        # 1. Absender-Erkennung (regelbasiert + LLM)
        sender_info = await self._classify_sender(email)

        # 2. Fristen-Extraktion
        deadline_info = await self._extract_deadline(email)

        # 3. Kategorisierung und Priorität
        category_info = await self._categorize(email, sender_info)

        # 4. Zusammenfassung und Aktions-Vorschlag
        summary_info = await self._summarize(email)

        # 5. Antwort-Vorschläge generieren
        responses = await self._generate_responses(email, sender_info, summary_info)

        return EmailAnalysis(
            sender_type=sender_info["type"],
            sender_organization=sender_info.get("organization"),
            category=category_info["category"],
            priority=category_info["priority"],
            has_deadline=deadline_info["has_deadline"],
            deadline_date=deadline_info.get("date"),
            deadline_text=deadline_info.get("text"),
            summary=summary_info["summary"],
            action_required=summary_info["action_required"],
            suggested_action=summary_info.get("action"),
            response_suggestions=responses,
            confidence=self._calculate_confidence(sender_info, deadline_info)
        )

    async def _classify_sender(self, email: AggregatedEmail) -> Dict:
        """Klassifiziert den Absender."""
        from_domain = email.from_address.split("@")[1].lower()

        # Regelbasierte Erkennung
        for key, pattern in self.SENDER_PATTERNS.items():
            if from_domain in pattern["domains"]:
                return {
                    "type": pattern["type"],
                    "organization": pattern["organization"],
                    "confidence": 0.95
                }

        # Fallback: LLM-basierte Erkennung
        prompt = f"""
        Klassifiziere den Absender dieser E-Mail:

        Von: {email.from_name} <{email.from_address}>
        Betreff: {email.subject}

        Mögliche Kategorien:
        - behoerde (Schulbehörde, Ministerium, etc.)
        - schultraeger (Kommune, Kreis, Stadt)
        - eltern (Eltern, Elternvertreter)
        - kollegium (andere Lehrkräfte)
        - sonstige

        Antworte nur mit der Kategorie und optional dem Organisationsnamen.
        Format: kategorie|organisationsname
        """

        response = await self.llm.complete(prompt, max_tokens=50)
        parts = response.strip().split("|")

        return {
            "type": parts[0] if parts else "sonstige",
            "organization": parts[1] if len(parts) > 1 else None,
            "confidence": 0.7
        }

    async def _extract_deadline(self, email: AggregatedEmail) -> Dict:
        """Extrahiert Fristen aus der E-Mail."""
        text = email.body_text or ""

        for pattern in self.DEADLINE_PATTERNS:
            match = re.search(pattern, text, re.IGNORECASE)
            if match:
                deadline_str = match.group(1)

                # Versuche Datum zu parsen
                try:
                    if "Tagen" in deadline_str or "Wochen" in deadline_str:
                        # Relative Frist
                        num = int(re.search(r"\d+", deadline_str).group())
                        unit = "weeks" if "Wochen" in deadline_str else "days"
                        deadline_date = email.date + timedelta(**{unit: num})
                    else:
                        # Absolutes Datum
                        deadline_date = datetime.strptime(deadline_str, "%d.%m.%Y")

                    return {
                        "has_deadline": True,
                        "date": deadline_date,
                        "text": match.group(0),
                        "confidence": 0.9
                    }
                except:
                    pass

        # LLM-Fallback für komplexere Fristen
        prompt = f"""
        Enthält diese E-Mail eine Frist oder einen Abgabetermin?

        Betreff: {email.subject}
        Text: {email.body_text[:1000]}

        Wenn ja, antworte mit: JA|DATUM|ORIGINALTEXT
        Wenn nein, antworte mit: NEIN
        """

        response = await self.llm.complete(prompt, max_tokens=100)

        if response.startswith("JA"):
            parts = response.split("|")
            if len(parts) >= 2:
                try:
                    return {
                        "has_deadline": True,
                        "date": datetime.strptime(parts[1].strip(), "%d.%m.%Y"),
                        "text": parts[2] if len(parts) > 2 else None,
                        "confidence": 0.7
                    }
                except:
                    pass

        return {"has_deadline": False}

    async def _generate_responses(
        self,
        email: AggregatedEmail,
        sender_info: Dict,
        summary_info: Dict
    ) -> List[str]:
        """Generiert Antwort-Vorschläge."""

        prompt = f"""
        Generiere 3 kurze, professionelle Antwort-Vorschläge für diese E-Mail.

        Kontext:
        - Absender: {sender_info.get('organization', email.from_name)} ({sender_info['type']})
        - Betreff: {email.subject}
        - Zusammenfassung: {summary_info['summary']}

        Antworte im folgenden Format:
        1. [Erste Antwort-Option]
        2. [Zweite Antwort-Option]
        3. [Dritte Antwort-Option]

        Die Antworten sollten:
        - Formell und respektvoll sein
        - Zur Situation passen
        - Unterschiedliche Optionen bieten (zustimmen, nachfragen, ablehnen)
        """

        response = await self.llm.complete(prompt, max_tokens=500)

        # Parse die drei Vorschläge
        suggestions = []
        for line in response.split("\n"):
            if line.strip().startswith(("1.", "2.", "3.")):
                suggestion = line.split(".", 1)[1].strip()
                if suggestion:
                    suggestions.append(suggestion)

        return suggestions[:3]

4. Datenmodell

4.1 SQL Schema

-- ============================================================
-- UNIFIED INBOX SCHEMA
-- Version: 2.0.0
-- ============================================================

-- Externe E-Mail-Konten
CREATE TABLE external_email_accounts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,

    -- Identität
    email_address VARCHAR(255) NOT NULL,
    display_name VARCHAR(255) NOT NULL,
    color VARCHAR(7) NOT NULL DEFAULT '#3B82F6',  -- Hex-Farbe

    -- Server-Konfiguration
    account_type VARCHAR(50) NOT NULL DEFAULT 'imap',
    imap_host VARCHAR(255) NOT NULL,
    imap_port INTEGER NOT NULL DEFAULT 993,
    smtp_host VARCHAR(255) NOT NULL,
    smtp_port INTEGER NOT NULL DEFAULT 587,
    use_ssl BOOLEAN NOT NULL DEFAULT true,

    -- Credentials (Vault-Referenz!)
    vault_secret_path VARCHAR(500) NOT NULL,

    -- Sync-Status
    last_sync TIMESTAMP,
    sync_state JSONB DEFAULT '{}',
    sync_error VARCHAR(500),
    supports_idle BOOLEAN DEFAULT false,

    -- Signaturen
    signature_html TEXT,
    signature_text TEXT,

    -- Status
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),

    -- Constraints
    CONSTRAINT unique_user_email UNIQUE (user_id, email_address)
);

CREATE INDEX idx_eea_user ON external_email_accounts(user_id);

-- Aggregierte E-Mails (Cache)
CREATE TABLE aggregated_emails (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    account_id UUID NOT NULL REFERENCES external_email_accounts(id) ON DELETE CASCADE,

    -- E-Mail-Identifikation
    message_id VARCHAR(500) NOT NULL,
    uid INTEGER,  -- IMAP UID

    -- E-Mail-Daten
    subject VARCHAR(1000),
    from_address VARCHAR(255) NOT NULL,
    from_name VARCHAR(255),
    to_addresses JSONB NOT NULL DEFAULT '[]',
    cc_addresses JSONB DEFAULT '[]',
    date TIMESTAMP NOT NULL,

    -- Inhalt (verschlüsselt gespeichert)
    body_text_encrypted BYTEA,
    body_html_encrypted BYTEA,
    has_attachments BOOLEAN DEFAULT false,
    attachment_info JSONB DEFAULT '[]',

    -- Status
    is_read BOOLEAN DEFAULT false,
    is_flagged BOOLEAN DEFAULT false,
    is_deleted BOOLEAN DEFAULT false,
    folder VARCHAR(255) DEFAULT 'INBOX',

    -- KI-Analyse
    ai_sender_type VARCHAR(50),
    ai_sender_organization VARCHAR(255),
    ai_category VARCHAR(50),
    ai_priority VARCHAR(20),
    ai_has_deadline BOOLEAN DEFAULT false,
    ai_deadline_date TIMESTAMP,
    ai_deadline_text VARCHAR(500),
    ai_summary TEXT,
    ai_action_required BOOLEAN DEFAULT false,
    ai_suggested_action TEXT,
    ai_response_suggestions JSONB DEFAULT '[]',
    ai_analyzed_at TIMESTAMP,
    ai_confidence FLOAT,

    -- Metadaten
    fetched_at TIMESTAMP DEFAULT NOW(),
    raw_headers JSONB,

    -- Constraints
    CONSTRAINT unique_message UNIQUE (account_id, message_id)
);

CREATE INDEX idx_ae_account ON aggregated_emails(account_id);
CREATE INDEX idx_ae_date ON aggregated_emails(date DESC);
CREATE INDEX idx_ae_unread ON aggregated_emails(is_read) WHERE is_read = false;
CREATE INDEX idx_ae_deadline ON aggregated_emails(ai_deadline_date) WHERE ai_has_deadline = true;
CREATE INDEX idx_ae_category ON aggregated_emails(ai_category);

-- Arbeitsvorrat (Tasks)
CREATE TABLE inbox_tasks (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,

    -- Quelle
    source_type VARCHAR(50) NOT NULL DEFAULT 'email',  -- email, manual, calendar
    source_email_id UUID REFERENCES aggregated_emails(id),

    -- Task-Daten
    title VARCHAR(500) NOT NULL,
    description TEXT,
    category VARCHAR(50),
    priority VARCHAR(20) DEFAULT 'mittel',

    -- Frist
    deadline TIMESTAMP,
    reminder_at TIMESTAMP,
    reminder_sent BOOLEAN DEFAULT false,

    -- Status
    status VARCHAR(20) DEFAULT 'offen',  -- offen, in_bearbeitung, erledigt, delegiert
    completed_at TIMESTAMP,

    -- Delegation
    delegated_to UUID REFERENCES users(id),
    delegated_at TIMESTAMP,
    delegation_note TEXT,

    -- Metadaten
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),
    created_by VARCHAR(50) DEFAULT 'ai',  -- ai, manual

    -- Ursprungs-Account (für Kontext)
    account_id UUID REFERENCES external_email_accounts(id)
);

CREATE INDEX idx_it_user ON inbox_tasks(user_id);
CREATE INDEX idx_it_deadline ON inbox_tasks(deadline);
CREATE INDEX idx_it_status ON inbox_tasks(status);
CREATE INDEX idx_it_source ON inbox_tasks(source_email_id);

-- Absender-Klassifikation (für schnellere Erkennung)
CREATE TABLE sender_classifications (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- Identifikation
    email_domain VARCHAR(255) NOT NULL,
    email_pattern VARCHAR(255),  -- z.B. "*@landesschulbehoerde.niedersachsen.de"

    -- Klassifikation
    sender_type VARCHAR(50) NOT NULL,
    organization_name VARCHAR(255),

    -- Region (für länderspezifische Behörden)
    bundesland VARCHAR(50),

    -- Vertrauen
    confidence FLOAT DEFAULT 1.0,
    verified BOOLEAN DEFAULT false,
    verified_by UUID,

    created_at TIMESTAMP DEFAULT NOW(),

    CONSTRAINT unique_domain UNIQUE (email_domain)
);

-- Seed-Daten für Niedersachsen
INSERT INTO sender_classifications (email_domain, sender_type, organization_name, bundesland, verified) VALUES
('nlschb.niedersachsen.de', 'behoerde', 'Landesschulbehörde Niedersachsen', 'niedersachsen', true),
('landesschulbehoerde.niedersachsen.de', 'behoerde', 'Landesschulbehörde Niedersachsen', 'niedersachsen', true),
('mk.niedersachsen.de', 'behoerde', 'Kultusministerium Niedersachsen', 'niedersachsen', true),
('schule.niedersachsen.de', 'behoerde', 'Bildungsportal Niedersachsen', 'niedersachsen', true),
('nibis.de', 'behoerde', 'NiBiS - Niedersächsischer Bildungsserver', 'niedersachsen', true),
('rlsb.de', 'behoerde', 'Regionales Landesamt für Schule und Bildung', 'niedersachsen', true);

-- Antwort-Vorlagen
CREATE TABLE response_templates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- Zuordnung
    user_id UUID REFERENCES users(id),  -- NULL = global
    sender_type VARCHAR(50),            -- Für welchen Absender-Typ
    category VARCHAR(50),               -- Für welche Kategorie

    -- Vorlage
    name VARCHAR(255) NOT NULL,
    subject_template VARCHAR(500),
    body_template TEXT NOT NULL,

    -- Platzhalter-Info
    placeholders JSONB DEFAULT '[]',  -- ["{{anrede}}", "{{datum}}"]

    -- Status
    is_active BOOLEAN DEFAULT true,
    usage_count INTEGER DEFAULT 0,
    created_at TIMESTAMP DEFAULT NOW()
);

-- Audit-Log für E-Mail-Aktionen
CREATE TABLE email_audit_log (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    user_id UUID NOT NULL REFERENCES users(id),
    account_id UUID REFERENCES external_email_accounts(id),
    email_id UUID REFERENCES aggregated_emails(id),

    action VARCHAR(50) NOT NULL,  -- read, sent, deleted, delegated
    details JSONB,

    ip_address INET,
    user_agent VARCHAR(500),

    created_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_eal_user ON email_audit_log(user_id);
CREATE INDEX idx_eal_created ON email_audit_log(created_at);

5. API-Endpunkte

5.1 Accounts API

/api/v1/unified-inbox/accounts:
  get:
    summary: Liste aller verbundenen E-Mail-Konten
    responses:
      200:
        description: Account-Liste mit Sync-Status

  post:
    summary: Neues E-Mail-Konto verbinden
    requestBody:
      content:
        application/json:
          schema:
            type: object
            required: [email_address, imap_host, smtp_host, username, password]
            properties:
              email_address:
                type: string
                format: email
              display_name:
                type: string
              color:
                type: string
              imap_host:
                type: string
              imap_port:
                type: integer
                default: 993
              smtp_host:
                type: string
              smtp_port:
                type: integer
                default: 587
              username:
                type: string
              password:
                type: string
                format: password
    responses:
      201:
        description: Account erfolgreich verbunden

/api/v1/unified-inbox/accounts/{account_id}:
  delete:
    summary: E-Mail-Konto trennen
    description: Entfernt das Konto und alle gecachten E-Mails
    responses:
      200:
        description: Account getrennt

  post:
    summary: Konto synchronisieren
    parameters:
      - name: action
        in: query
        schema:
          type: string
          enum: [sync, test]
    responses:
      200:
        description: Sync gestartet oder Test erfolgreich

5.2 Inbox API

/api/v1/unified-inbox/emails:
  get:
    summary: Vereinheitlichte Inbox
    parameters:
      - name: account_id
        in: query
        description: Filter nach Konto (optional)
        schema:
          type: string
          format: uuid
      - name: category
        in: query
        schema:
          type: string
          enum: [behoerde, schultraeger, personal, haushalt, paedagogik, sonstige]
      - name: priority
        in: query
        schema:
          type: string
          enum: [hoch, mittel, niedrig]
      - name: has_deadline
        in: query
        schema:
          type: boolean
      - name: unread_only
        in: query
        schema:
          type: boolean
      - name: page
        in: query
        schema:
          type: integer
          default: 1
    responses:
      200:
        description: E-Mail-Liste mit KI-Analyse

/api/v1/unified-inbox/emails/{email_id}:
  get:
    summary: E-Mail-Details
    responses:
      200:
        description: Vollständige E-Mail mit Analyse

  patch:
    summary: E-Mail aktualisieren (lesen, markieren)
    requestBody:
      content:
        application/json:
          schema:
            type: object
            properties:
              is_read:
                type: boolean
              is_flagged:
                type: boolean

/api/v1/unified-inbox/emails/{email_id}/reply:
  post:
    summary: Auf E-Mail antworten
    requestBody:
      content:
        application/json:
          schema:
            type: object
            required: [body_text]
            properties:
              body_text:
                type: string
              body_html:
                type: string
              use_suggestion:
                type: integer
                description: Index des Antwort-Vorschlags (0-2)

5.3 Tasks API

/api/v1/unified-inbox/tasks:
  get:
    summary: Arbeitsvorrat
    parameters:
      - name: status
        in: query
        schema:
          type: string
          enum: [offen, in_bearbeitung, erledigt, delegiert, ueberfaellig]
      - name: priority
        in: query
        schema:
          type: string
      - name: deadline_before
        in: query
        schema:
          type: string
          format: date
    responses:
      200:
        description: Task-Liste

  post:
    summary: Manuelle Aufgabe erstellen
    requestBody:
      content:
        application/json:
          schema:
            type: object
            required: [title]
            properties:
              title:
                type: string
              description:
                type: string
              deadline:
                type: string
                format: date-time
              priority:
                type: string
              link_to_email:
                type: string
                format: uuid

/api/v1/unified-inbox/tasks/{task_id}:
  patch:
    summary: Task aktualisieren
    requestBody:
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: string
                enum: [offen, in_bearbeitung, erledigt]
              priority:
                type: string
              deadline:
                type: string
                format: date-time

/api/v1/unified-inbox/tasks/{task_id}/delegate:
  post:
    summary: Task delegieren
    requestBody:
      content:
        application/json:
          schema:
            type: object
            required: [delegate_to]
            properties:
              delegate_to:
                type: string
                format: uuid
              note:
                type: string

6. Sicherheit

6.1 Credential-Management

┌─────────────────────────────────────────────────────────────────┐
│                 CREDENTIAL SECURITY                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  NIEMALS IM KLARTEXT:                                          │
│  ├── Passwörter werden direkt nach Eingabe an Vault gesendet   │
│  ├── Im Backend nur als Vault-Referenz gespeichert             │
│  ├── Credentials werden bei jeder Verbindung neu aus Vault     │
│  │   gelesen und sofort nach Nutzung verworfen                 │
│  └── Audit-Log für jeden Vault-Zugriff                         │
│                                                                 │
│  VAULT-STRUKTUR:                                                │
│  secret/                                                        │
│  └── mail-accounts/                                             │
│      └── {user_id}/                                             │
│          └── {email_address}/                                   │
│              ├── username                                       │
│              ├── password (verschlüsselt)                      │
│              └── oauth_token (wenn OAuth)                      │
│                                                                 │
│  ROTATION:                                                      │
│  ├── OAuth-Tokens: Automatisch via Refresh-Token               │
│  └── Passwörter: Bei Änderung durch Nutzer                     │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

6.2 E-Mail-Inhalt-Verschlüsselung

# E-Mail-Inhalte werden at-rest verschlüsselt

class EmailEncryption:
    """
    Verschlüsselt E-Mail-Inhalte vor der Speicherung.

    - Jeder User hat einen eigenen Encryption Key
    - Keys liegen in Vault, nicht in der DB
    - Bei User-Löschung: Key vernichten = Daten unlesbar
    """

    async def encrypt_email_content(
        self,
        user_id: str,
        body_text: str,
        body_html: Optional[str]
    ) -> Tuple[bytes, Optional[bytes]]:
        # User-spezifischen Key aus Vault holen
        key = await self.vault.read(f"secret/user-keys/{user_id}/email-key")

        # Verschlüsseln
        encrypted_text = self._encrypt(body_text, key)
        encrypted_html = self._encrypt(body_html, key) if body_html else None

        return encrypted_text, encrypted_html

    async def decrypt_email_content(
        self,
        user_id: str,
        encrypted_text: bytes,
        encrypted_html: Optional[bytes]
    ) -> Tuple[str, Optional[str]]:
        key = await self.vault.read(f"secret/user-keys/{user_id}/email-key")

        text = self._decrypt(encrypted_text, key)
        html = self._decrypt(encrypted_html, key) if encrypted_html else None

        return text, html

7. BreakPilot GmbH Interne Nutzung

7.1 Dual-Use-Konzept

┌─────────────────────────────────────────────────────────────────┐
│                    DUAL-USE ARCHITEKTUR                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  BREAKPILOT GMBH (Intern)                                      │
│  ├── Eigene Domain: @breakpilot.de                             │
│  ├── Eigener Mail-Server (Stalwart)                            │
│  ├── Funktionale Mailboxen für Rollen                          │
│  │   ├── support@breakpilot.de                                 │
│  │   ├── sales@breakpilot.de                                   │
│  │   ├── datenschutz@breakpilot.de                             │
│  │   └── buchhaltung@breakpilot.de                             │
│  ├── Mitarbeiter-Anonymisierung bei Ausscheiden                │
│  └── Volle Matrix/Jitsi/Kalender-Integration                   │
│                                                                 │
│  SCHULEN (Kunden)                                              │
│  ├── Option A: Unified Inbox                                   │
│  │   └── Aggregiert externe Konten (IMAP)                      │
│  │       ├── schulleitung@grundschule-xy.de                    │
│  │       ├── vorname.nachname@schule.nds.de                    │
│  │       └── weitere...                                        │
│  │                                                             │
│  ├── Option B: Gehostete Mailboxen                             │
│  │   └── @schule.breakpilot.app                                │
│  │       ├── schulleitung@grundschule.breakpilot.app          │
│  │       ├── sekretariat@grundschule.breakpilot.app           │
│  │       └── weitere...                                        │
│  │                                                             │
│  └── Option C: Hybrid                                          │
│      ├── Gehostete BreakPilot-Mailbox für Alltag               │
│      └── + Aggregation externer Pflicht-Konten                 │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

7.2 Internes Dogfooding

BreakPilot GmbH nutzt das System selbst:

1. Alle Mitarbeiter haben @breakpilot.de Mailboxen
2. Funktionale Adressen für Abteilungen
3. Vollständige KI-Assistenz im Alltag
4. Beweis der Funktionalität für Kunden
5. Kontinuierliche Verbesserung durch eigene Nutzung

8. Roadmap

Phase 1: Foundation (6-8 Wochen)

  • Mail Aggregator Service (IMAP/SMTP)
  • Account-Management (hinzufügen, entfernen, sync)
  • Unified Inbox UI (Basic)
  • Credential-Management (Vault)
  • BreakPilot interne Nutzung

Phase 2: KI-Integration (4-6 Wochen)

  • Absender-Erkennung (regelbasiert + LLM)
  • Fristen-Extraktion
  • Kategorisierung
  • Prioritäts-Scoring
  • Niedersachsen-spezifische Behörden-DB

Phase 3: Arbeitsvorrat (3-4 Wochen)

  • Task-Extraktion aus E-Mails
  • Deadline-Tracking
  • Erinnerungen (E-Mail, Push)
  • Kalender-Integration
  • Delegation

Phase 4: Antwort-Assistenz (3-4 Wochen)

  • Antwort-Vorschläge (LLM)
  • Vorlagen-Management
  • Ein-Klick-Antworten
  • Signatur-Management

Phase 5: Integrationen (4-6 Wochen)

  • Jitsi-Integration (Meetings aus E-Mail)
  • Matrix-Integration (Chat-Verknüpfung)
  • CalDAV-Sync
  • Mobile PWA

Phase 6: Erweiterung (Ongoing)

  • Weitere Bundesländer
  • OAuth-Support (Microsoft 365, Google)
  • Exchange Web Services
  • Desktop-App (Electron)

9. Referenzdokumente

Diese Spezifikation ergänzt:

  1. Mail-RBAC Architektur: /docs/architecture/mail-rbac-architecture.md
  2. Mail-RBAC Developer Spec: /docs/klausur-modul/MAIL-RBAC-DEVELOPER-SPECIFICATION.md
  3. DSGVO-Konzept: /docs/architecture/dsgvo-compliance.md

Anhang: Niedersachsen-spezifische Informationen

Behörden und ihre Domains

Behörde Domain(s) Typische Inhalte
Landesschulbehörde nlschb.niedersachsen.de Statistiken, Personal, Genehmigungen
Kultusministerium mk.niedersachsen.de Erlasse, Verordnungen
Bildungsportal schule.niedersachsen.de Account-Info, Fortbildungen
NiBiS nibis.de Curricula, Materialien
RLSB rlsb.de Regionale Verwaltung

Typische Fristen

Anlass Übliche Frist Häufigkeit
Schülerzahlen-Statistik September/März 2x jährlich
Haushaltsentwurf November 1x jährlich
Prüfungstermine Dezember/Januar 1x jährlich
Personalplanung Februar 1x jährlich
Fortbildungsanträge Laufend Variabel