Files
Lesstime/src/Mail/MailProviderInterface.php
matthieu c75dfa0371 fix(mail) : synchro multi-dossiers fiable contre OVH
Trois causes racines révélées par une vraie synchro complète (139 dossiers) :
- contrainte UNIQUE globale sur message_id : fausse pour IMAP (un même Message-ID
  existe dans plusieurs dossiers) → violation → fermeture de l'EntityManager →
  cascade qui tuait tous les dossiers suivants. Migration : index simple à la place.
- 139 connexions IMAP (une par dossier) → throttling OVH (failed to authenticate) :
  réutilisation d'une seule connexion (closeConnection() ajouté à l'interface).
- état de connexion corrompu après un dossier en erreur (must be in SELECTED state) :
  reconnexion ciblée après chaque dossier en échec.
- garde anti-cascade : reset du ManagerRegistry + arrêt propre si l'EM se ferme.

Résultat : 456 messages sur 57 dossiers (avant : 188/30 puis crash). Les rares
dossiers à encodage spécial sont skippés proprement et réessayés au cycle suivant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 08:21:02 +02:00

82 lines
2.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Mail;
use App\Mail\Dto\MailFolderDto;
use App\Mail\Dto\MailMessageDetailDto;
use App\Mail\Dto\MailMessageHeaderDto;
use App\Mail\Exception\MailProviderException;
interface MailProviderInterface
{
/**
* Opens a connection using the stored configuration and returns the number
* of folders found. Used by the admin "test connection" endpoint, so it
* MUST work even when the configuration is not yet enabled.
*
* @throws MailProviderException
*/
public function testConnection(): int;
/**
* Releases any reused network connection held by the provider.
* Safe to call multiple times; a no-op if nothing is open.
*/
public function closeConnection(): void;
/**
* Returns the full folder tree of the configured mailbox.
*
* @return list<MailFolderDto>
*
* @throws MailProviderException
*/
public function listFolders(): array;
/**
* Returns a paginated list of message headers for the given folder.
*
* @return list<MailMessageHeaderDto>
*
* @throws MailProviderException
*/
public function listMessages(string $folderPath, int $limit, int $offset): array;
/**
* Fetches the full message (headers + body + attachments list) by UID.
*
* @throws MailProviderException
*/
public function fetchMessage(string $folderPath, int $uid): MailMessageDetailDto;
/**
* Marks a message as read or unread on the IMAP server.
*
* @throws MailProviderException
*/
public function markRead(string $folderPath, int $uid, bool $read): void;
/**
* Marks a message as flagged (starred) or unflagged on the IMAP server.
*
* @throws MailProviderException
*/
public function markFlagged(string $folderPath, int $uid, bool $flagged): void;
/**
* Moves a message from one folder to another on the IMAP server.
*
* @throws MailProviderException
*/
public function moveMessage(string $folderPath, int $uid, string $targetFolder): void;
/**
* Fetches the raw binary content of an attachment by its MIME part number.
*
* @throws MailProviderException
*/
public function fetchAttachment(string $folderPath, int $uid, string $partNumber): string;
}