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)
90 lines
4.6 KiB
Markdown
90 lines
4.6 KiB
Markdown
# 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
|