From b0f05da84ad066daef42ad7a3c0cf2de06a5798d Mon Sep 17 00:00:00 2001 From: matthieu Date: Wed, 20 May 2026 08:22:11 +0200 Subject: [PATCH] =?UTF-8?q?docs(mail)=20:=20section=20"Statut=20&=20repris?= =?UTF-8?q?e"=20=E2=80=94=20handoff=20complet=20(bugs=20corrig=C3=A9s,=20p?= =?UTF-8?q?oints=20en=20suspens,=20commandes)=20pour=20reprise=20sur=20aut?= =?UTF-8?q?re=20poste?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/mail-integration.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/docs/mail-integration.md b/docs/mail-integration.md index e01bb6f..92edece 100644 --- a/docs/mail-integration.md +++ b/docs/mail-integration.md @@ -1,5 +1,44 @@ # Intégration Mail — Vue d'ensemble +> ## 🟢 Statut & reprise (handoff — MAJ 2026-05-20) +> +> **Branche** : `feat/mail-integration` · **MR Gitea** : https://gitea.malio.fr/MALIO-DEV/Lesstime/pulls/5 (base `develop`) +> Construit en 7 phases (plans dans `docs/superpowers/plans/2026-05-19-mail-phase*.md`). +> +> ### Ce qui marche (testé contre une vraie boîte OVH `contact@malio.fr`) +> - Connexion IMAP + test connexion (admin → `/admin` onglet Mail) +> - Synchro complète multi-dossiers : **456 messages / 57 dossiers** ramenés, ne crashe plus +> - Lecture dossiers/messages dans `/mail`, arbre repliable (chevrons, sous-dossiers masqués par défaut) +> - Lecture d'un mail, sanitization DOMPurify +> - Création/lien tâche depuis un mail +> +> ### Bugs déjà corrigés ce soir (NE PAS ré-investiguer) +> Tous dans `ImapMailProvider` / `MailSyncService` — les tests mockaient le provider, donc le fetch réel n'avait jamais été exercé avant le test live : +> 1. Requête sans critère → `BAD parse error: zero-length content` → `whereAll()` +> 2. `getDate()`/`getSubject()` renvoient des `Attribute` webklex v6 → casts explicites +> 3. Séquence par défaut `ST_MSGN` → `peek()` faisait un STORE rejeté par OVH (`flag could not be removed`) → forcé `ST_UID` partout +> 4. Snippet via `getTextBody()` = fetch du corps de chaque mail (sync 179s + peek) → `setFetchBody(false)`, snippet désactivé au listing +> 5. Test connexion exigeait `enabled=true` → découplé via `getClient(requireEnabled:false)` + `testConnection()` +> 6. Contrainte UNIQUE globale sur `message_id` → fausse pour IMAP (même Message-ID dans plusieurs dossiers) → fermait l'EntityManager → cascade. **Migration `Version20260520061736`** : index simple. Garde anti-cascade dans `MailSyncService` (reset `ManagerRegistry`). +> 7. 139 connexions IMAP (une/dossier) → throttling OVH → réutilisation d'1 connexion (`closeConnection()` sur l'interface) + reconnexion ciblée après dossier en erreur. +> - Contrat front/back réaligné dans `frontend/services/mail.ts` (route `/mail/folders/{path}/messages`, mapping `messages→items`, `fromAddress→fromEmail`, détail plat→imbriqué). +> +> ### Points en suspens / à savoir +> - **Mise à jour auto** = cron OS lançant `make mail-sync` toutes les 10 min (cf `docs/mail-cron-setup.md`). **Pas configuré en dev** — lancer à la main. +> - **Bouton "Actualiser"** : dispatch async Messenger (`MailSyncRequested → async`). Sans worker `messenger:consume async` qui tourne, les demandes s'empilent sans s'exécuter. En prod : supervisor. En dev : lancer un worker. +> - **~7 dossiers/139** à encodage spécial (ex: `INBOX/RH/.../SÉBASTIEN` en UTF7-modifié) ou réponses vides sont skippés proprement et réessayés au cycle suivant. Edge case webklex non bloquant. +> - **Dépendance** : `webklex/php-imap ^6.2` tire des paquets Laravel (`illuminate/*` via `carbon ^3`) dans ce projet Symfony — fonctionnel mais à valider en review. +> - 6 PHPUnit Notices (mocks sans expectations) non bloquantes. +> +> ### Commandes utiles +> ```bash +> make mail-sync # synchro complète +> docker exec -i -u www-data php-lesstime-fpm php bin/console app:mail:sync --folder=INBOX -v +> docker exec -i -u www-data php-lesstime-fpm php bin/console messenger:consume async -vv # worker (fait marcher le bouton) +> make test # 33 tests +> ``` +> Fixtures `make fixtures` plantent sur un état legacy `workflow_id` (hors-scope mail) — configurer la boîte via l'UI admin. + ## Fonctionnalités - Lecture de la boîte mail partagée (IMAP) depuis Lesstime