MVLS — Intégration RabbitMQ
Retour : vue d'ensemble MVLS.
Intégration RabbitMQ
Types de messages
MVLS utilise plusieurs types de messages RabbitMQ :
1. Messages utilisateurs
USER_CREATED: Création d'un jeune ou bénévole MVLSUSER_UPDATED: Mise à jour d'un jeune ou bénévole MVLSUSER_DELETED: Suppression d'un jeune ou bénévole MVLS
2. Messages binômes
BINOME_CREATED: Création d'un binôme MVLSBINOME_UPDATED: Mise à jour d'un binôme MVLS (changement de statut/état)
Format des messages
Structure générale
interface IMvlsRabbitMQMessage {
header: {
name: string; // "USER_CREATED", "USER_UPDATED", "USER_DELETED", "BINOME_CREATED", "BINOME_UPDATED"
model: string; // "USER" ou "BINOME"
event: string; // "CREATED", "UPDATED", "DELETED"
date: string; // Date ISO 8601
requestId: string; // Identifiant unique de la requête
uniqid: string; // Identifiant unique du message
VERSION: string; // "1.0"
producer: string; // "dema1n"
};
body:
| IFilterLyceenDataForMvlsResult
| IFilterEclaireurDataForMvlsResult
| IUserDeletedDataForMvlsResult
| IBinomeDataForMvlsResult;
}
Message USER_CREATED / USER_UPDATED (Lycéen)
{
"header": {
"name": "USER_CREATED",
"model": "USER",
"event": "CREATED",
"date": "2025-12-12T10:00:00.000Z",
"requestId": "abc123",
"uniqid": "xyz789",
"VERSION": "1.0",
"producer": "dema1n"
},
"body": {
"charte": true,
"notification": true,
"newEmail": null,
"user": {
"gender": "M",
"birthdate": "2007-05-15",
"firstname": "Jean",
"lastname": "Dupont",
"phoneNumber": "+33612345678",
"roles": ["lyceen"],
"userJwt": {
"username": "jean.dupont@example.com",
"ssoId": "sso-123",
"activationToken": "token-abc"
},
"mvlsLyceens": [
{
"createdAt": "2025-12-01T10:00:00.000Z",
"mentor_sexe": "M",
"etudesSup": "totaly",
"travailEfficace": "kinda",
"preparationSup": "yes",
"nomClasse": "Terminale S",
"domaines": ["Sciences", "Technologie"],
"formations": ["Bac+3", "Bac+5"],
"communication": ["email", "phone"],
"statut": "EN_ATTENTE",
"state": "ACTIF"
}
],
"parcoursLyceens": [
{
"createdAt": "2025-12-01T10:00:00.000Z",
"filiere": "Scientifique",
"isBoursierSecondaire": "OUI",
"etablissement": {
"departmentCode": "75",
"nom": "Lycée Victor Hugo"
}
}
]
}
}
}
Champ newEmail (optionnel) :
- Type :
string | null - Emplacement : Au niveau du
body(racine du body) - Description : Nouvel email de l'utilisateur si différent de
user.userJwt.username. Si présent et différent deusername, l'email de l'utilisateur sera mis à jour dans DEMA1N avec le préfixemvls_(ex:mvls_nouvel.email@example.com). - Exemple avec changement d'email :
{
"body": {
"charte": true,
"notification": true,
"newEmail": "nouvel.email@example.com",
"user": {
"userJwt": {
"username": "ancien.email@example.com"
}
}
}
}
Message USER_DELETED
{
"header": {
"name": "USER_DELETED",
"model": "USER",
"event": "DELETED",
"date": "2025-12-12T10:00:00.000Z",
"requestId": "abc123",
"uniqid": "xyz789",
"VERSION": "1.0",
"producer": "dema1n"
},
"body": {
"email": "jean.dupont@example.com"
}
}
Message BINOME_CREATED / BINOME_UPDATED
{
"header": {
"name": "BINOME_CREATED",
"model": "BINOME",
"event": "CREATED",
"date": "2025-12-12T10:00:00.000Z",
"requestId": "abc123",
"uniqid": "xyz789",
"VERSION": "1.0",
"producer": "dema1n"
},
"body": {
"binome_id": "123",
"jeune_id": "456",
"benevole_id": "789",
"jeune_email": "jean.dupont@example.com",
"benevole_email": "marie.martin@example.com",
"status": "EN_ATTENTE",
"state": "ACTIF",
"creationDate": "2025-12-12T10:00:00.000Z",
"buildDate": null,
"statusUpdateDate": "2025-12-12T10:00:00.000Z"
}
}
Routing Key
Tous les messages MVLS utilisent le même routing key : user___mvls
Quand les messages sont envoyés
Messages utilisateurs
- USER_CREATED : Lors de la création d'un jeune ou bénévole MVLS
- USER_UPDATED :
- Lors de la mise à jour d'un jeune MVLS via
JeuneService.updateAdmin() - Lors de la mise à jour d'un bénévole MVLS via
BenevolesService.updateAdmin() - USER_DELETED :
- Lors de la suppression d'un jeune MVLS via
JeuneService.deleteJeune() - Lors de la suppression d'un bénévole MVLS via
BenevolesService.deleteBenevole()
Messages binômes
- BINOME_CREATED : Lors de la création d'un binôme MVLS via
BinomeService.createBinome() - BINOME_UPDATED : Lors de la mise à jour d'un binôme MVLS (changement de statut ou d'état)
Messages suivis
- SUIVI_CREATED : Lors de la création d'un suivi MVLS (checkpoint) via
SuivistatusService.createSuivistatus() - SUIVI_UPDATED : Lors de la mise à jour d'un suivi MVLS via
SuivistatusService.changeSuivistatus()
Format du message SUIVI_CREATED / SUIVI_UPDATED :
{
"header": {
"name": "SUIVI_CREATED",
"model": "SUIVI",
"event": "CREATED",
"date": "2025-12-12T10:00:00.000Z",
"requestId": "abc123",
"uniqid": "xyz789",
"VERSION": "1.0",
"producer": "dema1n"
},
"body": {
"suivi": {
"suivi_id": "123",
"binome_id": "456",
"step_id": "789",
"day_step": 5,
"status": "EN_ATTENTE",
"status_jeune": "EN_ATTENTE",
"status_benevole": "EN_ATTENTE",
"creation_date": "2025-12-12T10:00:00.000Z",
"status_update_date": "2025-12-12T10:00:00.000Z"
}
}
}
Réponse d'Inspire (lien dans l'email de checkpoint)
Les emails Brevo de checkpoint reçoivent {{ params.contactok }} (RAS, actif = '1') et {{ params.nocontact }} (problème, actif = '0'), construits dans MessagesService (binomes/services/messages.service.ts) :
{INSPIRE_BASE_URL}/mentorat/suivi/:token/:contactStatus/:suiviId/:type avec contactStatus = jeune | benevole, type = contactok | nocontact et token = md5(binomeId + '/suivi/' + suiviId + '/' + contactStatus + '/' + type).
Inspire répond par un message SUIVI_UPDATE_FROM_INSPIRE (exchange dema1n, routing key user___mvls, body.suivi_update). Champs : ISuiviUpdateFromInspire dans back/src/mvls/mvls.interfaces.ts ; traitement : MvlsService (ignore les suivis inconnus ou non MVLS, sans erreur renvoyée). DEMA1N notifie ensuite SUIVI_UPDATED.
Réception des messages
Le service MVLS écoute les messages entrants via RabbitMQ :
@RabbitRPC({
exchange: 'dema1n',
queue: 'Dema1n_mvls',
routingKey: 'user___mvls'
})
public async pubSubHandler(msg: IMvlsRabbitMQMessage) {
// Traitement des messages reçus
}
Gestion du champ newEmail dans USER_UPDATED et USER_CREATED
Lors de la réception d'un message USER_UPDATED ou USER_CREATED, le champ newEmail peut être présent au niveau du body pour indiquer un changement d'email :
- Si
newEmailest présent et différent deuser.userJwt.username: - L'utilisateur est recherché par son ancien email (avec préfixe
mvls_) :mvls_+user.userJwt.username - L'email de l'utilisateur est mis à jour avec le nouvel email (avec préfixe
mvls_) :mvls_+newEmail -
Les autres champs de l'utilisateur sont également mis à jour selon les données du message
-
Si
newEmailestnullou identique àusername: - Aucune mise à jour de l'email n'est effectuée
- Seuls les autres champs sont mis à jour
Exemple de traitement :
// Message reçu avec newEmail différent de username
{
"body": {
"newEmail": "nouvel.email@example.com",
"user": {
"userJwt": {
"username": "ancien.email@example.com"
}
}
}
}
// Comportement :
// 1. Recherche de l'utilisateur : findByEmailMvls('mvls_ancien.email@example.com')
// 2. Mise à jour de l'email : user.email = 'mvls_nouvel.email@example.com'
// 3. Mise à jour des autres champs (firstName, lastName, etc.)