refactor(mail): #28 un seul template email parent (principal + co-parent)

Made-with: Cursor
This commit is contained in:
MARTIN Julien 2026-04-17 18:37:47 +02:00
parent 94d9428c43
commit 7590c95f06
6 changed files with 9 additions and 39 deletions

View File

@ -44,8 +44,7 @@ describe('MailService (ticket #28)', () => {
});
it.each<[ValidationAccountEmailKind, string]>([
['parent_primary', 'Compte validé'],
['parent_coparent', 'Co-parent'],
['parent', 'Compte parent validé'],
['am', 'Inscription validée'],
])('sendValidatedAccountPasswordSetupEmail (%s) utilise Handlebars + lien token', async (kind, subjectPart) => {
const token = '11111111-2222-3333-4444-555555555555';

View File

@ -5,7 +5,7 @@ import * as Handlebars from 'handlebars';
import { AppConfigService } from '../config/config.service';
/** Ticket #28 — quel template d'email envoyer après validation de compte */
export type ValidationAccountEmailKind = 'parent_primary' | 'parent_coparent' | 'am';
export type ValidationAccountEmailKind = 'parent' | 'am';
@Injectable()
export class MailService {
@ -18,8 +18,7 @@ export class MailService {
private templateBasename(kind: ValidationAccountEmailKind): string {
const map: Record<ValidationAccountEmailKind, string> = {
parent_primary: 'account-validated-parent-primary',
parent_coparent: 'account-validated-parent-coparent',
parent: 'account-validated-parent',
am: 'account-validated-am',
};
return map[kind];
@ -67,8 +66,7 @@ export class MailService {
const html = this.getCompiledTemplate(kind)(data) as string;
const subjects: Record<ValidationAccountEmailKind, string> = {
parent_primary: `${appName} — Compte validé : créez votre mot de passe`,
parent_coparent: `${appName} — Co-parent : créez votre mot de passe`,
parent: `${appName} — Compte parent validé : créez votre mot de passe`,
am: `${appName} — Inscription validée : créez votre mot de passe`,
};

View File

@ -1,14 +0,0 @@
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<h2 style="color: #4CAF50;">Bonjour {{prenom}} {{nom}},</h2>
<p>Le dossier d'inscription sur <strong>{{appName}}</strong> auquel vous êtes rattaché·e en tant que <strong>co-parent</strong> a été <strong>validé</strong>.</p>
{{#if numeroDossier}}
<p><strong>Numéro de dossier :</strong> {{numeroDossier}}</p>
{{/if}}
<p>Vous devez maintenant <strong>définir votre mot de passe</strong> pour accéder à l'application avec votre propre compte.</p>
<div style="text-align: center; margin: 30px 0;">
<a href="{{{createPasswordUrl}}}" style="background-color: #4CAF50; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; font-weight: bold;">Créer mon mot de passe</a>
</div>
<p style="color: #666; font-size: 13px;">Si le bouton ne fonctionne pas, copiez ce lien dans votre navigateur :<br /><span style="word-break: break-all;">{{{createPasswordUrl}}}</span></p>
<hr style="border: 1px solid #eee; margin: 20px 0;" />
<p style="color: #666; font-size: 12px;">Cet email a été envoyé automatiquement par {{appName}}. Merci de ne pas y répondre.</p>
</div>

View File

@ -1,10 +1,10 @@
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<h2 style="color: #4CAF50;">Bonjour {{prenom}} {{nom}},</h2>
<p>Votre demande d'inscription sur <strong>{{appName}}</strong> a été <strong>validée</strong>.</p>
<p>Votre compte parent sur <strong>{{appName}}</strong> a été <strong>validé</strong>.</p>
{{#if numeroDossier}}
<p><strong>Numéro de dossier :</strong> {{numeroDossier}}</p>
{{/if}}
<p>En tant que <strong>demandeur principal</strong>, vous devez maintenant <strong>définir votre mot de passe</strong> pour accéder à l'application.</p>
<p>Pour accéder à l'application, veuillez <strong>définir votre mot de passe</strong> en cliquant sur le bouton ci-dessous.</p>
<div style="text-align: center; margin: 30px 0;">
<a href="{{{createPasswordUrl}}}" style="background-color: #4CAF50; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; font-weight: bold;">Créer mon mot de passe</a>
</div>

View File

@ -286,20 +286,8 @@ export class UserService {
savedUser.token_creation_mdp_expire_le = exp;
await this.usersRepository.save(savedUser);
let kind: ValidationAccountEmailKind = 'am';
if (savedUser.role === RoleType.ASSISTANTE_MATERNELLE) {
kind = 'am';
} else if (savedUser.numero_dossier) {
const parentsDossier = await this.usersRepository.find({
where: { numero_dossier: savedUser.numero_dossier, role: RoleType.PARENT },
order: { cree_le: 'ASC' },
});
const premier = parentsDossier[0];
kind =
premier && premier.id !== savedUser.id ? 'parent_coparent' : 'parent_primary';
} else {
kind = 'parent_primary';
}
const kind: ValidationAccountEmailKind =
savedUser.role === RoleType.ASSISTANTE_MATERNELLE ? 'am' : 'parent';
await this.mailService.sendValidatedAccountPasswordSetupEmail(
{

View File

@ -600,11 +600,10 @@ Installer et configurer Nodemailer pour l'envoi d'emails.
Créer les templates d'emails pour la validation des comptes (avec lien création MDP).
**Tâches** :
- [x] Template Parent 1 (création MDP) — `account-validated-parent-primary.hbs`
- [x] Template **Parent** (création MDP, parent principal ou co-parent) — `account-validated-parent.hbs`
- [x] URL app : Lire depuis `ConfigService.get('app_url')` (lien `/create-password?token=…`)
- [x] Nom app : Lire depuis `ConfigService.get('app_name')`
- [x] Expéditeur : via `sendEmail` (email_from_name / email_from_address)
- [x] Template Parent 2 (co-parent création MDP) — `account-validated-parent-coparent.hbs`
- [x] Template AM (création MDP) — `account-validated-am.hbs`
- [x] Intégration Handlebars + copie `.hbs` dans `dist` (`nest-cli.json` assets)
- [x] Envoi déclenché dans `UserService.validateUser` (parent / AM sans mot de passe) + renouvellement expiration token