Files
leocrm/.a0/briefings/T06_briefing.md
T
leocrm-bot f646c597dc T06: Mail plugin backend — IMAP/SMTP, threading, templates, rules, PGP, vacation, delegates — 46 tests, 74.56% coverage
- 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)
2026-07-01 15:41:27 +02:00

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__.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