Easy_solution/NOTIFICATION.MD

8.9 KiB
Raw Permalink Blame History

Système de notification de l'application

Vue d'ensemble

Le système de notification de l'application permet d'informer les utilisateurs de diverse action.

Architecture

Composants principaux

  1. Service de Notification : Gère la création, l'envoi et le suivi des notifications.
  2. Interface Utilisateur : Affiche les notifications aux utilisateurs via des pops-ups, des bannières ou des emails.
  3. Template Email : Modèles prédéfinis pour les notifications par email.
  4. Type D'action : Enum d'action qui déclenche des notifications (ex: nouvel utilisateur, utilisateur actif, ...).

Service de Notification

Le service de notification est responsable de la gestion des notifications. Il inclut les fonctionnalités suivantes :

  • Création de notifications basées sur des événements spécifiques.
  • Envoi de notifications via différents canaux (email, in-app).
  • Suivi de l'état des notifications (envoyé, lu, etc.).

Interface Utilisateur

L'interface utilisateur affiche les notifications de manière conviviale. Les notifications peuvent apparaître sous forme de pops-ups, de bannières ou d'emails. (Possibilité d'intéragir avec les notifications)

Template Email

Les templates email sont utilisés pour formater les notifications envoyées par email. Chaque type de notification a son propre template pour assurer une communication claire et cohérente.

Type d'action

enum ActionType: String {
    case NewUser = "NEW_USER";
    case ActiveUser = "ACTIVE_USER";
    case PasswordReset = "PASSWORD_RESET";
    case SubscriptionExpired = "SUBSCRIPTION_EXPIRED";
    case OrganizationInvited = "ORGANIZATION_INVITED";
    case OrganizationInactive = "ORGANIZATION_INACTIVE";
    case OrganizationDeleted = "ORGANIZATION_DELETED";
    case OrginizationUserInvited = "ORGANIZATION_USER_INVITED";
    case UserDeleted = "USER_DELETED";
}

Flux de travail

  1. Ladministrateur crée un utilisateur depuis linterface (formulaire “Créer un utilisateur”).
  2. Le contrôleur valide la requête et appelle le cas dusage UserAdministrationService->handle(ActionType::NewUser, $admin, $payload).
  3. Le service crée lutilisateur en base avec le statut INVITED, associe lorganisation de ladmin, et génère un lien signé/jeton de setup de mot de passe (TTL).
  4. Le service publie un événement de domaine UserInvitedEvent { userId, adminId, organizationId } sur Messenger (transport async).
  5. Handler async A — SendUserInvitationEmailHandler:
  6. Construit lemail via Symfony Mailer + Twig (emails/user_invitation.html.twig) avec le lien de définition de mot de passe.
  7. Envoie le mail à lutilisateur invité.
  8. Handler async B — NotifyAdminInvitationSentHandler:
  9. Crée une notification interne (Notifier, canal “inapp”).
  10. Pousse un événement temps réel via Mercure sur le topic admin/{adminId}/events avec le type INVITATION_EMAIL_SENT.
  11. LUI admin affiche un toast/bannière confirmant “Email dinvitation envoyé”.
  12. Lutilisateur ouvre lemail et clique le lien de définition de mot de passe.
  13. Le PasswordSetupController vérifie la signature/le jeton et la validité (TTL), affiche le formulaire, puis enregistre le nouveau mot de passe.
  14. À la réussite, lutilisateur passe au statut ACTIVE et laction publie UserActivatedEvent { userId, adminId, organizationId } sur Messenger (async).
  15. Handler async C — NotifyAdminUserActivatedHandler:
  16. Crée une notification interne (Notifier, canal “inapp”) “Compte activé”.
  17. Pousse un événement Mercure sur admin/{adminId}/events avec le type USER_ACTIVATED.
  18. LUI admin met à jour la liste des membres (badge “Actif”) et affiche un toast confirmant lactivation.
  19. Journalisation/Audit:
  20. Chaque handler écrit une trace (succès/échec) en base ou dans un EmailLog/NotificationLog.
  21. En cas déchec denvoi, Messenger applique la stratégie de retry puis bascule en file failed si nécessaire (tableau de bord de supervision).
  22. Cas “utilisateur existant ajouté à une autre organisation”:
  23. Si lemail existe déjà, on rattache lutilisateur à la nouvelle organisation et on publie OrganizationUserInvitedEvent.
  24. Handler dédié envoie un email dinformation (“Vous avez été ajouté à une nouvelle organisation”) et notifie ladmin via Notifier + Mercure.
  25. Cas dactions dérivées par enum:
  26. ActionType::NewUser → déclenche UserInvitedEvent (steps 36).
  27. ActionType::ActiveUser (si activé par un flux admin) → déclenche directement UserActivatedEvent (steps 910).
  28. ActionType::OrganizationUserInvited → flux similaire au point 12 pour la multiorganisation.
  29. Autres actions (PasswordReset, UserDeleted, etc.) suivent le même patron: contrôleur → service (match enum) → événement Messenger → handlers (Mailer/Notifier/Mercure) → UI temps réel.

Stack technologique

  • Symfony Messenger: asynchrone, retries, découplage des I/O lents.
  • Symfony Mailer + Twig: emails dinvitation et dinformation.
  • Symfony Notifier (canal inapp) + Mercure: notifications persistées + push temps réel vers lUI admin.
  • Enum ActionType: routage clair dans lapplication, évite la logique stringbased.
flowchart LR
%% Couche 1: Action initiale
    A[User action event - Admin cree un utilisateur] --> B[HTTP controller API - Symfony]
    B --> C[Domain service - UserAdministrationService]
    C -->|Inspecte enum ActionType::NewUser| C1[Create user - status INVITED - liaison organisation - genere lien jeton mot de passe TTL]
    C1 --> D[Dispatch UserInvitedEvent - userId adminId organizationId - vers Symfony Messenger bus]

%% Couche 2: Messaging / Infra
    D --> E[Transport async - AMQP / Redis / Doctrine]
    E --> RQ[Retry queue]
    E --> FQ[Failed queue - dead letter]
    E --> W[Workers Messenger]
    F[Supervisor / systemd] --> W

%% Monolog transversal (logs a chaque etape)
    A --> LOG_GLOBAL[Monolog - log event initial]
    B --> LOG_GLOBAL
    C --> LOG_GLOBAL
    C1 --> LOG_GLOBAL
    D --> LOG_GLOBAL
    E --> LOG_GLOBAL
    RQ --> LOG_GLOBAL
    FQ --> LOG_GLOBAL
    W --> LOG_GLOBAL

%% Handlers pour l'invitation
    W --> H1[Handler A - Symfony Mailer + Twig]
    H1 --> H1o[Email d'invitation avec lien setup mot de passe]
    H1 --> LOG_GLOBAL

    W --> H2[Handler B - Symfony Notifier in-app]
    H2 --> UI1[Notification UI admin - Email d'invitation envoye]
    H2 --> LOG_GLOBAL

    W -. optionnel .-> WH1[Webhook HTTP sortant - invitation envoyee]
    WH1 --> LOG_GLOBAL
    W -. optionnel .-> SMS1[SMS gateway - SMS invitation]
    SMS1 --> LOG_GLOBAL
    W -. optionnel .-> PUSH1[Mobile push service - notification mobile]
    PUSH1 --> LOG_GLOBAL

    RQ --> METRICS[Metrics et dashboard]
    FQ --> METRICS
    LOG_GLOBAL --> METRICS

%% Flux activation utilisateur
    subgraph Activation du compte
        UA[User action event - Invite clique le lien] --> PS[HTTP controller API - PasswordSetupController]
        PS -->|Verifie signature et TTL| PSOK[Set password - user status ACTIVE]
        PS --> LOG_GLOBAL
        PSOK --> LOG_GLOBAL

        PSOK --> D2[Dispatch UserActivatedEvent - userId adminId organizationId - vers Messenger bus]
        D2 --> E2[Transport async]
        E2 --> RQ2[Retry queue]
        E2 --> FQ2[Failed queue]
        E2 --> W2[Workers Messenger]
        F --> W2

        D2 --> LOG_GLOBAL
        E2 --> LOG_GLOBAL
        RQ2 --> LOG_GLOBAL
        FQ2 --> LOG_GLOBAL
        W2 --> LOG_GLOBAL

        W2 --> H3[Handler C - Notifier in-app]
        H3 --> UI2[Notification UI admin - Compte active]
        H3 --> LOG_GLOBAL

        W2 -. optionnel .-> WH2[Webhook HTTP sortant - user active]
        WH2 --> LOG_GLOBAL
        W2 -. optionnel .-> MAIL2[Mailer ou SMS ou Push - confirmation utilisateur]
        MAIL2 --> LOG_GLOBAL

        RQ2 --> METRICS
        FQ2 --> METRICS
    end

%% Cas particulier : utilisateur existant ajoute a une nouvelle organisation
    C -->|Email deja existant| SP1[Rattache a nouvelle organisation]
    SP1 --> LOG_GLOBAL
    SP1 --> D3[Dispatch OrganizationUserInvitedEvent]
    D3 --> E3[Transport async] --> W3[Workers]
    F --> W3
    D3 --> LOG_GLOBAL
    E3 --> LOG_GLOBAL
    W3 --> LOG_GLOBAL

    W3 --> M3[Mailer - ajoute a une nouvelle organisation]
    M3 --> LOG_GLOBAL
    W3 --> N3[Notifier in-app - toast admin Utilisateur ajoute]
    N3 --> LOG_GLOBAL
    W3 -. optionnel .-> WH3[Webhook ou SMS ou Mobile]
    WH3 --> LOG_GLOBAL

    M3 --> METRICS
    N3 --> METRICS
    WH3 --> METRICS

%% Styles
    classDef infra fill:#e8f0fe,stroke:#5b8def,stroke-width:1px;
    classDef handler fill:#dcf7e9,stroke:#2ea66a,stroke-width:1px;
    classDef ui fill:#f0d9ff,stroke:#9c27b0,stroke-width:1px;
    classDef audit fill:#eeeeee,stroke:#9e9e9e,stroke-width:1px;

    class E,E2,E3,RQ,FQ,RQ2,FQ2,METRICS infra;
    class W,W2,W3,H1,H2,H3,M3,N3 handler;
    class H1o,UI1,UI2 ui;
    class LOG_GLOBAL audit;