Documentation MVLS - Intégration DEMA1N

Version : 1.0
Dernière mise à jour : 12/12/2025

Table des matières

  1. Vue d'ensemble
  2. Architecture
  3. Configuration
  4. Intégration RabbitMQ → mvls-rabbitmq.md
  5. Suivi MVLS avec Inspire
  6. Templates Brevo
  7. Champs spécifiques MVLS
  8. Dépannage

Vue d'ensemble

MVLS (Mentoré Lycéen) est une intégration spécifique de DEMA1N qui permet de gérer les jeunes lycéens et les bénévoles éclaireurs dans un contexte particulier. Cette intégration utilise :

  • RabbitMQ pour la synchronisation des données entre DEMA1N et la plateforme MVLS
  • Templates Brevo pour l'envoi d'emails personnalisés
  • Sandbox pour isoler les données MVLS des autres utilisateurs DEMA1N
  • Champs spécifiques dans externalInfos pour stocker les données MVLS

Concepts clés

  • Sandbox : Les utilisateurs MVLS ont sandbox === 'MVLS' pour les distinguer des autres utilisateurs DEMA1N
  • Lycéen : Jeune MVLS avec le rôle lyceen
  • Éclaireur : Bénévole MVLS avec le rôle eclaireur
  • Binôme MVLS : Relation entre un lycéen et un éclaireur MVLS

Architecture

Structure des modules

back/src/mvls/
├── mvls.module.ts          # Module NestJS MVLS
├── mvls.service.ts         # Service principal MVLS
├── mvls.controller.ts       # Contrôleur MVLS
└── mvls.interfaces.ts      # Interfaces TypeScript

Flux de données

┌─────────────┐
│   DEMA1N    │
│  (Backend)  │
└──────┬──────┘
       │
       │ RabbitMQ Messages
       │ (USER_CREATED, USER_UPDATED, USER_DELETED, BINOME_CREATED, BINOME_UPDATED)
       │
       ▼
┌─────────────┐
│   RabbitMQ  │
│   Exchange │
│   "dema1n" │
└──────┬──────┘
       │
       │ Routing Key: "user___mvls"
       │
       ▼
┌─────────────┐
│  Plateforme │
│     MVLS    │
└─────────────┘

Services impliqués

  • MvlsService : Gestion des messages RabbitMQ et filtrage des données
  • JeuneService : Gestion des jeunes MVLS et publication des messages
  • BenevolesService : Gestion des bénévoles MVLS et publication des messages
  • BinomeService : Gestion des binômes MVLS et publication des messages
  • MailService : Envoi d'emails via templates Brevo pour MVLS

Configuration

Variables d'environnement

# RabbitMQ
RABBIT_MQ_URL=amqp://user:password@host:5672
RABBIT_MQ_EXCHANGE_NAME=dema1n
RABBIT_MQ_EXCHANGE_TYPE=topic

# Brevo (Sendinblue)
BREVO_API_KEY=votre_clé_api_brevo
BREVO_URL=https://api.brevo.com/v3

# Producer (pour identifier les messages)
PRODUCER=dema1n

Configuration RabbitMQ

L'exchange RabbitMQ est configuré dans mvls.module.ts :

RabbitMQModule.forRootAsync({
  exchanges: [
    {
      name: configService.get<string>('RABBIT_MQ_EXCHANGE_NAME'),
      type: configService.get<string>('RABBIT_MQ_EXCHANGE_TYPE'),
      options: {
        durable: true,
      },
    },
  ],
});

Migration base de données

Une migration a été ajoutée pour supporter les templates Brevo :

// Migration: 1765124120829-addedBrevoTemplateId.ts
ALTER TABLE `message_template` ADD `brevoTemplateId` bigint NULL;

Fenêtre éclaireur (lue depuis l'API inspire)

Dans le BO binôme (pages/bo/binomes/_id/index.vue), pour un binôme de la sandbox MVLS, le statut bénévole proposé par défaut à l'annulation ou à la fin d'un binôme (CancellationReasonsDialog, TerminationReasonsDialog) est APTE si MVLS est ouvert pour les éclaireurs, NON_DISPONIBLE sinon. Hors sandbox MVLS, le défaut reste APTE. La page appelle GET /mvls-options/is-mvls-eclaireur-window-open sur l'API inspire (route publique : dema1n n'a pas de JWT inspire).

  • Si l'appel échoue, le défaut reste APTE (comportement antérieur) ; l'admin peut toujours changer le statut dans le dropdown.

Système de suivi MVLS avec Inspire

Pour les binômes MVLS, les emails de checkpoint (steps avec suiviActivated = true) contiennent des liens vers Inspire Orientation ({{ params.contactok }} / {{ params.nocontact }}). Inspire reçoit SUIVI_CREATED, affiche le formulaire, puis répond via SUIVI_UPDATE_FROM_INSPIRE ; DEMA1N notifie ensuite SUIVI_UPDATED.

Format des URLs, token et messages RabbitMQ : mvls-rabbitmq.md.


Templates Brevo

Configuration

