Files
wondif_vue/server/api/projet-academie.post.js
2026-06-07 10:16:15 +02:00

288 lines
8.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createError, readBody } from "h3"
import { getMysqlPool } from "~~/server/utils/mysql"
import { sendProjetAcademieEmails } from "~~/server/utils/mailer"
function normalizeValue(value) {
return typeof value === "string" ? value.trim() : ""
}
function normalizeBoolean(value) {
return value === true
}
function normalizePositiveInteger(value) {
const number = Number(value)
return Number.isInteger(number) && number > 0 ? number : null
}
function normalizeDiploma(diploma) {
return {
type: normalizeValue(diploma?.type),
otherType: normalizeValue(diploma?.otherType),
discipline: normalizeValue(diploma?.discipline),
year: normalizeValue(diploma?.year),
establishment: normalizeValue(diploma?.establishment),
}
}
function isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
}
function withTimeout(promise, delay, message) {
return Promise.race([
promise,
new Promise((_, reject) => {
setTimeout(() => reject(new Error(message)), delay)
}),
])
}
function hasDiplomaData(diploma) {
return Boolean(diploma.type || diploma.otherType || diploma.discipline || diploma.year || diploma.establishment)
}
function validateDiploma(diploma) {
if (!hasDiplomaData(diploma)) {
return true
}
if (!diploma.type || !diploma.discipline || !diploma.year || !diploma.establishment) {
return false
}
if (diploma.type === "Autre" && !diploma.otherType) {
return false
}
return true
}
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const payload = {
lastName: normalizeValue(body?.lastName).toUpperCase(),
firstName: normalizeValue(body?.firstName),
gender: normalizeValue(body?.gender),
birthDate: normalizeValue(body?.birthDate),
birthPlace: normalizeValue(body?.birthPlace),
nationality: normalizeValue(body?.nationality),
email: normalizeValue(body?.email),
phone: normalizeValue(body?.phone),
address: normalizeValue(body?.address),
city: normalizeValue(body?.city),
postalCode: normalizeValue(body?.postalCode),
country: normalizeValue(body?.country),
instrument: normalizeValue(body?.instrument),
previousAcademyParticipation: normalizeValue(body?.previousAcademyParticipation),
previousAcademyParticipationCount: normalizePositiveInteger(body?.previousAcademyParticipationCount),
trainingLevel: normalizeValue(body?.trainingLevel),
otherTrainingLevel: normalizeValue(body?.otherTrainingLevel),
conservatory: normalizeValue(body?.conservatory),
otherConservatory: normalizeValue(body?.otherConservatory),
teacherName: normalizeValue(body?.teacherName),
diplomas: Array.isArray(body?.diplomas)
? body.diplomas.slice(0, 3).map(normalizeDiploma)
: [],
emergencyLastName: normalizeValue(body?.emergencyLastName),
emergencyFirstName: normalizeValue(body?.emergencyFirstName),
emergencyRelation: normalizeValue(body?.emergencyRelation),
emergencyPhone: normalizeValue(body?.emergencyPhone),
emergencyEmail: normalizeValue(body?.emergencyEmail),
acceptRules: normalizeBoolean(body?.acceptRules),
}
while (payload.diplomas.length < 3) {
payload.diplomas.push(normalizeDiploma({}))
}
if (
!payload.lastName ||
!payload.firstName ||
!payload.gender ||
!payload.birthDate ||
!payload.birthPlace ||
!payload.nationality ||
!payload.email ||
!payload.phone ||
!payload.address ||
!payload.city ||
!payload.postalCode ||
!payload.country ||
!payload.instrument ||
!payload.previousAcademyParticipation ||
!payload.trainingLevel ||
!payload.conservatory ||
!payload.teacherName ||
!payload.emergencyLastName ||
!payload.emergencyFirstName ||
!payload.emergencyRelation ||
!payload.emergencyPhone ||
!payload.emergencyEmail ||
!payload.acceptRules
) {
throw createError({
statusCode: 400,
statusMessage: "Tous les champs obligatoires doivent être remplis.",
})
}
if (!isValidEmail(payload.email) || !isValidEmail(payload.emergencyEmail)) {
throw createError({
statusCode: 400,
statusMessage: "Une adresse email nest pas valide.",
})
}
if (payload.previousAcademyParticipation === "oui" && !payload.previousAcademyParticipationCount) {
throw createError({
statusCode: 400,
statusMessage: "Le nombre de participations est obligatoire.",
})
}
if (payload.trainingLevel === "Autre" && !payload.otherTrainingLevel) {
throw createError({
statusCode: 400,
statusMessage: "Lautre formation est obligatoire.",
})
}
if (payload.conservatory === "Autre" && !payload.otherConservatory) {
throw createError({
statusCode: 400,
statusMessage: "Lautre conservatoire est obligatoire.",
})
}
if (!payload.diplomas.every(validateDiploma)) {
throw createError({
statusCode: 400,
statusMessage: "Chaque diplôme renseigné doit être complet.",
})
}
const db = getMysqlPool()
const [diploma1, diploma2, diploma3] = payload.diplomas
try {
const [result] = await db.execute(
`
INSERT INTO academie_orchestre_candidatures (
nom,
prenom,
genre,
date_naissance,
lieu_naissance,
nationalite,
email,
telephone,
adresse,
ville,
code_postal,
pays_residence,
instrument,
deja_participe_academie,
nombre_participations_academie,
niveau_cycle_2026_2027,
autre_formation,
conservatoire_2026_2027,
autre_conservatoire,
professeur_instrument,
diplome_1_type,
diplome_1_autre_type,
diplome_1_discipline,
diplome_1_annee,
diplome_1_etablissement,
diplome_2_type,
diplome_2_autre_type,
diplome_2_discipline,
diplome_2_annee,
diplome_2_etablissement,
diplome_3_type,
diplome_3_autre_type,
diplome_3_discipline,
diplome_3_annee,
diplome_3_etablissement,
contact_urgence_nom,
contact_urgence_prenom,
contact_urgence_lien,
contact_urgence_telephone,
contact_urgence_email,
reglement_accepte
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`,
[
payload.lastName,
payload.firstName,
payload.gender,
payload.birthDate,
payload.birthPlace,
payload.nationality,
payload.email,
payload.phone,
payload.address,
payload.city,
payload.postalCode,
payload.country,
payload.instrument,
payload.previousAcademyParticipation,
payload.previousAcademyParticipationCount,
payload.trainingLevel,
payload.otherTrainingLevel,
payload.conservatory,
payload.otherConservatory,
payload.teacherName,
diploma1.type,
diploma1.otherType,
diploma1.discipline,
diploma1.year,
diploma1.establishment,
diploma2.type,
diploma2.otherType,
diploma2.discipline,
diploma2.year,
diploma2.establishment,
diploma3.type,
diploma3.otherType,
diploma3.discipline,
diploma3.year,
diploma3.establishment,
payload.emergencyLastName,
payload.emergencyFirstName,
payload.emergencyRelation,
payload.emergencyPhone,
payload.emergencyEmail,
payload.acceptRules,
]
)
let emailsSent = false
try {
emailsSent = await withTimeout(
sendProjetAcademieEmails(payload),
15000,
"Délai dépassé pour l'envoi email projet-academie."
)
} catch (mailError) {
console.error("Erreur envoi email projet-academie:", mailError)
}
return {
ok: true,
id: result.insertId,
emailsSent,
}
} catch (error) {
console.error("Erreur API projet-academie:", error)
throw createError({
statusCode: 500,
statusMessage: "Impossible denregistrer la candidature pour le moment.",
})
}
})