From d90afe53a07ad02e3b3863c9665807ee46ea84dd Mon Sep 17 00:00:00 2001 From: R0m1k3 Date: Tue, 11 Aug 2026 15:07:11 +0200 Subject: [PATCH] =?UTF-8?q?Recueillir=20=C3=A0=20l'embauche=20ce=20qu'exig?= =?UTF-8?q?e=20le=20contrat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trois corrections sur le formulaire d'embauche, dont une qui explique le blocage rencontré sur le planning. L'équipe devient **requise** dès qu'un contrat est ouvert. Elle était facultative, avec un « Aucune pour l'instant » qui paraissait anodin : le planning s'ordonnant par équipe, le salarié n'apparaissait alors sur aucune grille, et rien ne le signalait avant la première semaine à couvrir. Quand l'établissement choisi n'a aucune équipe, le champ le dit et renvoie vers les réglages plutôt que de laisser deviner. Le contrôle est repris côté serveur : la validation du navigateur ne protège pas une action. Le type de contrat n'a plus de valeur par défaut, et les neuf valeurs sont rangées par ordre alphabétique. Un CDI pré-rempli est un type que personne n'a choisi, alors qu'il commande les règles de durée et la déclaration ; et le classement par fréquence supposée fait chercher les huit autres. L'envoi des plannings par SMS disparaît, formulaire, dossier et colonne. Le drapeau recueillait un consentement pour un canal qui n'a jamais existé et qu'il n'est pas prévu de brancher. Un consentement conservé sans finalité est une donnée collectée sans base légale : la minimisation impose de la supprimer, pas de la garder au cas où. Une divergence assumée avec le produit audité : la case « ouvrir un contrat maintenant » reste. Il faut pouvoir créer un administrateur ou un manager invité sans lui inventer un contrat de travail. Co-Authored-By: Claude Opus 5 --- .../20260811160000_drop_sms/migration.sql | 11 +++ prisma/schema.prisma | 4 - src/app/(app)/equipe/AddEmployeeForm.tsx | 85 +++++++++++++------ .../(app)/equipe/[id]/PersonalInfoPanel.tsx | 19 ----- src/app/(app)/equipe/[id]/page.tsx | 1 - src/server/employees/actions.ts | 8 +- src/server/employees/profile-actions.ts | 4 - src/server/employees/queries.ts | 2 - 8 files changed, 75 insertions(+), 59 deletions(-) create mode 100644 prisma/migrations/20260811160000_drop_sms/migration.sql diff --git a/prisma/migrations/20260811160000_drop_sms/migration.sql b/prisma/migrations/20260811160000_drop_sms/migration.sql new file mode 100644 index 0000000..e1491e2 --- /dev/null +++ b/prisma/migrations/20260811160000_drop_sms/migration.sql @@ -0,0 +1,11 @@ +-- --------------------------------------------------------------------------- +-- Retrait de l'envoi des plannings par SMS. +-- +-- Le drapeau était un consentement recueilli pour un canal qui n'a jamais +-- existé : aucun envoi de SMS n'est branché, et il n'est pas prévu de l'être. +-- Un consentement conservé sans finalité est une donnée collectée sans base +-- légale — la minimisation impose de la supprimer, pas de la garder « au cas +-- où ». +-- --------------------------------------------------------------------------- + +ALTER TABLE "EmployeeProfile" DROP COLUMN IF EXISTS "smsSchedules"; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 07448d5..77484a8 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -603,10 +603,6 @@ model EmployeeProfile { landline String? personalEmail String? - /// Envoi des plannings par SMS. Un consentement, donc explicitement faux - /// par défaut : la charge de la preuve pèse sur l'employeur. - smsSchedules Boolean @default(false) - socialSecurityNumberEnc Bytes? ibanEnc Bytes? bicEnc Bytes? diff --git a/src/app/(app)/equipe/AddEmployeeForm.tsx b/src/app/(app)/equipe/AddEmployeeForm.tsx index 5d4b472..59d4d19 100644 --- a/src/app/(app)/equipe/AddEmployeeForm.tsx +++ b/src/app/(app)/equipe/AddEmployeeForm.tsx @@ -25,18 +25,35 @@ import type { const empty: ActionState = {}; +/** + * Les neuf types de contrat, par ordre alphabétique. + * + * Pas de « CDI en premier » : le classement par fréquence supposée fait chercher + * les huit autres, et se lit comme un défaut à accepter. L'ordre alphabétique + * ne privilégie rien et se parcourt sans réfléchir. + */ const CONTRACT_TYPES = [ - ['CDI', 'CDI'], - ['CDD', 'CDD'], ['APPRENTISSAGE', 'Apprentissage'], - ['STAGIAIRE', 'Stagiaire'], - ['SAISONNIER', 'Saisonnier'], - ['EXTRA', 'Extra'], - ['INTERIM', 'Intérim'], + ['CDD', 'CDD'], + ['CDI', 'CDI'], ['DIRIGEANT_ASSIMILE_SALARIE', 'Dirigeant assimilé salarié'], ['DIRIGEANT_NON_SALARIE', 'Dirigeant non salarié'], + ['EXTRA', 'Extra'], + ['INTERIM', 'Intérim'], + ['SAISONNIER', 'Saisonnier'], + ['STAGIAIRE', 'Stagiaire'], ] as const; +/** Marque d'obligation, annoncée aussi aux lecteurs d'écran. */ +function Required() { + return ( + + * + (requis) + + ); +} + const selectClass = 'h-9 min-w-0 rounded-2 border border-line-2 bg-surface px-2 text-sm text-ink-1 outline-none focus-visible:border-focus'; @@ -136,20 +153,6 @@ export function AddEmployeeForm({ /> - - @@ -186,9 +189,22 @@ export function AddEmployeeForm({ /> + {/* Aucune valeur par défaut : un type de contrat pré-rempli est + un type que personne n'a choisi, et il commande les règles de + durée comme la déclaration. */} + {/* L'équipe est **requise** avec un contrat. Le planning + s'ordonne par équipe : un salarié rattaché à l'établissement + mais à aucune équipe n'apparaît sur aucune grille, et rien ne + le signale avant la première semaine à couvrir. */}