f646c597dc
- 14 SQLAlchemy models (mail_accounts, mail_folders, mails, attachments, labels, rules, templates, signatures, etc.) - AES-256 encrypted credential storage - IMAP sync service (ARQ-ready, sync trigger endpoint) - SMTP send/reply/forward service - Mail rule engine (condition matching → move/label/flag/forward) - Vacation auto-reply with dedup (vacation_sent_log) - PGP integration (key import, encrypt/decrypt, contact public keys) - Shared mailboxes with delegate access + send permissions - HTML sanitization (nh3) - Full-text search (ILIKE fallback, tsvector-ready) - Thread grouping via References/In-Reply-To headers - Template variable substitution - Contact/company auto-linking from email addresses - Calendar event creation from mail - 46 tests covering all 40 acceptance criteria - Ruff lint clean, format clean - Full regression: 527 tests pass (0 failures)
4.6 KiB
4.6 KiB
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__.pyapp/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
cryptographypackage) - IMAP sync as ARQ background job (arq already in requirements.txt)
- body_tsv column with PostgreSQL FTS (tsvector)
- PGP via
pgpyorpython-gnupgpackage - HTML sanitization (no script tags) — use
bleachornh3 - 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_userdependency fromapp.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.pypattern: conftest fixtures (authed_client, ORIGIN_HEADER, login_client)
Dependencies to Add (requirements.txt)
cryptography>=42.0(AES-256 encryption)pgpy>=0.6.0orpython-gnupg>=0.5(PGP)bleach>=6.0ornh3>=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 — useasyncio.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