Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014akYEuf44fM6EiUvrmoBzS
3.2 KiB
3.2 KiB
Modèle de données
Deux tables Supabase (Postgres). Pas de table users côté invité : les
invités n'ont pas de compte. L'admin n'a pas de compte non plus en V1 — son
accès repose sur un token secret (voir decisions.md).
Table events
| Colonne | Type | Description |
|---|---|---|
id |
uuid (PK, défaut gen_random_uuid()) |
Identifiant unique de l'événement |
slug |
text, unique |
Identifiant lisible utilisé dans l'URL publique d'upload (/e/<slug>) |
nom |
text |
Nom de l'événement (ex : "Mariage Julie & Marc") |
date_evenement |
date |
Date de l'événement, sert de référence pour l'expiration |
created_at |
timestamptz, défaut now() |
Date de création de l'événement dans le système |
expire_at |
timestamptz |
Date/heure d'expiration calculée (date_evenement + 7 jours) |
statut |
text |
Statut de l'événement : actif, expire, archive (à affiner) |
admin_token |
text, unique |
Token secret donnant accès à la galerie admin |
client_nom |
text, nullable |
Nom du client (utile en V2/V3 quand le service est vendu) |
facture_montant |
numeric, nullable |
Montant facturé au client (utile en V2/V3) |
Table photos
| Colonne | Type | Description |
|---|---|---|
id |
uuid (PK, défaut gen_random_uuid()) |
Identifiant unique de la photo |
event_id |
uuid (FK → events.id, on delete cascade) |
Événement associé |
url_storage |
text |
Chemin/URL du fichier dans Supabase Storage |
nom_invite |
text, nullable |
Nom saisi par l'invité (optionnel) |
message |
text, nullable |
Message laissé par l'invité (optionnel) |
uploaded_at |
timestamptz, défaut now() |
Date d'upload |
Row Level Security (RLS)
RLS activé sur les deux tables. Règles à valider avec Kévin avant implémentation définitive, principe retenu pour l'instant :
events
- Lecture publique : non autorisée directement (pas de
SELECTpublic surevents). L'accès public à l'upload passe par une vérification côté fonction/API sur lesluget lestatut = 'actif', sans exposer toute la ligne (notamment pasadmin_token). - Lecture admin : autorisée si la requête présente l'
admin_tokencorrespondant (comparaison côté fonction Postgres/Edge Function plutôt que policy RLS naïve, pour éviter d'exposer le token dans une clauseWHEREcôté client). - Écriture : réservée à l'admin/back-office (pas de policy publique
d'insertion/update sur
events).
photos
- Insertion (upload) anonyme autorisée si et seulement si :
- l'
event_idcorrespond à un événement dont lestatut = 'actif', et - la date courante est antérieure à
expire_at.
- l'
- Lecture réservée à l'admin (accès via
admin_tokenvalidé), jamais de lecture publique de la liste des photos d'un événement. - Update / delete : pas d'update par les invités ; delete réservé au job d'expiration automatique (ou à l'admin, à confirmer).
⚠️ Le détail exact des policies RLS (SQL) sera écrit dans
supabase/migrations/au moment de l'implémentation, et validé avec Kévin avant application — cf. règle "décision structurante" dansCLAUDE.md.