Files
photobooth-qr/docs/decisions.md
T
KevinLecou 107e5c619a Nouvelle DA "Polaroid Néon" : écran galerie invité (maquette visuelle)
Nouvelle direction artistique actée (.claude/skills/photobooth-da/SKILL.md)
qui remplace progressivement la DA corail/prune/doré des 3 passes
précédentes. Décision associée : les invités voient désormais toutes les
photos de l'événement (revirement du "upload only" initial), cf.
docs/decisions.md — implique une mise à jour de la mention RGPD à faire.

Écran 3 du brief (galerie invité) livré en premier, comme demandé,
priorité au rendu visuel : grille de cadres polaroid (rotation aléatoire
-4°/+4°, légende manuscrite Caveat), fond noir chaud #12100E, effet
"chute avec rebond" pour un nouveau polaroid (bouton de démo temporaire
pour l'évaluer sans backend réel).

Contrastes vérifiés par calcul WCAG AA (skill) : texte clair sur fond
sombre largement conforme, mais texte clair sur les 3 couleurs d'accent
échouait (1.3:1 à 2.8:1) — corrigé en texte sombre systématique sur les
surfaces accent (6.3:1 à 13.2:1).

Nouvelles polices auto-hébergées (General Sans 700, Caveat variable,
Inter variable — ~144 Ko cumulés, poids documenté dans src/vendor/NOTICE.md).

⚠️ Maquette avec données factices (src/galerie/mock-photos/) : pas encore
câblée à Supabase, il manque une RPC/Edge Function publique de listing
(aucune fonction actuelle ne convient à un accès invité anonyme sans
admin_token). Route /galerie/<slug> ajoutée à deploy/nginx-photobooth.conf
et déployée sur photobooth.assistantaikev.eu.
2026-09-18 09:04:05 +02:00

8.1 KiB

Journal des décisions

Ce fichier consigne les décisions structurantes actées pour le projet, avec la date à laquelle elles ont été prises. Toute nouvelle décision structurante (schéma DB, auth, hébergement, etc.) doit être ajoutée ici après validation par Kévin.

2026-09-18

  • Galerie invité (revirement) : les invités peuvent désormais voir toutes les photos de l'événement (pas juste envoyer la leur), dans le cadre de la nouvelle DA "Polaroid Néon". Ça inverse la décision du cahier des charges initial ("Pas de galerie visible côté invité, confirmé : upload only"). Conséquence RGPD : le texte de mention légale (docs/rgpd.md + modale de bienvenue) doit indiquer que photo/prénom/ message sont visibles par les autres invités de l'événement, pas seulement mis à disposition de l'organisateur — mis à jour dans la foulée. Implémentation : backend (nouvelle RPC/Edge Function publique de listing + URLs signées pour les invités) pas encore fait à cette date, seul le rendu visuel est en cours.
  • Nouvelle direction artistique "Polaroid Néon" actée, voir .claude/skills/photobooth-da/SKILL.md pour le détail complet (palette, typographie, composant polaroid signature). Remplace les 3 passes DA précédentes (palette corail/prune/doré + Fraunces) — celles-ci restent en prod tant que la nouvelle direction n'est pas implémentée écran par écran.
  • Stack confirmée inchangée : vanilla JS/HTML/CSS, pas de framework (React proposé dans un brief externe, décliné — mandat CLAUDE.md déjà explicite sur ce point, aucune décision contraire prise).

2026-09-16 (récap fin de journée)

Produit passé de "code écrit, rien de déployé" à réellement en ligne et testé : https://photobooth.assistantaikev.eu (VPS Hostinger, nginx + Traefik), backend sur le projet Supabase définitif kevin-lecou-hub.

  • Bugs réels trouvés et corrigés en cours de route (tous via tests en conditions réelles, pas en théorie) :
    • MIME type .mjs mal servi par nginx (bloquait tout le JS qui importe un module vendorisé — upload invité ET générateur QR étaient cassés).
    • Chemins relatifs (style.css, config.js, gallery.js) cassés sur les URLs réécrites /e/<slug> et /admin/<slug> — passage en chemins absolus partout.
    • Bug de cascade CSS présent depuis le tout premier commit : display: flex déclaré en dur sur .upload-form/.welcome-modal empêchait hidden (JS) de masquer quoi que ce soit visuellement — le formulaire est resté affiché en permanence, superposé aux autres états, sans que personne ne s'en rende compte avant un test réel.
    • Faille d'abus sur insert_public_photo (spam de lignes sans upload réel) — corrigée, vérification d'existence du fichier Storage ajoutée.
  • Nouvelle fonctionnalité : limite de photos par invité par événement (max_photos_per_guest), appliquée côté serveur via un guest_id anonyme (localStorage) — pas une identité vérifiée, contournable, mais fait respecter la vraie limite côté base.
  • RGPD : mention légale déplacée d'un bloc permanent vers une modale de bienvenue personnalisée (nom de l'événement) au premier passage par événement — texte légal inchangé, juste la présentation.
  • Direction artistique : 3 passes (palette sobre → palette punchy corail/prune/doré/Fraunces → mode sombre + finition animations). Statut au 2026-09-16 soir : jugée "pas mal, vraiment fonctionnel" par Kévin, mais couleurs/DA pas encore validées définitivement — Kévin prévoit un retour détaillé à l'agent direction-artistique lors d'une prochaine session.
  • Reste ouvert : activation du workflow n8n de purge Storage (credentials à créer côté Kévin), documentation de création d'un événement (encore manuel en SQL), remote Git à définir.

