Aller au contenu principal

Architecture Sessions, Collaborateurs & Moodboards

Document de référence pour comprendre le modèle centré sessions avec collaborateurs et moodboards.

Changelog docs

  • 2026-02-18: Suppression du concept "Projet". Les collaborateurs et moodboards sont rattachés directement aux sessions. Simplification des rôles (VIEWER/EDITOR/ADMIN).
  • 2026-02-18: Mise à jour moodboards - images uniquement, upload multiple (max 10), niveau session.
  • 2026-02-18: Simplification moodboard - un seul moodboard par session (auto-créé), routes sans :moodboardId pour les items.
  • 2026-02-19: Migration des droits client moodboard vers client_access_level (NONE / READ / READ_WRITE). Suppression de is_shared_with_client et client_can_edit.
  • 2026-02-19: Reorder drag & drop + suppression exposés côté client authentifié (/client-accounts/me/...) quand le moodboard est en READ_WRITE.
  • 2026-02-19: Reorder moodboard en UI optimiste (user/client/portal) + synchro temps réel via websocket moodboard:updated.

1. Vision

1.1 Modèle centré Sessions

  • La session est l'unité centrale de travail.
  • Les objets métier (collaborateurs, moodboards, documents, paiements, workflows, fichiers) se rattachent à la session.
  • Il n'y a pas de couche "projet" intermédiaire. Les photographes et prestataires pensent en "séances", pas en "projets".

2. Principes fonctionnels

  1. Session d'abord : chaque prestation est une session avec son contexte (date, lieu, type, contact, statut).
  2. Collaboration directe : les collaborateurs sont invités au niveau de la session.
  3. Moodboard par session : chaque session a un moodboard unique (auto-créé) avec des images.
  4. Documents liés : devis, factures, contrats sont rattachés à la session via le contact.

3. Entités et relations

3.1 Entités

  • sessions : Sessions photographiques (mariages, séances, événements)
  • session_collaborators : Collaborateurs invités sur une session
  • session_moodboards : Moodboards de session (partageables avec le client)
  • session_moodboard_items : Éléments de moodboard (images uniquement)
  • session_contacts : Relations sessions ↔ contacts
  • session_tags : Tags associés aux sessions
  • session_providers : Prestataires associés (traiteurs, DJ, etc.)
  • session_checklists / session_checklist_items : Checklists de session
  • session_files : Fichiers associés à une session
  • session_planning_items : Items de planification (roadmap)
  • quotes / contracts / invoices / payments : Documents financiers liés au contact de la session

3.2 Relations

  • session 1 -> N session_collaborators
  • session 1 -> 1 session_moodboard (fonctionnellement unique par owner/session)
  • session_moodboard 1 -> N session_moodboard_items
  • session 1 -> N quotes/contracts/invoices (via contact)
  • session 1 -> N session_files
  • session 1 -> N session_providers

4. Collaborateurs

4.1 Identification

Chaque collaborateur est identifié par exactement un des trois moyens :

  • collaborator_user_id : un utilisateur Aaperture existant
  • invited_email : une adresse email (invitation en attente)
  • linked_provider_id : un prestataire lié (user_providers)

4.2 Rôles simplifiés

RôleDescription
VIEWERLecture seule sur la session
EDITORLecture + modification
ADMINAccès complet (comme le owner)

4.3 Flux d'invitation

  1. Owner invite un collaborateur sur une session.
  2. Statut initial : PENDING.
  3. Collaborateur accepte (ACCEPTED) ou refuse (DECLINED).
  4. Possibilité de renvoyer l'invitation.

4.4 API

  • GET /sessions/:sessionId/collaborators
  • POST /sessions/:sessionId/collaborators
  • PATCH /sessions/:sessionId/collaborators/:id
  • DELETE /sessions/:sessionId/collaborators/:id
  • POST /sessions/:sessionId/collaborators/:id/resend-invite

5. Moodboard

