feat(mail) : migrate Mail integration into module (back)

LST-67 (2.5) backend. Behaviour-preserving move of the IMAP mail integration
into src/Module/Mail/. All /api/mail/* routes, securities (ROLE_CLIENT still
excluded via MailAccessChecker) and the async sync are unchanged.

- 4 entities + 4 repositories (Domain interfaces + Doctrine impls, bound).
  TaskMailLink.task now references TaskInterface (contract) instead of the
  concrete PM Task. Link/unlink/list-mails controllers load tasks via
  TaskRepositoryInterface; MailCreateTaskController keeps the concrete Task
  (instantiation) — documented Mail->PM coupling.
- Domain (MailProviderInterface, exception), Application (5 DTOs, MailSyncService,
  MailSyncRequested message + handler), Infrastructure (ImapMailProvider +
  MimeHeaderDecoder, MailAccessChecker, 2 console commands, 12 controllers,
  ApiPlatform state + MailSettings resource). TokenEncryptor stays shared.
- doctrine mapping Mail; messenger routing repointed; services.yaml repo +
  provider bindings; MailModule registered (id mail, mail.access/configure).
- #[Auditable] + Timestampable on MailConfiguration only (additive migration);
  IMAP data entities keep their own sync timestamps.

163 tests green, mapping valid, no route regression, cs-fixer clean.
This commit is contained in:
Matthieu
2026-06-20 19:44:19 +02:00
parent 57ccd9a740
commit 25d3a693f9
55 changed files with 453 additions and 209 deletions
+54
View File
@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Mail module: add Timestampable + Blamable tracking on mail_configuration.
*
* Purely additive — adds nullable audit columns to an existing table:
* created_at / updated_at (Timestampable)
* created_by / updated_by -> "user"(id) ON DELETE SET NULL (Blamable)
* No DROP/ALTER on existing data. Columns are lowercase snake_case.
* Hand-written to mirror the schema dump and guarantee zero destructive
* instruction. down() drops the new columns and their FKs/indexes.
*/
final class Version20260620200000 extends AbstractMigration
{
public function getDescription(): string
{
return 'Mail: add Timestampable/Blamable columns on mail_configuration (additive)';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE mail_configuration ADD created_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL');
$this->addSql('ALTER TABLE mail_configuration ADD updated_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL');
$this->addSql('ALTER TABLE mail_configuration ADD created_by INT DEFAULT NULL');
$this->addSql('ALTER TABLE mail_configuration ADD updated_by INT DEFAULT NULL');
$this->addSql('ALTER TABLE mail_configuration ADD CONSTRAINT FK_BFC0A7DBDE12AB56 FOREIGN KEY (created_by) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE');
$this->addSql('ALTER TABLE mail_configuration ADD CONSTRAINT FK_BFC0A7DB16FE72E1 FOREIGN KEY (updated_by) REFERENCES "user" (id) ON DELETE SET NULL NOT DEFERRABLE');
$this->addSql('CREATE INDEX IDX_BFC0A7DBDE12AB56 ON mail_configuration (created_by)');
$this->addSql('CREATE INDEX IDX_BFC0A7DB16FE72E1 ON mail_configuration (updated_by)');
$this->addSql("COMMENT ON COLUMN mail_configuration.created_at IS 'Creation timestamp (Timestampable, set on prePersist)'");
$this->addSql("COMMENT ON COLUMN mail_configuration.updated_at IS 'Last update timestamp (Timestampable, set on prePersist/preUpdate)'");
$this->addSql("COMMENT ON COLUMN mail_configuration.created_by IS 'User who created the entry (Blamable, FK user.id, SET NULL on delete)'");
$this->addSql("COMMENT ON COLUMN mail_configuration.updated_by IS 'User who last updated the entry (Blamable, FK user.id, SET NULL on delete)'");
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE mail_configuration DROP CONSTRAINT FK_BFC0A7DBDE12AB56');
$this->addSql('ALTER TABLE mail_configuration DROP CONSTRAINT FK_BFC0A7DB16FE72E1');
$this->addSql('DROP INDEX IDX_BFC0A7DBDE12AB56');
$this->addSql('DROP INDEX IDX_BFC0A7DB16FE72E1');
$this->addSql('ALTER TABLE mail_configuration DROP created_at');
$this->addSql('ALTER TABLE mail_configuration DROP updated_at');
$this->addSql('ALTER TABLE mail_configuration DROP created_by');
$this->addSql('ALTER TABLE mail_configuration DROP updated_by');
}
}