Checkpoint: Ajout de la possibilité de joindre un fichier dans l'envoi des rappels par email

Modifications apportées :
- Ajout des colonnes nomFichier, urlFichier, s3Key, typeFichier, tailleFichier dans la table rappels
- Création du composant FileUpload pour l'upload de fichiers vers S3 (max 10 Mo)
- Création de l'endpoint API /api/upload-file pour gérer l'upload
- Intégration du composant FileUpload dans les formulaires de création et modification de rappels
- Mise à jour des procédures tRPC create et update pour gérer les informations de fichier
- Modification des fonctions sendRappelJ7Email et sendRappelJ1Email pour inclure les pièces jointes
- Mise à jour du scheduler de rappels pour passer les informations de fichier lors de l'envoi
- Les fichiers sont téléchargés depuis S3 et convertis en base64 pour être attachés aux emails
This commit is contained in:
Manus
2026-01-08 06:00:27 -05:00
parent 6e25c00865
commit 5308b7921e
16 changed files with 2613 additions and 4 deletions

View File

@@ -229,6 +229,9 @@ export async function sendRappelJ7Email(params: {
dates: Array<{ dateDebut: Date; dateFin: Date; ordre: number }>;
lieu: string;
formateur?: string;
attachmentUrl?: string;
attachmentFilename?: string;
attachmentMimeType?: string;
}): Promise<boolean> {
const fonctionLabel = params.apprenantFonction === 'directeur' ? 'Directeur' :
params.apprenantFonction === 'chef_service' ? 'Chef de service' : '';
@@ -282,10 +285,32 @@ export async function sendRappelJ7Email(params: {
formateur: params.formateur || '',
};
// Préparer les pièces jointes si nécessaire
const attachments: Array<{ filename: string; content: string; contentType: string }> = [];
if (params.attachmentUrl && params.attachmentFilename && params.attachmentMimeType) {
try {
// Télécharger le fichier depuis S3 et le convertir en base64
const response = await fetch(params.attachmentUrl);
const buffer = await response.arrayBuffer();
const base64 = Buffer.from(buffer).toString('base64');
attachments.push({
filename: params.attachmentFilename,
content: base64,
contentType: params.attachmentMimeType,
});
} catch (error) {
console.error('[Email] Erreur lors du téléchargement de la pièce jointe:', error);
// Continuer l'envoi sans la pièce jointe
}
}
return sendEmail({
to: params.apprenantEmail,
subject: `Rappel J-7 : ${params.formationNom}`,
html: await getEmailTemplate(content, 'rappel', variables),
attachments: attachments.length > 0 ? attachments : undefined,
});
}
@@ -302,6 +327,9 @@ export async function sendRappelJ1Email(params: {
dates: Array<{ dateDebut: Date; dateFin: Date; ordre: number }>;
lieu?: string;
formateur?: string;
attachmentUrl?: string;
attachmentFilename?: string;
attachmentMimeType?: string;
}): Promise<boolean> {
const fonctionLabel = params.apprenantFonction === 'directeur' ? 'Directeur' :
params.apprenantFonction === 'chef_service' ? 'Chef de service' : '';
@@ -358,10 +386,32 @@ export async function sendRappelJ1Email(params: {
formateur: params.formateur || '',
};
// Préparer les pièces jointes si nécessaire
const attachments: Array<{ filename: string; content: string; contentType: string }> = [];
if (params.attachmentUrl && params.attachmentFilename && params.attachmentMimeType) {
try {
// Télécharger le fichier depuis S3 et le convertir en base64
const response = await fetch(params.attachmentUrl);
const buffer = await response.arrayBuffer();
const base64 = Buffer.from(buffer).toString('base64');
attachments.push({
filename: params.attachmentFilename,
content: base64,
contentType: params.attachmentMimeType,
});
} catch (error) {
console.error('[Email] Erreur lors du téléchargement de la pièce jointe:', error);
// Continuer l'envoi sans la pièce jointe
}
}
return sendEmail({
to: params.apprenantEmail,
subject: `Rappel J-1 : ${params.formationNom} - C'est demain !`,
html: await getEmailTemplate(content, 'rappel', variables),
attachments: attachments.length > 0 ? attachments : undefined,
});
}