# T06: Mail Plugin Backend — Implementation Briefing ## Task Implement the complete Mail Plugin as a built-in plugin under `app/plugins/builtins/mail/`. ## Requirements (F-MAIL-01 bis F-MAIL-19) - F-MAIL-01: Standard-Ordner (Posteingang, Postausgang, Entwürfe, Spam) + IMAP-Sync - F-MAIL-02: E-Mail schreiben, antworten, weiterleiten (HTML-Editor, SMTP) - F-MAIL-03: Volltext-Suche über Mails (body_tsv, FTS) - F-MAIL-04: Anhänge (hochladen, herunterladen, DMS-Link) - F-MAIL-05: Threading (Konversationen gruppieren, References/In-Reply-To) - F-MAIL-06: Vorlagen/Templates (Platzhalter-Substitution) - F-MAIL-07: Filter/Regeln (Condition → Action: move/label/flag/forward) - F-MAIL-08: Abwesenheitsnotiz (Auto-Reply, dedup via vacation_sent_log) - F-MAIL-09: Labels/Flags (Stern, Wichtig, Custom Labels, farbig) - F-MAIL-10: Kontakt-Verknüpfung (auto aus Email-Adressen, manuell) - F-MAIL-11: Kalender-Integration (Termin aus Mail erstellen) - F-MAIL-12: PGP-Verschlüsselung (Key-Import, encrypt/decrypt, contact public keys) - F-MAIL-13: Signaturen (pro User, pro Postfach, HTML-Content) - F-MAIL-14: Mehrere Postfächer (IMAP/SMTP pro User konfigurierbar) - F-MAIL-15: Geteilte Postfächer (Gruppen-Postfach, Seen-By-Tracking) - F-MAIL-16: Stellvertretung (Delegate access: read/full) - F-MAIL-17: Sende-Berechtigungen (wer darf als Gruppe senden) - F-MAIL-18: Postfach-Konfiguration (IMAP/SMTP, AES-256 encrypted credentials, Verbindungstest) - F-MAIL-19: Mail-Ordner verwalten (Erstellen, Umbenennen, Löschen, IMAP-Sync) ## Acceptance Criteria (40 ACs) See task_graph.json T06.acceptance_criteria — ALL must pass. ## Architecture - Plugin Pattern: Follow `app/plugins/builtins/dms/` structure exactly - Files to create: - `app/plugins/builtins/mail/__init__.py` - `app/plugins/builtins/mail/plugin.py` (MailPlugin class, PluginManifest) - `app/plugins/builtins/mail/models.py` (14+ SQLAlchemy models) - `app/plugins/builtins/mail/schemas.py` (Pydantic schemas for all entities) - `app/plugins/builtins/mail/routes.py` (APIRouter with all endpoints) - `app/plugins/builtins/mail/services.py` (Service layer: IMAP sync, SMTP send, rules, vacation, PGP) - `app/plugins/builtins/mail/migrations/0001_initial.sql` (DB migration) - `tests/test_mail.py` (Test all 40 ACs) ## Models Required mail_accounts, mail_folders, mails, mail_attachments, mail_labels, mail_label_assignments, mail_rules, mail_templates, mail_signatures, vacation_sent_log, mail_seen_by, mail_account_delegates, mail_account_send_permissions, pgp_keys, contact_pgp_keys ## Key Technical Details - AES-256 encryption for mail account passwords (use `cryptography` package) - IMAP sync as ARQ background job (arq already in requirements.txt) - body_tsv column with PostgreSQL FTS (tsvector) - PGP via `pgpy` or `python-gnupg` package - HTML sanitization (no script tags) — use `bleach` or `nh3` - Plugin manifest: name="mail", dependencies=["permissions"] or [] - Routes prefix: `/api/v1/mail` - Follow existing test pattern from `tests/test_dms.py` (use authed_client, ORIGIN_HEADER) - All routes need `get_current_user` dependency from `app.deps` ## Test Spec - Test file: `tests/test_mail.py` - Run: `cd /a0/usr/workdir/dev-projects/leocrm && python -m pytest tests/test_mail.py -v --tb=short` - Coverage: `python -m pytest tests/test_mail.py --cov=app/plugins/builtins/mail --cov-report=term-missing` - Coverage target: 80% - Follow `tests/test_dms.py` pattern: conftest fixtures (authed_client, ORIGIN_HEADER, login_client) ## Dependencies to Add (requirements.txt) - `cryptography>=42.0` (AES-256 encryption) - `pgpy>=0.6.0` or `python-gnupg>=0.5` (PGP) - `bleach>=6.0` or `nh3>=0.2` (HTML sanitization) - `aiosmtplib>=3.0` (async SMTP) - `aioimaplib>=1.0` (async IMAP) ## Forbidden Patterns - No synchronous IMAP/SMTP in route handlers — use async or ARQ jobs - No plaintext password storage — AES-256 encryption mandatory - No raw HTML in API responses without sanitization - No credential values in any API response - No `time.sleep()` in tests — use `asyncio.sleep()` or mocking ## Existing Code References - Plugin base class: `app/plugins/base.py` → BasePlugin - Plugin manifest: `app/plugins/manifest.py` → PluginManifest, PluginRouteDef - DMS plugin (pattern to follow): `app/plugins/builtins/dms/` - Calendar plugin (pattern to follow): `app/plugins/builtins/calendar/` - Test pattern: `tests/test_dms.py`, `tests/test_calendar.py` - DB deps: `app/core/db.py` → get_db - Auth deps: `app/deps.py` → get_current_user - Test fixtures: `tests/conftest.py` → authed_client, ORIGIN_HEADER, login_client ## Estimated Size - ~800 lines code (models + schemas + routes + services + plugin + migration) - ~400+ lines tests