2026-09-15

  • Expiration des données : suppression à J+7 à partir de la date de l'événement (date_evenement), et non à partir de la date de création de l'événement dans le système.
  • Sécurité admin (V1) : accès à la galerie admin via un token secret dans l'URL (admin_token), pas de système de login/mot de passe. Réévaluer ce choix avant V2/V3 si le nombre de clients augmente.
  • Suppression des données : effective à J+7 dans tous les cas, y compris si l'organisateur a déjà téléchargé le ZIP d'export des photos.
  • Hébergement : utilisation du VPS existant de Kévin (148.230.114.175), pas de nouvel hébergement dédié pour l'instant.

2026-09-16

  • Compression image côté client : utilisation de la lib browser-image-compression, plutôt qu'une implémentation maison via Canvas API. Doit gérer l'orientation EXIF et les formats HEIC (iPhone).

2026-09-15 (bis)

  • Préfixage des tables : le projet Supabase de photobooth-qr sera mutualisé avec les autres projets de Kévin (KOMI, KAZA...). Tables préfixées pq_ (pq_events, pq_photos), conformément à la convention du CLAUDE.md global. Les fonctions Postgres exposées au front (get_public_event, event_accepts_uploads) restent sans préfixe : ce sont des points de contrat public, pas des tables internes.
  • Bucket Supabase Storage event-photos : bucket privé (pas de lecture publique). Convention de chemin : {event_id}/{uuid}.{ext}. Consultation admin exclusivement via URLs signées générées par l'Edge Function service_role. Aucune policy SELECT/UPDATE/DELETE publique sur storage.objects. Limité à file_size_limit = 6 Mo et allowed_mime_types = image/jpeg (aligné sur la sortie de compression du front, qui force tout en JPEG y compris les HEIC convertis).
  • pq_photos.url_storage : contrainte CHECK garantissant que le chemin commence par event_id/, pour empêcher qu'une ligne de l'event A pointe vers un fichier de l'event B (isolation multi-tenant), trouvé lors de la relecture sécurité du 2026-09-15.
  • get_public_event : renvoie l'événement même si son statut n'est pas actif (expiré/archivé), pour permettre au front d'afficher un message adapté. Risque jugé faible : les slugs sont partagés via QR code, donc non secrets par nature.

2026-09-16 (quater)

  • Limite de photos par invité : nouvelle colonne photobooth.events.max_photos_per_guest (NULL = illimité par défaut), réglable uniquement en SQL à la création de l'event pour l'instant (pas d'UI admin dédiée). Appliquée via un guest_id anonyme généré et persisté côté client (localStorage) — pas une identité vérifiée, contournable en changeant d'appareil ou en vidant le storage. Fait respecter côté serveur (RPC insert_public_photo, source de vérité) et côté client de façon proactive (évite un envoi pour se le faire refuser à la dernière étape).

2026-09-16 (ter)

  • Domaine de production (V1) : photobooth.assistantaikev.eu, sous-domaine du domaine déjà utilisé pour n8n. Décision explicitement temporaire : à déplacer vers un domaine dédié en V2/V3 si le produit est vendu sous sa propre marque. Front servi par un container nginx sur le VPS existant (Traefik/Let's Encrypt déjà en place pour n8n), config dans deploy/. APP_BASE_URL configurée comme secret sur les 2 Edge Functions pour le CORS. Déploiement testé en conditions réelles le 2026-09-16 (upload + galerie admin fonctionnels depuis le domaine public).

2026-09-16 (bis)

  • Déclenchement de la purge Storage à J+7 : option n8n retenue (plutôt que pg_cron+pg_net). Un workflow n8n planifié quotidien appelle l'Edge Function expire-events avec la service_role key (Credentials Store n8n), avec notification Telegram en cas d'échec. Cohérent avec la stack n8n déjà utilisée pour KOMI/KAZA, et le VPS n8n existant sert de point d'orchestration commun. Conception du workflow : n8n/workflows/purge-storage-j7.json (JSON importable, non testé sur l'instance n8n réelle, credentials à relier manuellement avant activation).