5.1 Principes

  • Chaque session a un seul moodboard (auto-créé à l'ajout du premier item).
  • Le moodboard contient uniquement des images (upload multiple, max 10 à la fois).
  • Le partage client est piloté par client_access_level :
    • NONE : non partagé
    • READ : lecture seule
    • READ_WRITE : lecture + upload + suppression + reorder côté client
  • Les items supportent une catégorie optionnelle pour organiser les images.
  • Le frontend affiche directement la grille d'images, sans liste intermédiaire de moodboards.
  • Le reorder est en drag & drop avec optimistic update (pas de retour visuel en arrière pendant la persistance).
  • Les changements moodboard déclenchent un event websocket moodboard:updated pour invalider/refetch côté user et client.

5.2 API photographe

  • GET /sessions/:sessionId/moodboards — retourne le moodboard unique (objet) ou null
  • PUT /sessions/:sessionId/moodboards — créer/mettre à jour les paramètres du moodboard (title, description, client_access_level)
  • DELETE /sessions/:sessionId/moodboards — supprimer le moodboard et tous ses items
  • POST /sessions/:sessionId/moodboards/upload-image — upload une image
  • POST /sessions/:sessionId/moodboards/upload-images — upload multiple (max 10)
  • POST /sessions/:sessionId/moodboards/items — ajouter un item (auto-crée le moodboard)
  • PATCH /sessions/:sessionId/moodboards/items/:itemId — modifier un item
  • DELETE /sessions/:sessionId/moodboards/items/:itemId — supprimer un item

5.3 API client

5.3.1 Lien sécurisé (token client-access)

  • GET /client-access/sessions/:sessionId/moodboards — retourne le moodboard partagé (objet) ou null
  • POST /client-access/sessions/:sessionId/moodboards/items — ajouter un item
  • PATCH /client-access/sessions/:sessionId/moodboards/items/:itemId — modifier un item
  • DELETE /client-access/sessions/:sessionId/moodboards/items/:itemId — supprimer un item
  • POST /client-access/sessions/:sessionId/moodboards/upload-image — upload une image
  • POST /client-access/sessions/:sessionId/moodboards/upload-images — upload multiple (max 10)

5.3.2 Portail client authentifié (client-accounts)

  • GET /client-accounts/me/sessions/:sessionId/moodboard — retourne le moodboard partagé (objet) ou null
  • PATCH /client-accounts/me/sessions/:sessionId/moodboard/items/:itemId — update item (reorder/catégorie/image), autorisé en READ_WRITE
  • DELETE /client-accounts/me/sessions/:sessionId/moodboard/items/:itemId — suppression item, autorisée en READ_WRITE

6. Vue session (onglets)

La page de détail d'une session comporte les onglets suivants :

  1. Vue d'ensemble : résumé, statut, contact, prochaines actions
  2. Préparation : checklist, tâches, workflow
  3. Logistique : planning, roadmap, météo
  4. Documents : fichiers liés
  5. Finances : devis, factures, paiements
  6. Suivi client : contact, relances, historique
  7. Équipe : collaborateurs invités + prestataires
  8. Moodboard : moodboard et images

7. Portail client

7.1 Routes

  • /portal/sessions — liste des séances du client
  • /portal/sessions/:sessionId — détail d'une séance
  • /portal/documents — documents (devis, factures, contrats)
  • /portal/galleries — galeries photos
  • /portal/messages — messagerie
  • /portal/files — fichiers partagés

7.2 API client

  • GET /client-accounts/me/sessions — liste des sessions du client
  • GET /client-accounts/me/sessions/:sessionId — détail d'une session
  • GET /client-accounts/me/sessions/:sessionId/moodboard — moodboard de session partagé
  • PATCH /client-accounts/me/sessions/:sessionId/moodboard/items/:itemId — mise à jour item (si READ_WRITE)
  • DELETE /client-accounts/me/sessions/:sessionId/moodboard/items/:itemId — suppression item (si READ_WRITE)
  • GET /client-accounts/me/documents — documents du client
  • GET /client-accounts/me/photographers — photographes liés

8. Tables DB

session_collaborators

CREATE TABLE session_collaborators (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
session_id UUID NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
owner_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
collaborator_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
invited_email VARCHAR(255),
linked_provider_id UUID REFERENCES user_providers(id) ON DELETE SET NULL,
role VARCHAR(50) NOT NULL DEFAULT 'VIEWER'
CHECK (role IN ('VIEWER', 'EDITOR', 'ADMIN')),
invitation_status VARCHAR(50) NOT NULL DEFAULT 'PENDING'
CHECK (invitation_status IN ('PENDING', 'ACCEPTED', 'DECLINED')),
invited_by_user_id UUID REFERENCES users(id),
invited_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
accepted_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT exactly_one_identifier CHECK (
(collaborator_user_id IS NOT NULL)::int +
(invited_email IS NOT NULL)::int +
(linked_provider_id IS NOT NULL)::int = 1
)
);

session_moodboards + session_moodboard_items

CREATE TABLE session_moodboards (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
session_id UUID NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
owner_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
title VARCHAR(255) NOT NULL DEFAULT 'Moodboard',
description TEXT,
client_access_level VARCHAR(20) NOT NULL DEFAULT 'NONE'
CHECK (client_access_level IN ('NONE', 'READ', 'READ_WRITE')),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE session_moodboard_items (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
moodboard_id UUID NOT NULL REFERENCES session_moodboards(id) ON DELETE CASCADE,
created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
item_type VARCHAR(20) NOT NULL CHECK (item_type IN ('IMAGE', 'LINK', 'NOTE')),
image_url TEXT,
external_url TEXT,
note TEXT,
category VARCHAR(100),
display_order INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);