Commit Graph

484 Commits

Author SHA1 Message Date
f62c790449 feat(mail) : MailLinkTaskModal — autocomplete tâches, filtre projet, debounce 300ms 2026-05-20 00:47:55 +02:00
13cec9a46a feat(mail) : MailCreateTaskModal — picker projet/groupe/priorité, appel createTaskFromMail 2026-05-20 00:47:08 +02:00
d676fdcb0c feat(mail) : clés i18n Phase 6 — createTaskModal, linkTaskModal, pickerModal, taskTab 2026-05-20 00:46:09 +02:00
bfcf712123 docs(mail) : plan détaillé Phase 6 — modals create/link task + onglet Mails dans TaskModal (8 tasks)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:44:26 +02:00
622fcf72c1 feat(mail) : page /mail — layout 3 colonnes, deep-link messageId, refus ROLE_CLIENT 2026-05-20 00:37:03 +02:00
67e73a52d7 feat(mail) : MailMessageViewer — header, body sanitizé DOMPurify, PJ téléchargeables, 4 actions 2026-05-20 00:36:29 +02:00
aa175063dc feat(mail) : MailMessageList — liste paginée infinite scroll, indicateurs lu/étoilé/PJ/date relative 2026-05-20 00:35:47 +02:00
9aa14d38a9 feat(mail) : MailFolderTree — arbre récursif dossiers, badges unread, icônes système 2026-05-20 00:35:19 +02:00
95a98012ad feat(mail) : MailRefreshButton — bouton sync manuel, disabled pendant syncing 2026-05-20 00:34:59 +02:00
535753b189 feat(mail) : composable useSystemFolderLabel — mapping dossiers système IMAP vers i18n + icônes 2026-05-20 00:34:46 +02:00
e710f57c49 feat(mail) : clés i18n mail.* (titres, vides, dossiers système, actions, erreurs) 2026-05-20 00:34:24 +02:00
73f0adc761 docs(mail) : plan détaillé Phase 5 — page /mail 3 colonnes + 4 composants (9 tasks)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:32:34 +02:00
2e0f5b4e30 feat(mail) : store Pinia useMailStore — folders, messages, polling 30s, markRead/markFlagged 2026-05-20 00:26:19 +02:00
33e4e79f8e feat(mail) : service API mail — listFolders/messages/getMessage/markRead/markFlagged/createTask/linkTask/downloadAttachment/triggerSync 2026-05-20 00:25:21 +02:00
bfa155d060 feat(mail) : helper sanitizeMailHtml — DOMPurify + placeholder images distantes 2026-05-20 00:24:30 +02:00
e7224765b1 feat(mail) : types TS DTOs mail (config, folders, messages, attachments) 2026-05-20 00:23:26 +02:00
fe07398059 feat(mail) : install dompurify + types 2026-05-20 00:22:33 +02:00
a440ce267f docs(mail) : plan détaillé Phase 4 — services TS, store Pinia, DOMPurify (6 tasks)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:21:50 +02:00
8986f3cb0e feat(mail) : security.yaml - access_control ^/api/mail (IS_AUTHENTICATED_FULLY)
- ajoute la regle ^/api/mail avant ^/api pour expliciter l'authentification requise
- les checks fins ROLE_USER vs ROLE_CLIENT restent dans MailAccessChecker (chaque controller)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:15:49 +02:00
6d420c86e8 feat(mail) : MailSyncTriggerController - POST /api/mail/sync (202 + Messenger async)
- dispatch MailSyncRequested au bus Messenger, retourne 202 immediat
- folderPath optionnel via body JSON pour sync ciblee
- en test : transport in-memory route le message en sync
- securite via MailAccessChecker

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:15:25 +02:00
cc46dd915d feat(mail) : MailSyncRequested message + handler + messenger.yaml transport async Doctrine
- App\Message\MailSyncRequested (optionnel folderPath)
- App\MessageHandler\MailSyncRequestedHandler delegue a MailSyncService::syncFolder ou syncAll
- messenger.yaml : transport async via Doctrine DSN, retry 3x exponentiel, failure transport
- en test : transport in-memory (sync immediat)
- migration Version20260519220000 : cree messenger_messages table (idempotente, IF NOT EXISTS)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:14:47 +02:00
f7f7a07162 feat(mail) : MailAttachmentDownloadController - GET /api/mail/attachments/{id} (stream, disposition: attachment)
- downloadId = base64url(messageDbId:partNumber)
- Content-Disposition: attachment systematique (jamais inline pour eviter XSS via HTML attachments)
- X-Content-Type-Options: nosniff
- filename sanitise via basename pour eviter path traversal

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:12:38 +02:00
117175d4b1 feat(mail) : MailLinkTask + MailUnlinkTask + TaskMailsList controllers
- POST /api/mail/messages/{id}/link-task body {taskId} : cree TaskMailLink (idempotent)
- DELETE /api/mail/messages/{id}/link-task/{taskId} : supprime le lien (204)
- GET /api/tasks/{id}/mails : liste les mails lies a une tache
- securite via MailAccessChecker, tests fonctionnels 401/403

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:12:10 +02:00
c7d12f6acd feat(mail) : MailCreateTaskController - POST /api/mail/messages/{id}/create-task
- cree une Task avec titre = subject du mail (max 255 chars)
- utilise findMaxNumberByProjectForUpdate pour numero (advisory lock PG)
- transaction wrapInTransaction pour eviter race conditions
- taskGroupId et priorityId optionnels via body JSON
- cree automatiquement le TaskMailLink (mail <-> tache)
- retourne 201 + taskId/taskNumber/taskTitle/messageId

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:10:53 +02:00
f584ed96fa feat(mail) : MailMessageReadController + MailMessageFlagController - POST .../read et .../flag
- POST /api/mail/messages/{id}/read body {read: bool} - synchro IMAP + BDD
- POST /api/mail/messages/{id}/flag body {flagged: bool} - synchro IMAP + BDD
- IMAP-side non bloquant : BDD est mise a jour meme si IMAP fail (resync au prochain cycle)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:10:06 +02:00
5ce7693343 feat(mail) : MailMessageDetailController - GET /api/mail/messages/{id} (live IMAP + cache 5 min)
- recupere headers + body + attachments via ImapMailProvider::fetchMessage
- cache Symfony pool cache.app, cle mail_body_{md5(messageId)}, TTL 300s
- attachments serialises sans contenu binaire, avec downloadId base64url(messageDbId:partNumber)
- 503 si IMAP indisponible, 404 si message inconnu
- les tests read/flag ROLE_CLIENT/auth seront ajoutes en Task 10 (route deja existante)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:09:30 +02:00
7fb525595e feat(mail) : MailMessagesListController - GET /api/mail/folders/{path}/messages (pagination cursor)
- MailMessageRepository::findByFolderCursor : pagination cursor sentAt DESC, id DESC
- cursor base64url(sentAt_iso:id), limit max 100
- folderPath URL-encode (requirements: .+ pour supporter les slashes nested)
- securite via MailAccessChecker

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:08:18 +02:00
b1d6303afe feat(mail) : MailFoldersListController - GET /api/mail/folders (arbre BDD + unreadCount)
- lit la BDD (pas l'IMAP live), retourne l'arbre des dossiers avec metadata
- securite via MailAccessChecker : ROLE_USER/ADMIN, refus ROLE_CLIENT pur
- tests fonctionnels 401/403/200

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:07:23 +02:00
1c3ba9c33c feat(mail) : MailAccessChecker - verification acces mail ROLE_USER/ROLE_ADMIN (refus ROLE_CLIENT pur)
- ensureCanAccessMail : refuse ROLE_CLIENT pur (sans ROLE_ADMIN)
- ensureIsAdmin : helper pour endpoints config
- service utilise par tous les controllers metier mail

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:06:45 +02:00
412c412cbc feat(mail) : MailTestConnectionController — POST /api/mail/configuration/test
- endpoint ROLE_ADMIN qui teste la connexion IMAP via listFolders
- retourne ok:bool + foldersCount ou error sanitise (pas de leak interne)
- priority:1 obligatoire pour eviter conflit avec route API Platform {id}

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:06:25 +02:00
62e0bf5f11 feat(mail) : MailSettings ApiResource singleton (GET/PATCH /api/mail/configuration)
- ApiResource MailSettings expose les operations Get + Patch sur /api/mail/configuration
- Provider + Processor relient le DTO a l'entite MailConfiguration (singleton)
- password en write-only (jamais retourne) + hasPassword en lecture
- chiffrement password via TokenEncryptor (sodium)
- securite ROLE_ADMIN sur les deux operations

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:06:01 +02:00
696b40ca80 feat(mail) : install symfony/messenger + browser-kit + ENCRYPTION_KEY test (deps Phase 3)
- ajoute symfony/messenger ^8.0 et symfony/doctrine-messenger ^8.0 pour la sync mail async
- ajoute symfony/browser-kit + css-selector en dev pour tests fonctionnels WebTestCase
- ENCRYPTION_KEY ajoutee dans phpunit.dist.xml pour permettre le chiffrement en test
- MESSENGER_TRANSPORT_DSN configure (Doctrine), messenger.yaml minimal (sera enrichi en Task 12)
- fix(orm) : ClientTicket - migre uniqueConstraints en attribut separe (Doctrine ORM 4 deprecation)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 00:05:49 +02:00
cbbc491d69 docs(mail) : plan détaillé Phase 3 — API endpoints, sécurité ROLE_CLIENT, Messenger async (15 tasks)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 23:48:43 +02:00
26fab44dab docs(mail) : guide configuration cron OS pour mail-sync 2026-05-19 23:39:44 +02:00
0028b489e4 feat(mail) : Makefile — target mail-sync avec options FOLDER et DRYRUN 2026-05-19 23:39:21 +02:00
1fb7460f8e feat(mail) : commande app:mail:sync avec options --folder et --dry-run 2026-05-19 23:38:40 +02:00
c47434b502 feat(mail) : MailSyncService — syncAll/syncFolder/syncFolderStructure + lock + garde 50% 2026-05-19 23:37:31 +02:00
f245863b78 feat(mail) : MailMessageRepository — findMaxUidInFolder, findLastNByFolder, findAllUidsByFolder 2026-05-19 23:35:30 +02:00
b546f528df feat(mail) : ImapMailProvider — implémentation complète MailProviderInterface 2026-05-19 23:35:12 +02:00
b5b4288cc0 feat(mail) : DTO MailSyncReport + test unitaire 2026-05-19 23:32:29 +02:00
3a2d8d5bde feat(mail) : install webklex/php-imap + symfony/lock, configure lock store 2026-05-19 23:32:01 +02:00
23191bdab6 docs(mail) : plan détaillé Phase 2 — ImapMailProvider, MailSyncService, commande app:mail:sync (9 tasks)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 23:29:18 +02:00
5f92cbbf4f feat(mail) : fixture MailConfiguration OVH defaults (disabled) 2026-05-19 23:22:05 +02:00
f80680e874 feat(mail) : MailProviderInterface + MailProviderException 2026-05-19 23:20:58 +02:00
697197864f feat(mail) : DTOs — MailFolderDto, MailMessageHeaderDto, MailAttachmentDto, MailMessageDetailDto 2026-05-19 23:20:35 +02:00
0da26ff418 feat(mail) : migration — 4 tables mail_configuration, mail_folder, mail_message, task_mail_link 2026-05-19 23:20:03 +02:00
cd9c16a990 feat(mail) : TaskMailLink entity + repository 2026-05-19 23:17:16 +02:00
0c597bc653 feat(mail) : MailMessage entity + repository 2026-05-19 23:16:52 +02:00
0c80159d7e feat(mail) : MailFolder entity + repository 2026-05-19 23:16:17 +02:00
3cac87aa24 feat(mail) : MailConfiguration entity + repository + singleton test 2026-05-19 23:15:47 +02:00