Droit à l'image par signature électronique (membre + accompagnants)
Remplace la feuille à imprimer par un recueil électronique du consentement, construit selon l'article 9 du Code civil (droit à l'image = droit de la personnalité, personnel) : - Le membre signe une fois, dans son espace, une autorisation GÉNÉRALE couvrant toute photo de lui — plus besoin de valider chaque publication. Capture d'une signature dessinée (pad canvas), nom, horodatage et IP : une signature électronique simple, preuve de consentement (art. 7 RGPD). Étape proposée au premier accès mais NON bloquante (« Plus tard »). - Un adulte ne pouvant pas consentir pour un autre, l'image des accompagnants est recueillie PAR PERSONNE au moment de l'inscription à la rencontre : case « autorise / n'autorise pas » par participant + attestation du membre d'avoir informé chaque personne et obtenu son accord (mineur : représentant légal). - La publication n'est plus bloquée par le statut de consentement (évite le blocage systématique) ; le consentement est la preuve conservée. - Admin : statut d'autorisation dans la liste des membres (avec la signature consultable) et par participant dans la liste des inscrits (badges + exports Excel/impression). - Table image_consents (journal append-only) et colonne inscriptions.image_consent, migrations idempotentes. - Politique de confidentialité mise à jour (consentement par personne, fondement art. 9, cas des mineurs). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fkg15RCxNgUys4ru73He2o
This commit is contained in:
12 files changed
+516
-48
No files matched your search
+26
-1
@@ -31,8 +31,15 @@ export const demandeSchema = z.object({
|
||||
tel: trimmed(30, 6),
|
||||
});
|
||||
|
||||
// Each participant carries their own image-rights decision (an adult can't
|
||||
// consent for another — art. 9 Code civil), and the member attests they
|
||||
// informed each accompanying person and obtained their agreement.
|
||||
export const inscriptionPublicSchema = z.object({
|
||||
participants: z.array(trimmed(120, 1)).min(1).max(100),
|
||||
participants: z
|
||||
.array(z.object({ nom: trimmed(120, 1), imageConsent: z.boolean() }))
|
||||
.min(1)
|
||||
.max(100),
|
||||
attestation: z.literal(true, { errorMap: () => ({ message: "l'attestation est requise" }) }),
|
||||
});
|
||||
|
||||
export const memberProfileSchema = z.object({
|
||||
@@ -51,6 +58,24 @@ export const adminMemberSchema = memberProfileSchema.extend({
|
||||
valide: z.boolean().optional(),
|
||||
});
|
||||
|
||||
// Electronic image-rights consent submitted by the member. A drawn PNG
|
||||
// signature and at least one publication scope are required to authorize;
|
||||
// refusing needs neither. Signature kept small (canvas ~500x160) to stay
|
||||
// well under the JSON body limit.
|
||||
export const imageConsentSchema = z
|
||||
.object({
|
||||
decision: z.enum(['accepted', 'refused']),
|
||||
scopes: z.array(z.enum(['site', 'social', 'print'])).max(3).optional().default([]),
|
||||
signatoryName: trimmed(120, 1),
|
||||
signaturePng: z.string().max(60000).optional().default(''),
|
||||
})
|
||||
.refine(
|
||||
(d) =>
|
||||
d.decision !== 'accepted' ||
|
||||
(d.signaturePng.startsWith('data:image/png;base64,') && d.scopes.length > 0),
|
||||
{ message: 'une signature et au moins un support sont requis pour autoriser', path: ['signaturePng'] }
|
||||
);
|
||||
|
||||
export const rencontreSchema = z.object({
|
||||
titre: trimmed(200, 1),
|
||||
date_renc: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, 'format AAAA-MM-JJ'),
|
||||
|
||||
Reference in new issue
Block a user