Les templates Brevo sont configurés dans la table message_template avec le champ brevoTemplateId :

ALTER TABLE `message_template` ADD `brevoTemplateId` bigint NULL;

Utilisation

Lors de l'envoi d'un email via MailService.send(), si le template a un brevoTemplateId, l'email est envoyé via l'API Brevo au lieu de SMTP classique :

if (template.brevoTemplateId) {
  const brevoResult = await this.sendForTemplate(
    cleanedMailTo,
    template.brevoTemplateId,
    data,
    view, // Slug pour le log
    template.subject, // Sujet pour le log
  );
}

Format des données envoyées à Brevo

{
  templateId: number,
  messageVersions: [
    {
      to: [{ email: "destinataire@example.com" }],
      params: {
        // Variables du template Brevo
        prenom: "Jean",
        nom: "Dupont",
        // ... autres variables
      }
    }
  ]
}

Logs MAIL

Les emails envoyés via Brevo sont loggés dans la table log-mail avec :

  • Le slug du template
  • Le destinataire (sans préfixe mvls_)
  • Le sujet du template
  • Un HTML contenant les variables transmises et la réponse Brevo API

Préfixe mvls_

Les emails MVLS peuvent avoir un préfixe mvls_ dans DEMA1N (ex: mvls_jean.dupont@example.com). Ce préfixe est automatiquement retiré avant l'envoi à Brevo pour garantir la compatibilité.


Champs spécifiques MVLS

Structure externalInfos

Les données spécifiques MVLS sont stockées dans le champ externalInfos (JSON) des entités Jeune et Benevole.

Champs lycéen (Jeune MVLS)

{
  // Scolarité
  nomClasse: string | null;              // Nom de la classe
  domaines: string[] | null;             // Domaines d'intérêt
  domainesAutre: string | null;          // Autre domaine (si "Autre" sélectionné)
  formations: string[] | null;           // Formations souhaitées
  formationsAutre: string | null;        // Autre formation (si "Autre" sélectionné)
  alternance: boolean | null;             // Intérêt pour l'alternance

  // Questions scolarité
  etudesSup: string | null;              // "totaly" | "kinda" | "notreally" | "no"
  travailEfficace: string | null;        // "totaly" | "kinda" | "notreally" | "no"
  preparationSup: string | null;         // "yes" | "kinda" | "no"

  // Mentorat
  mentor_sexe: string | null;            // Préférence de genre du mentor
  communication: string[] | null;        // Préférences de communication

  // Représentant légal
  legalRepresentativeEmail: string | null;
  legalRepresentativePhone: string | null;

  // Adresse
  streetNumber: string | null;
  street: string | null;
  zipcode: string | null;
  city: string | null;

  // Autres
  voeux_formation: string | null;
  besoins: string[] | null;
  statut: string | null;
  state: string | null;
  dateUpdateStatut: Date | string | null;
  dateUpdateState: Date | string | null;
}

Champs éclaireur (Bénévole MVLS)

{
  // Formations
  formations: string[] | null;
  formationsAutre: string | null;

  // Domaines
  domaines: string | string[] | null;
  domainesAutre: string | null;

  // Autres
  casierJudiciaire: boolean | null;
  precision: string | null;
  besoins: string[] | null;
  alternance: boolean | null;
  annee: string | null;
  sourceOfFinanceStudies: string | null;
  statut: string | null;
  state: string | null;
  dateUpdateStatut: Date | string | null;
  dateUpdateState: Date | string | null;
}

Options des champs scolarité

affirmationOptions (pour etudesSup et travailEfficace)

[
  { label: 'Oui, totalement', value: 'totaly' },
  { label: 'Oui, plutôt', value: 'kinda' },
  { label: 'Non, pas vraiment', value: 'notreally' },
  { label: 'Non, pas du tout', value: 'no' },
];

preparationSupOptions (pour preparationSup)

[
  { label: 'Oui, suffisamment', value: 'yes' },
  { label: 'Oui, mais pas assez', value: 'kinda' },
  { label: 'Non, jamais', value: 'no' },
];

Dépannage

  • Champs MVLS dans le BO : /bo/jeunes/{id} (section « SCOLARITÉ ») et /bo/benevoles/{id} (section éclaireur). Visibles uniquement si user.sandbox === 'MVLS' et externalInfos renseigné.
  • Messages RabbitMQ : docker-compose logs -f api | grep -i "mvls\|rabbitmq".
  • Emails : table log-mail (WHERE slug LIKE '%mvls%' ORDER BY date_envoi DESC).

Les messages RabbitMQ ne partent pas

Vérifier user.sandbox === 'MVLS', RABBIT_MQ_URL, et que l'exchange dema1n existe.

Les emails Brevo ne partent pas

Vérifier que le template a un brevoTemplateId, BREVO_API_KEY, la table log-mail et les logs (grep -i "brevo").


Support

Pour toute question ou problème concernant l'intégration MVLS, contactez l'équipe technique DEMA1N.

Version du document : 1.0
Dernière mise à jour : 12/12/2025