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>
723 lines
23 KiB
Markdown
723 lines
23 KiB
Markdown
# Mail-RBAC Architektur mit Mitarbeiter-Anonymisierung
|
|
|
|
**Version:** 1.0.0
|
|
**Datum:** 2026-01-10
|
|
**Status:** Architekturplanung
|
|
|
|
---
|
|
|
|
## Executive Summary
|
|
|
|
Dieses Dokument beschreibt eine neuartige Architektur, die E-Mail, Kalender und Videokonferenzen mit rollenbasierter Zugriffskontrolle (RBAC) verbindet. Das Kernkonzept ermöglicht die **vollständige Anonymisierung von Mitarbeiterdaten** bei Verlassen des Unternehmens, während geschäftliche Kommunikationshistorie erhalten bleibt.
|
|
|
|
**Wichtig:** Dieses Konzept existiert in dieser Form noch nicht als fertige Lösung auf dem Markt. Es handelt sich um eine innovative Architektur, die entwickelt werden muss.
|
|
|
|
---
|
|
|
|
## 1. Das Problem
|
|
|
|
### Traditionelle E-Mail-Systeme
|
|
```
|
|
max.mustermann@firma.de → Person gebunden
|
|
→ DSGVO: Daten müssen gelöscht werden
|
|
→ Geschäftshistorie geht verloren
|
|
```
|
|
|
|
### BreakPilot-Lösung: Rollenbasierte E-Mail
|
|
```
|
|
klassenlehrer.5a@schule.breakpilot.app → Rolle gebunden
|
|
→ Person kann anonymisiert werden
|
|
→ Kommunikationshistorie bleibt erhalten
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Architektur-Übersicht
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ BreakPilot Groupware │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
│ │ Webmail │ │ Kalender │ │ Jitsi │ │
|
|
│ │ (SOGo) │ │ (SOGo) │ │ Meeting │ │
|
|
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
|
│ │ │ │ │
|
|
│ └────────────────┼────────────────┘ │
|
|
│ │ │
|
|
│ ┌───────────┴───────────┐ │
|
|
│ │ RBAC-Mail-Bridge │ ◄─── Neue Komponente │
|
|
│ │ (Python/Go) │ │
|
|
│ └───────────┬───────────┘ │
|
|
│ │ │
|
|
│ ┌─────────────────────┼─────────────────────┐ │
|
|
│ │ │ │ │
|
|
│ ▼ ▼ ▼ │
|
|
│ ┌──────────┐ ┌──────────────┐ ┌────────────┐ │
|
|
│ │PostgreSQL│ │ Mail Server │ │ MinIO │ │
|
|
│ │(RBAC DB) │ │ (Stalwart) │ │ (Backups) │ │
|
|
│ └──────────┘ └──────────────┘ └────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Komponenten-Auswahl
|
|
|
|
### 3.1 E-Mail Server: Stalwart Mail Server
|
|
|
|
**Empfehlung:** [Stalwart Mail Server](https://stalw.art/)
|
|
|
|
| Kriterium | Bewertung |
|
|
|-----------|-----------|
|
|
| Lizenz | AGPL-3.0 (Open Source) |
|
|
| Sprache | Rust (performant, sicher) |
|
|
| Features | IMAP, SMTP, JMAP, WebSocket |
|
|
| Kalender | CalDAV integriert |
|
|
| Kontakte | CardDAV integriert |
|
|
| Spam/Virus | Integriert |
|
|
| API | REST API für Administration |
|
|
|
|
**Lizenz-Implikation für kommerzielle Nutzung:**
|
|
- AGPL-3.0 erfordert Veröffentlichung von Änderungen am Stalwart-Code selbst
|
|
- Nutzung als Service ohne Code-Änderungen: keine Veröffentlichungspflicht
|
|
- Unsere RBAC-Bridge ist separater Code: kann proprietär bleiben
|
|
|
|
### 3.2 Webmail-Client: SOGo oder Roundcube
|
|
|
|
**Option A: SOGo** (empfohlen)
|
|
- Lizenz: GPL-2.0 / LGPL-2.1
|
|
- Kalender, Kontakte, Mail in einem
|
|
- ActiveSync Support
|
|
- Outlook-ähnliche Oberfläche
|
|
|
|
**Option B: Roundcube**
|
|
- Lizenz: GPL-3.0
|
|
- Nur Webmail
|
|
- Benötigt separaten Kalender
|
|
|
|
### 3.3 Kalender-Integration
|
|
|
|
Stalwart bietet CalDAV, kann mit:
|
|
- SOGo Webinterface
|
|
- Thunderbird
|
|
- iOS/Android Kalender
|
|
- Outlook (via CalDAV Plugin)
|
|
|
|
### 3.4 Jitsi-Integration
|
|
|
|
Bereits vorhanden in BreakPilot:
|
|
- `backend/jitsi_api.py` - Meeting-Erstellung
|
|
- `email_service.py` - Jitsi-Einladungen per E-Mail
|
|
- Kalender-Events können Jitsi-Links enthalten
|
|
|
|
---
|
|
|
|
## 4. Datenmodell für Rollen-E-Mail
|
|
|
|
### 4.1 Neue Datenbank-Tabellen
|
|
|
|
```sql
|
|
-- Funktionale E-Mail-Adressen (rollengebunden)
|
|
CREATE TABLE functional_mailboxes (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
|
|
-- Rolle und Mailbox
|
|
role_key VARCHAR(100) NOT NULL, -- z.B. "klassenlehrer_5a"
|
|
email_address VARCHAR(255) UNIQUE NOT NULL, -- z.B. "klassenlehrer.5a@schule.bp.app"
|
|
display_name VARCHAR(255) NOT NULL, -- z.B. "Klassenlehrer 5a"
|
|
|
|
-- Zuordnung
|
|
tenant_id UUID NOT NULL REFERENCES tenants(id),
|
|
resource_type VARCHAR(50) DEFAULT 'class', -- class, department, function
|
|
resource_id VARCHAR(100), -- z.B. "5a" oder "mathematik"
|
|
|
|
-- Status
|
|
is_active BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
|
|
CONSTRAINT fk_role FOREIGN KEY (role_key)
|
|
REFERENCES roles(role_key) ON DELETE RESTRICT
|
|
);
|
|
|
|
-- Zuordnung: Welche Person hat welche funktionale Mailbox
|
|
CREATE TABLE mailbox_assignments (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
|
|
mailbox_id UUID NOT NULL REFERENCES functional_mailboxes(id),
|
|
user_id UUID NOT NULL REFERENCES users(id),
|
|
|
|
-- Zeitraum
|
|
valid_from TIMESTAMP DEFAULT NOW(),
|
|
valid_to TIMESTAMP,
|
|
|
|
-- Audit
|
|
assigned_by UUID REFERENCES users(id),
|
|
assigned_at TIMESTAMP DEFAULT NOW(),
|
|
revoked_by UUID,
|
|
revoked_at TIMESTAMP,
|
|
|
|
-- Constraints
|
|
CONSTRAINT unique_active_assignment
|
|
UNIQUE (mailbox_id, user_id)
|
|
WHERE revoked_at IS NULL
|
|
);
|
|
|
|
-- Persönliche E-Mail-Adressen (für Anonymisierung)
|
|
CREATE TABLE personal_email_accounts (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES users(id),
|
|
|
|
-- E-Mail
|
|
email_address VARCHAR(255) UNIQUE NOT NULL,
|
|
|
|
-- Anonymisierungsstatus
|
|
is_anonymized BOOLEAN DEFAULT false,
|
|
anonymized_at TIMESTAMP,
|
|
anonymized_by UUID,
|
|
|
|
-- Original-Daten (verschlüsselt, für DSGVO-Auskunft)
|
|
original_name_encrypted BYTEA,
|
|
original_email_encrypted BYTEA,
|
|
encryption_key_id VARCHAR(100),
|
|
|
|
-- Audit
|
|
created_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
-- Audit-Trail für E-Mail-Kommunikation (ohne personenbezogene Daten)
|
|
CREATE TABLE email_audit_trail (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
|
|
-- Kommunikation
|
|
mailbox_id UUID REFERENCES functional_mailboxes(id),
|
|
direction VARCHAR(10) NOT NULL, -- 'inbound', 'outbound'
|
|
|
|
-- Metadaten (keine Inhalte!)
|
|
subject_hash VARCHAR(64), -- SHA-256 für Deduplizierung
|
|
timestamp TIMESTAMP NOT NULL,
|
|
external_party_domain VARCHAR(255), -- z.B. "eltern.de" (nicht volle Adresse)
|
|
|
|
-- Rolle zum Zeitpunkt
|
|
role_key VARCHAR(100) NOT NULL,
|
|
|
|
-- Person NICHT gespeichert - nur über Assignment nachvollziehbar
|
|
-- Bei Anonymisierung: Assignment-User wird anonymisiert
|
|
|
|
created_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
-- Anonymisierungsprotokoll (DSGVO-Nachweis)
|
|
CREATE TABLE anonymization_log (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
|
|
-- Was wurde anonymisiert
|
|
entity_type VARCHAR(50) NOT NULL, -- 'user', 'email_account'
|
|
entity_id UUID NOT NULL,
|
|
|
|
-- Wie
|
|
anonymization_type VARCHAR(50) NOT NULL, -- 'pseudonymization', 'deletion'
|
|
fields_affected JSONB NOT NULL,
|
|
|
|
-- Warum
|
|
reason VARCHAR(100) NOT NULL, -- 'employee_departure', 'dsgvo_request'
|
|
|
|
-- Audit
|
|
performed_by UUID NOT NULL,
|
|
performed_at TIMESTAMP DEFAULT NOW(),
|
|
|
|
-- Bestätigung
|
|
legal_basis VARCHAR(255), -- z.B. "Art. 17 DSGVO"
|
|
retention_period_days INTEGER
|
|
);
|
|
```
|
|
|
|
### 4.2 Anonymisierungs-Workflow
|
|
|
|
```
|
|
Mitarbeiter kündigt
|
|
│
|
|
▼
|
|
┌───────────────────────────┐
|
|
│ 1. Functional Mailboxes │
|
|
│ → Neu zuweisen oder │
|
|
│ → Deaktivieren │
|
|
└───────────┬───────────────┘
|
|
│
|
|
▼
|
|
┌───────────────────────────┐
|
|
│ 2. Personal Email Account │
|
|
│ → Anonymisieren: │
|
|
│ max.mustermann@... │
|
|
│ → mitarbeiter_a7x2@... │
|
|
└───────────────────────────┘
|
|
│
|
|
▼
|
|
┌───────────────────────────┐
|
|
│ 3. Users-Tabelle │
|
|
│ → Pseudonymisieren: │
|
|
│ name: "Max Mustermann" │
|
|
│ → "Ehem. Mitarbeiter" │
|
|
└───────────────────────────┘
|
|
│
|
|
▼
|
|
┌───────────────────────────┐
|
|
│ 4. Mailbox Assignments │
|
|
│ → Bleiben für Audit │
|
|
│ → User-Referenz zeigt │
|
|
│ auf anonymisierte │
|
|
│ Daten │
|
|
└───────────────────────────┘
|
|
│
|
|
▼
|
|
┌───────────────────────────┐
|
|
│ 5. E-Mail-Archiv │
|
|
│ → Header anonymisieren │
|
|
│ → Inhalte optional │
|
|
│ löschen │
|
|
└───────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 5. RBAC-Mail-Bridge Implementierung
|
|
|
|
### 5.1 Python-Komponente
|
|
|
|
```python
|
|
# rbac_mail_bridge/anonymizer.py
|
|
|
|
class EmployeeAnonymizer:
|
|
"""
|
|
Anonymisiert Mitarbeiterdaten bei Ausscheiden.
|
|
Erhält Audit-Trail und funktionale Zuordnungen.
|
|
"""
|
|
|
|
async def anonymize_employee(
|
|
self,
|
|
user_id: str,
|
|
reason: str,
|
|
performed_by: str
|
|
) -> AnonymizationResult:
|
|
"""
|
|
Vollständige Anonymisierung eines Mitarbeiters.
|
|
|
|
Schritte:
|
|
1. Functional Mailboxes neu zuweisen
|
|
2. Personal Email anonymisieren
|
|
3. User-Daten pseudonymisieren
|
|
4. E-Mail-Archive bereinigen
|
|
5. Audit-Log erstellen
|
|
"""
|
|
|
|
async with self.db.transaction():
|
|
# 1. Functional Mailboxes
|
|
assignments = await self.get_active_assignments(user_id)
|
|
for assignment in assignments:
|
|
await self.revoke_assignment(
|
|
assignment.id,
|
|
revoked_by=performed_by,
|
|
reason="employee_departure"
|
|
)
|
|
|
|
# 2. Personal Email
|
|
personal_email = await self.get_personal_email(user_id)
|
|
if personal_email:
|
|
# Verschlüssele Original für DSGVO-Auskunft
|
|
encrypted = await self.encrypt_for_retention(
|
|
personal_email.email_address,
|
|
personal_email.display_name
|
|
)
|
|
|
|
# Anonymisiere
|
|
anon_email = f"user_{generate_random_id()}@anon.local"
|
|
await self.db.execute("""
|
|
UPDATE personal_email_accounts
|
|
SET
|
|
email_address = $1,
|
|
is_anonymized = true,
|
|
anonymized_at = NOW(),
|
|
original_email_encrypted = $2
|
|
WHERE user_id = $3
|
|
""", anon_email, encrypted, user_id)
|
|
|
|
# 3. User-Daten
|
|
await self.db.execute("""
|
|
UPDATE users SET
|
|
name = 'Ehemaliger Mitarbeiter',
|
|
email = $1,
|
|
is_active = false,
|
|
anonymized_at = NOW()
|
|
WHERE id = $2
|
|
""", f"anon_{user_id[:8]}@deleted.local", user_id)
|
|
|
|
# 4. E-Mail-Archive
|
|
await self.mail_server.anonymize_mailbox(user_id)
|
|
|
|
# 5. Audit-Log
|
|
await self.create_anonymization_log(
|
|
entity_type="user",
|
|
entity_id=user_id,
|
|
reason=reason,
|
|
performed_by=performed_by
|
|
)
|
|
|
|
return AnonymizationResult(success=True)
|
|
```
|
|
|
|
### 5.2 API-Endpunkte
|
|
|
|
```python
|
|
# rbac_mail_bridge/api.py
|
|
|
|
router = APIRouter(prefix="/api/v1/mail-rbac", tags=["mail-rbac"])
|
|
|
|
@router.get("/mailboxes")
|
|
async def list_functional_mailboxes(
|
|
user: Dict = Depends(get_current_admin)
|
|
) -> List[FunctionalMailbox]:
|
|
"""Liste aller funktionalen Mailboxen"""
|
|
pass
|
|
|
|
@router.post("/mailboxes")
|
|
async def create_functional_mailbox(
|
|
mailbox: FunctionalMailboxCreate,
|
|
user: Dict = Depends(get_current_admin)
|
|
) -> FunctionalMailbox:
|
|
"""Erstellt eine rollengebundene Mailbox"""
|
|
pass
|
|
|
|
@router.post("/mailboxes/{mailbox_id}/assign")
|
|
async def assign_mailbox_to_user(
|
|
mailbox_id: str,
|
|
assignment: MailboxAssignment,
|
|
user: Dict = Depends(get_current_admin)
|
|
) -> Assignment:
|
|
"""Weist eine Mailbox einem Benutzer zu"""
|
|
pass
|
|
|
|
@router.post("/users/{user_id}/anonymize")
|
|
async def anonymize_user(
|
|
user_id: str,
|
|
request: AnonymizationRequest,
|
|
user: Dict = Depends(get_current_admin)
|
|
) -> AnonymizationResult:
|
|
"""Anonymisiert einen ausgeschiedenen Mitarbeiter"""
|
|
pass
|
|
|
|
@router.get("/audit/anonymizations")
|
|
async def list_anonymizations(
|
|
user: Dict = Depends(get_current_admin)
|
|
) -> List[AnonymizationLog]:
|
|
"""Liste aller Anonymisierungen (DSGVO-Nachweis)"""
|
|
pass
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Docker-Compose Integration
|
|
|
|
```yaml
|
|
# docker-compose.yml Erweiterung
|
|
|
|
services:
|
|
# ... bestehende Services ...
|
|
|
|
# Stalwart Mail Server
|
|
stalwart:
|
|
image: stalwartlabs/mail-server:latest
|
|
container_name: breakpilot-mail
|
|
hostname: mail.breakpilot.local
|
|
ports:
|
|
- "25:25" # SMTP
|
|
- "143:143" # IMAP
|
|
- "465:465" # SMTPS
|
|
- "993:993" # IMAPS
|
|
- "4190:4190" # ManageSieve
|
|
- "8080:8080" # Web Admin
|
|
volumes:
|
|
- stalwart-data:/opt/stalwart-mail/data
|
|
- ./config/stalwart:/opt/stalwart-mail/etc
|
|
environment:
|
|
- STALWART_HOSTNAME=mail.breakpilot.local
|
|
networks:
|
|
- breakpilot-pwa-network
|
|
depends_on:
|
|
- postgres
|
|
profiles:
|
|
- mail # Nur mit --profile mail starten
|
|
|
|
# SOGo Groupware (Webmail + Kalender)
|
|
sogo:
|
|
image: sogo/sogo:latest
|
|
container_name: breakpilot-sogo
|
|
ports:
|
|
- "20000:20000"
|
|
volumes:
|
|
- ./config/sogo:/etc/sogo
|
|
environment:
|
|
- SOGO_HOSTNAME=groupware.breakpilot.local
|
|
depends_on:
|
|
- stalwart
|
|
- postgres
|
|
networks:
|
|
- breakpilot-pwa-network
|
|
profiles:
|
|
- mail
|
|
|
|
# RBAC-Mail-Bridge
|
|
rbac-mail-bridge:
|
|
build:
|
|
context: ./rbac-mail-bridge
|
|
dockerfile: Dockerfile
|
|
container_name: breakpilot-rbac-mail
|
|
environment:
|
|
- DATABASE_URL=${DATABASE_URL}
|
|
- STALWART_API_URL=http://stalwart:8080
|
|
- STALWART_API_KEY=${STALWART_API_KEY}
|
|
depends_on:
|
|
- postgres
|
|
- stalwart
|
|
networks:
|
|
- breakpilot-pwa-network
|
|
profiles:
|
|
- mail
|
|
|
|
volumes:
|
|
stalwart-data:
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Admin-UI im Frontend
|
|
|
|
### 7.1 Neue Admin-Seite: `/admin/mail-management`
|
|
|
|
```tsx
|
|
// website/app/admin/mail-management/page.tsx
|
|
|
|
// Tabs:
|
|
// 1. Funktionale Mailboxen
|
|
// - Liste aller rollengebundenen Adressen
|
|
// - Zuweisungen verwalten
|
|
//
|
|
// 2. Mitarbeiter E-Mail
|
|
// - Persönliche Accounts
|
|
// - Anonymisierungs-Status
|
|
//
|
|
// 3. Anonymisierung
|
|
// - Mitarbeiter-Offboarding
|
|
// - Anonymisierungs-Wizard
|
|
//
|
|
// 4. Audit-Log
|
|
// - Alle Anonymisierungen
|
|
// - DSGVO-Export
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Lizenz-Übersicht
|
|
|
|
| Komponente | Lizenz | Kommerzielle Nutzung | Veröffentlichungspflicht |
|
|
|------------|--------|---------------------|-------------------------|
|
|
| Stalwart Mail | AGPL-3.0 | Ja | Nur bei Code-Änderungen |
|
|
| SOGo | GPL-2.0/LGPL | Ja | Nur bei Code-Änderungen |
|
|
| Roundcube | GPL-3.0 | Ja | Nur bei Code-Änderungen |
|
|
| RBAC-Mail-Bridge | Eigene | N/A | Kann proprietär bleiben |
|
|
| BreakPilot Backend | Eigene | N/A | Proprietär |
|
|
|
|
**Empfehlung:** Bei reiner Nutzung der Open-Source-Komponenten ohne Code-Änderungen besteht keine Veröffentlichungspflicht. Die RBAC-Mail-Bridge ist unser eigener Code.
|
|
|
|
---
|
|
|
|
## 9. Implementierungsreihenfolge
|
|
|
|
### Phase 1: Grundlagen (2-3 Wochen Entwicklung)
|
|
1. Datenbank-Schema erstellen
|
|
2. RBAC-Mail-Bridge Backend
|
|
3. Basic API-Endpunkte
|
|
|
|
### Phase 2: Mail-Server Integration
|
|
4. Stalwart konfigurieren
|
|
5. SOGo als Webclient
|
|
6. LDAP/OAuth Bridge
|
|
|
|
### Phase 3: Anonymisierung
|
|
7. Anonymisierungs-Service
|
|
8. E-Mail-Archive-Bereinigung
|
|
9. DSGVO-Export-Funktion
|
|
|
|
### Phase 4: Frontend
|
|
10. Admin-UI erstellen
|
|
11. Offboarding-Wizard
|
|
12. Audit-Dashboard
|
|
|
|
### Phase 5: Kalender & Jitsi
|
|
13. CalDAV Integration
|
|
14. Jitsi-Meeting-Einladungen aus Kalender
|
|
15. Mobile Sync (ActiveSync/CardDAV)
|
|
|
|
---
|
|
|
|
## 10. Existiert das schon?
|
|
|
|
**Kurze Antwort: Nein, nicht in dieser Form.**
|
|
|
|
### Ähnliche Konzepte:
|
|
|
|
1. **Funktionale Mailboxen** (existiert)
|
|
- Shared Mailboxes in Exchange/Microsoft 365
|
|
- Group Addresses in Google Workspace
|
|
- → Aber: Keine RBAC-Integration, keine Anonymisierung
|
|
|
|
2. **DSGVO-Löschung** (existiert)
|
|
- Standard: Konto komplett löschen
|
|
- → Aber: Verlust der Geschäftshistorie
|
|
|
|
3. **Pseudonymisierung** (existiert als Konzept)
|
|
- In Forschungsdatenbanken üblich
|
|
- → Aber: Nicht für E-Mail-Systeme implementiert
|
|
|
|
### Was BreakPilot anders macht:
|
|
|
|
```
|
|
Traditionell:
|
|
max.mustermann@firma.de → Kündigung → Löschen → Historie weg
|
|
|
|
BreakPilot:
|
|
klassenlehrer.5a@schule.bp.app ← Max Mustermann zugeordnet
|
|
← Maria Müller übernimmt
|
|
← Historie bleibt, Person anonymisiert
|
|
```
|
|
|
|
**Fazit:** Das Konzept ist innovativ und müsste entwickelt werden. Es gibt keine fertige Open-Source-Lösung, die all diese Features kombiniert.
|
|
|
|
---
|
|
|
|
## 11. Alternative: Minimale Implementation
|
|
|
|
Falls das vollständige System zu komplex ist, gibt es eine minimale Variante:
|
|
|
|
### 11.1 Nur Functional Mailboxes
|
|
|
|
```sql
|
|
-- Minimales Schema
|
|
CREATE TABLE role_email_aliases (
|
|
id UUID PRIMARY KEY,
|
|
role_key VARCHAR(100) UNIQUE NOT NULL,
|
|
email_alias VARCHAR(255) UNIQUE NOT NULL, -- klassenlehrer.5a@...
|
|
forward_to UUID REFERENCES users(id), -- Aktuelle Person
|
|
is_active BOOLEAN DEFAULT true
|
|
);
|
|
```
|
|
|
|
- Keine eigene Mail-Infrastruktur
|
|
- Aliases werden an persönliche Adressen weitergeleitet
|
|
- Bei Kündigung: Alias umleiten
|
|
- Limitation: Keine echte Anonymisierung der Historie
|
|
|
|
### 11.2 Mailpit als Development-Only
|
|
|
|
Bestehendes Mailpit bleibt für Entwicklung:
|
|
- Kein Produktions-Mailserver
|
|
- Externe Mails über Gmail/Microsoft
|
|
- Functional Mailboxes als Konzept in DB
|
|
|
|
---
|
|
|
|
## 12. Nächste Schritte
|
|
|
|
1. **Entscheidung:** Vollständiges System oder minimale Variante?
|
|
2. **Proof of Concept:** Functional Mailboxes mit bestehendem RBAC
|
|
3. **Evaluierung:** Stalwart Mail Server in Testumgebung
|
|
4. **Architektur-Review:** Mit Datenschutzbeauftragtem abstimmen
|
|
|
|
---
|
|
|
|
## Anhang A: Referenzen
|
|
|
|
- [Stalwart Mail Server](https://stalw.art/)
|
|
- [SOGo Groupware](https://www.sogo.nu/)
|
|
- [Roundcube Webmail](https://roundcube.net/)
|
|
- [CalDAV Standard](https://tools.ietf.org/html/rfc4791)
|
|
- [DSGVO Art. 17 - Recht auf Löschung](https://dsgvo-gesetz.de/art-17-dsgvo/)
|
|
|
|
## Anhang B: Bestehende BreakPilot-Integration
|
|
|
|
- RBAC-System: `/backend/rbac_api.py`
|
|
- E-Mail-Service: `/backend/email_service.py`
|
|
- Jitsi-Integration: `/backend/jitsi_api.py`
|
|
- Mailpit-Config: `docker-compose.yml:193-202`
|
|
|
|
---
|
|
|
|
## Anhang C: Unified Inbox Implementation (2026-01)
|
|
|
|
### Implementierte Komponenten
|
|
|
|
Die Unified Inbox wurde als Teil des klausur-service implementiert:
|
|
|
|
| Komponente | Pfad | Beschreibung |
|
|
|------------|------|--------------|
|
|
| **Models** | `klausur-service/backend/mail/models.py` | Pydantic Models für Accounts, E-Mails, Tasks |
|
|
| **Database** | `klausur-service/backend/mail/mail_db.py` | PostgreSQL-Operationen mit asyncpg |
|
|
| **Credentials** | `klausur-service/backend/mail/credentials.py` | Vault-Integration für IMAP/SMTP-Passwörter |
|
|
| **Aggregator** | `klausur-service/backend/mail/aggregator.py` | Multi-Account IMAP Sync |
|
|
| **AI Service** | `klausur-service/backend/mail/ai_service.py` | KI-Analyse (Absender, Fristen, Kategorien) |
|
|
| **Task Service** | `klausur-service/backend/mail/task_service.py` | Arbeitsvorrat-Management |
|
|
| **API** | `klausur-service/backend/mail/api.py` | FastAPI Router mit 30+ Endpoints |
|
|
|
|
### Frontend-Komponenten
|
|
|
|
| Komponente | Pfad | Beschreibung |
|
|
|------------|------|--------------|
|
|
| **Admin UI** | `website/app/admin/mail/page.tsx` | Kontenverwaltung, KI-Einstellungen |
|
|
| **User Inbox** | `website/app/mail/page.tsx` | Unified Inbox mit KI-Panel |
|
|
| **Arbeitsvorrat** | `website/app/mail/tasks/page.tsx` | Task-Management Dashboard |
|
|
|
|
### API-Endpoints (Port 8086)
|
|
|
|
```
|
|
# Account Management
|
|
POST /api/v1/mail/accounts - Neues Konto hinzufügen
|
|
GET /api/v1/mail/accounts - Alle Konten auflisten
|
|
DELETE /api/v1/mail/accounts/{id} - Konto entfernen
|
|
POST /api/v1/mail/accounts/{id}/test - Verbindung testen
|
|
|
|
# Unified Inbox
|
|
GET /api/v1/mail/inbox - Aggregierte Inbox
|
|
GET /api/v1/mail/inbox/{id} - Einzelne E-Mail
|
|
POST /api/v1/mail/send - E-Mail senden
|
|
|
|
# KI-Features
|
|
POST /api/v1/mail/analyze/{id} - E-Mail analysieren
|
|
GET /api/v1/mail/suggestions/{id} - Antwortvorschläge
|
|
|
|
# Arbeitsvorrat
|
|
GET /api/v1/mail/tasks - Alle Tasks
|
|
POST /api/v1/mail/tasks - Manuelle Task erstellen
|
|
PATCH /api/v1/mail/tasks/{id} - Task aktualisieren
|
|
GET /api/v1/mail/tasks/dashboard - Dashboard-Statistiken
|
|
```
|
|
|
|
### Niedersachsen-spezifische Absendererkennung
|
|
|
|
```python
|
|
KNOWN_AUTHORITIES_NI = {
|
|
"@mk.niedersachsen.de": "Kultusministerium Niedersachsen",
|
|
"@rlsb.de": "Regionales Landesamt für Schule und Bildung",
|
|
"@landesschulbehoerde-nds.de": "Landesschulbehörde",
|
|
"@nibis.de": "NiBiS",
|
|
}
|
|
```
|
|
|
|
### LLM-Playbook für E-Mail-Analyse
|
|
|
|
Das Playbook `mail_analysis` in `/backend/llm_gateway/services/playbook_service.py` enthält:
|
|
- Absender-Klassifikation (12 Typen)
|
|
- Fristenerkennung mit Datumsextraktion
|
|
- Kategorisierung (11 Kategorien)
|
|
- Prioritätsvorschlag
|