Notifications et Push
Vérifié le 30 septembre 2026 sur le checkout local uniksimweb, branche messagerie_fixes, HEAD 3f74bcb0, incluant les changements indexés du refactoring temps réel. Cette description porte sur le code local; elle ne confirme pas son déploiement.
Vue d’ensemble
Toutes les notifications passent par NotificationService.notify(userId, notificationType, payload, isImportant). Le systèmecompte reçoit une entrée dans son inbox Redis, un événement Socket.IO sur /account et une tentative de notificationspush UnikSimFCM combinevers troisses mécanismesinstallations. complémentairesLe : une inbox persistée dans Redis, des événements temps réel via Socket.IO,Web et l’application mobile lisent l’inbox; le jeu produit des push notifications via Firebasel’API.
Flux de garantircréation qu’uneet notification puisse être visible immédiatement dans l’application lorsque l’utilisateur est connecté, tout en permettant une livraison push lorsque l’application n’est pas active.
1. Architecture générale des notificationsresponsabilités
flowchart LR
SRC[ServicesS[Service métier /ou SupportService]GameNotificationService] --> NS[NotificationService]N[NotificationService.notify]
NSN --> REDIS[R[(Inbox Redis inbox)du compte)]
NSN --> EVT[EventEmitter]E[EventEmitter NSnotification.created]
E --> FBS[FirebaseService]G[AccountGateway EVT/account]
G --> GW[SupportGateway]A[AccountSocketService]
GWA --> ROOM[user_userId]U[UserNotificationService ROOMet interface]
N --> FE[FrontendF[FirebaseService]
Angular / App]
FBSF --> TOK[UserFcmTokenT[(UserFcmToken)]
+ subscriptions]
FBSF --> FCM[Firebase FCM]
D[FCM -->vers DEV[Appareilsinstallations utilisateur]du FE --> API[API notifications]
API --> REDIS
compte]
La
notification.created; AccountGateway relaie la notification vers user_<userId> dans le namespace /account.
Construire le titre et Contrat partagé
NotificationDto côté backend et UserNotification côté Angular partagent les champs uid, userId, notificationType, timestamp, isRead, isImportant. Les champs métier, par exemple ticketId ou simUid, sont placés directement à côté de l’inbox.cette enveloppe. Les champs d’enveloppe définis par le serveur écrasent ceux du payload.
2.
L’UID Créationcombine d’unele notificationcompte, le timestamp et quatre octets aléatoires pour undistinguer utilisateurplusieurs connecténotifications
sequenceDiagram
participant S as Service métier
participant N as NotificationService
participant R as Redis
participant E as EventEmitter
participant G as SupportGateway
participant F as Frontend
S->>N: notifyUser(userId, type, payload)
N->>N: Construit titre/body localisés
N->>R: LPUSH notification + expiry
R-->>N: Persistée
N->>E: NOTIFICATION_CREATED
E->>G: événement
G-->>F: notification.created
F->>F: upsert dans l'état local
F->>F: incrémente unread + joue le son
Le gateway relaie l’événementcréées dans la roommême milliseconde. Le texte push utilise les clés uniksim.push_<type>_title/body, les placeholders du payload et un texte de secours. Les valeurs FCM sont converties en chaînes; notificationUid conserve la compatibilité avec les clients historiques.
Inbox Redis et API du compte
La clé est user_<id>_notifications. LPUSH conserve les plus récentes en premier, LTRIM limite l’inbox à 100 entrées et EXPIRE fixe 10 519 200 secondes de rétention. Chaque insertion renouvelle le TTL de toute la liste; ce n’est pas une expiration indépendante par notification.
GET /notifications
Retourne l’inbox du compte POST /notifications/:notificationUid/read
Met à jour l’LSET.
DELETE /notifications/:notificationUid
Retire l’entrée avec LREM.
Ces routes utilisent AuthGuardUser et l’identité request.user.sub.
3.Frontend Livraisonet Pushtemps via Firebaseréel
sequenceDiagramAccountSocketServiceparticipantreçoit Nnotification.created, asdéclenche NotificationServicele participantson FBSet asexpose FirebaseServicel’observable. participantAppComponent DBtransmet asla MySQLnotification participantà FCMUserNotificationService.upsert(). asCe Firebaseservice Cloudmaintient Messagingle participantBehaviorSubject, Ddéduplique aspar AppareilUID N->>FBS:et sendPushNotificationToUser(userId)dérive FBS->>DB:le Charge installations FCMnombre de l'utilisateurnotifications DB-->>FBS:non tokenslues. actifsLe FBS->>FCM:chargement multicast(tokens,initial payload)et FCM-->>D:les pushactions notificationlu/suppression FCM-->>FBS:utilisent résultatsHTTP. parSupportSocketService gère les conversations et tickets; la réception des notifications appartient au service du compte.
Installations et livraison FCM
PUT /push/installations/:installationId enregistre token et platform pour le compte authentifié. Dans une transaction, le service supprime les inscriptions périmées portant le même token FBS->>FBS:puis détectecrée invalid/unregisteredou FBS->>DB:met supprimeà jour UserFcmToken. DELETE /push/installations/ tokens:installationIdinvalidesretire
LesLa pushlivraison sont envoyées àcharge toutes les installations du compte.compte, Pourdéduplique les notificationstokens liées à un jeu, le backend peut cibleret les installations selon leurs subscriptions à des productCodeId.
4. Installations FCM et subscriptions
flowchart TD
APP[Application / appareil] --> REG[registerInstallation]
REG --> OWN[Validation des productCodeIds possédés]
OWN --> CLEAN[Supprime le même token d'anciennes installations]
CLEAN --> UPSERT[Upsert UserFcmToken]
UPSERT --> SUB[Remplace UserFcmSubscriptions]
SUB --> SEND[Envoi futur]
SEND --> MATCH[Filtre ownership + productCodeId]
MATCH --> TOKENS[Liste des tokens]
TOKENS --> FCM[Firebase FCM]
FCM --> BAD{Token invalide ?}
BAD -->|Oui| DEL[Supprime token + subscriptions]
BAD -->|Non| OK[Conserve installation]
5. Cycle de vie d’une notification
stateDiagram-v2
[*] --> CREATED
CREATED --> UNREAD: persistance Redis
UNREAD --> READ: marquer comme lue
READ --> UNREAD: nouvelle notification distincte
UNREAD --> DELETED: supprimer
READ --> DELETED: supprimer
DELETED --> [*]Architecture frontend
Le frontend maintient une copie locale de l’inbox et fusionne les données provenant de l’API HTTP avec les événements temps réel. Le service principal est user-notification.service.ts.
flowchart LR
API[GET /notifications] --> UNS[UserNotificationService]
SOCK[SupportSocketService] -->|notification.created| UNS
UNS --> STATE[BehaviorSubject notifications]
STATE --> UI[Badge / liste / toast]
UI -->|mark as read| READ[POST /notifications/:uid/read]
UI -->|delete| DEL[DELETE /notifications/:uid]
READ --> UNS
DEL --> UNS
Responsabilités du frontend
GET /notificationsPersistance Redis
L’inbox d’un utilisateur est stockée dans une liste Redis dont la clé est dérivée de son identifiant. Les nouvelles notifications sont insérées en têtelots via . LPUSHsendEachForMulticastet la clé reçoit une durée de rétention.
Les opérations read/unread/delete utilisent la liste existante et modifient ou retirent l’entrée concernée.
Notifications liées à un jeu
Le système possède également un chemin de notification lié à un jeu. Avant l’envoi, le backend vérifie que les subscriptions FCM sont toujours cohérentes avec les product codes réellement possédés. Cela évite d’envoyer une notification de jeu à un appareil dont l’accès a été retiré ou réassigné.
Gestion des erreurs
UserFcmSubscription ni de filtrage des appareils par productCode. Si les variables Firebase sont Notifications viaenvoyées HTTP.
par le jeu
POST /saveNotification reçoit userUid (profil jeu du destinataire), notificationType, extraData et éventuellement isImportant. GameNotificationService traduit le profil actif ProductsCode.gameOid en compte Web et vérifie la simulation BrainCloud indiquée par extraData.simUid.
L’expéditeur doit posséder un profil actif membre de cette simulation; le destinataire doit aussi en être membre. Le serveur utilise teacherUid et les clés de students du document pour cette vérification. Les types réservés au support sont refusés, le payload JSON est limité à 2 048 caractères et les identifiants à 255 caractères. La vérification BrainCloud expire après dix secondes. Une fois validée, la notification suit exactement le flux commun notify().
Fichiers principaux
uniksim-back-end/src/service/notification.service.ts
uniksim-back-end/src/service/game-notification.service.ts, firebase.service.ts
uniksim-back-end/src/dto/notification.dto.ts, src/gateway/support.account.gateway.ts, src/guards/socketAuth.middleware.ts
uniksimFrontEnd/src/app/app.controller.ts et NOTIFICATION_CONFIG dans src/node.js/server/constantsVariable.js
Angular : service/account/account-socket.service.ts, service/realtime/realtime-socket.ts, service/notifications/user-notification.service.ts, Models/Notification.ts
Tests : uniksimFrontEnd/src/app/service/support/support-socket.test/notification/notification.service.test.ts et game-notification.service.test.ts
Points
Voir d’attentionaussi