Aller au contenu

Référence : Modèle de compte pro et de structure

Objectif

Poser un document de référence évolutif sur le modèle cible V1 des comptes pro, des structures, des events pro et des règles d'autorisation associées.

Ce document couvre :

  • l'existant confirmé dans le repo ;
  • les principes produit déjà arbitrés ;
  • le modèle canonique cible ;
  • la matrice V1 des actions et des contrôles ;
  • les points explicitement laissés pour plus tard.

Ce document n'est pas une spécification d'implémentation finale. Il sert de support de décision et de suivi avant implémentation.

Références connexes :

État actuel confirmé

Comptes et profils

  • Un User est le compte technique d'authentification.
  • Un User pointe vers une Person.
  • La création de compte crée aujourd'hui un couple User + Person.
  • Les rôles sont stockés en JSON dans users.roles.
  • Le rôle créé par défaut à la création du compte est ROLE_USER.
  • Une grande partie du produit suppose qu'un utilisateur authentifié possède une Person.

Person

  • Person est le profil métier principal.
  • Le profil sert aux feeds people, aux conversations, aux events, à la solidarité et aux notifications.
  • Le cycle de vie du profil repose sur la complétude et la modération.
  • L'existant ne distingue pas encore de type de compte individual vs pro.

Structures

  • Une Structure existe déjà comme entité catalogue :
  • type ;
  • nom ;
  • description ;
  • coordonnées ;
  • avatar ;
  • activités legacy via sports ;
  • installations / équipements.
  • Une structure peut donc déjà exister sans propriétaire, sans plan et sans compte pro.
  • Le schéma actuel ne porte pas encore de lien explicite entre une structure et les personnes autorisées à la gérer.

Events / moovs

  • Un event est aujourd'hui toujours créé par une Person via created_by_id.
  • Le modèle ne porte pas encore de rattachement métier d'un event à une structure.
  • Le lieu de l'event est aujourd'hui porté directement sur l'event via address et city_id.
  • Le produit ne distingue pas encore explicitement :
  • un event particulier ;
  • un event pro.

Solidarité

  • Le domaine solidarité dispose déjà d'un vrai moteur de capabilities et de quotas effectifs pour les comptes individual.
  • Il existe déjà une notion de EventHelper pour un helper externe non participant, limité à la sphère solidarité.
  • La conversation générale d'un event reste aujourd'hui pilotée par la participation, pas par EventHelper.

Principes transverses validés

On raisonne en comptes, pas en personne physique

  • Le produit raisonne sur des comptes distincts.
  • Une même personne physique peut avoir :
  • un compte individual ;
  • un compte pro.
  • Ces deux comptes restent séparés, avec deux emails distincts.

Type de compte

  • Il faut distinguer deux types de compte :
  • individual ;
  • pro.
  • Le choix du type se fait à la création du compte.
  • Le type est immuable en V1.
  • Le type de compte est une règle métier d'acteur, pas une règle d'authentification pure.
  • Le type doit donc être porté par Person plutôt que par User.

Rôles globaux

  • Tous les comptes authentifiés conservent ROLE_USER.
  • Les comptes pro portent en plus ROLE_PRO.
  • Les rôles globaux ne suffisent pas, à eux seuls, pour l'autorisation métier.

Compte pro

  • Un compte pro reste une Person.
  • Un compte pro peut exister sans structure au départ.
  • Un compte pro apparaît dans les feeds people.
  • Un compte pro voit les feeds people et events.
  • Pour vivre les usages de type "moover particulier", une même personne doit utiliser son compte individual.

Structure

  • Une Structure est d'abord une entité réelle référencée dans le produit.
  • Une structure peut exister sans :
  • compte pro rattaché ;
  • propriétaire ;
  • plan.
  • Les couches de gestion et de monétisation sont des surcouches optionnelles de cette structure catalogue.

Event pro

  • Un event pro est toujours créé techniquement par un compte.
  • Il est en revanche toujours organisé, sur le plan métier, au nom d'une structure.
  • Donc :
  • created_by_person_id reste la source de vérité d'audit ;
  • organizer_structure_id porte l'organisateur métier.
  • Un compte pro ne crée jamais un event pro "hors structure".

Lieu de l'event

  • Le lieu de l'event doit rester un concept distinct de l'organisateur.
  • address et city_id restent la source de vérité du lieu.
  • Une structure peut être référencée comme lieu, mais ce lien reste descriptif en V1 et ne porte aucun droit.

Modèle canonique cible

1. Person et compte

Ajouter un type de compte stable, par exemple :

  • people.account_type

Valeurs cibles :

  • individual ;
  • pro.

Effets :

  • discrimination métier explicite des parcours ;
  • pas de conversion individual -> pro en V1 ;
  • projection éventuelle dans les claims de session pour éviter des rechargements.

2. Structure

La structure reste l'entité centrale côté pro.

Elle peut exister selon plusieurs états produit :

  • catalogue
  • visible / référençable ;
  • pas de gestionnaire ;
  • pas de plan ;
  • gérée
  • revendiquée ou créée par un pro ;
  • possède un propriétaire et éventuellement des délégués ;
  • gérée + plan
  • dispose d'une affectation de plan ;
  • débloque des capabilities et quotas pro.

Important :

  • une structure n'a pas besoin d'être gérée pour exister ;
  • une structure n'a pas besoin d'avoir de plan pour exister.

3. StructureMembership

StructureMembership est la relation durable entre un compte pro et une structure gérée.

Responsabilités :

  • dire qu'une Person pro est rattachée à une structure ;
  • porter les permissions de gestion ;
  • distinguer propriétaire et délégués ;
  • tracer qui a accordé les droits.

Propriétés cibles :

  • structure_id ;
  • person_id ;
  • granted_by_person_id ;
  • is_owner ;
  • status ;
  • permissions explicites ou masque équivalent ;
  • timestamps.

Règles :

  • propriétaire unique par structure ;
  • seul le propriétaire gère les accès en V1 ;
  • seuls les comptes pro peuvent recevoir un StructureMembership.

4. StructureAdherent

StructureAdherent est la relation durable entre un compte individual et une structure.

Responsabilités :

  • porter l'adhésion métier ;
  • servir aux badges ;
  • servir aux events members_only ;
  • servir au comptage des adhérents ;
  • servir aux invitations d'adhérents.

Règles :

  • individual only ;
  • plusieurs structures possibles pour une même personne ;
  • aucun droit d'administration ne dérive de cette relation ;
  • statut V1 simple :
  • active ;
  • inactive.

4 bis. StructureAdherentInvitation

StructureAdherentInvitation est l'objet métier dédié permettant à une structure d'inviter une adresse email à devenir adhérent sans passer par la waitlist globale.

Responsabilités :

  • porter une invitation structure-level, email-only ;
  • permettre soit la création d'un compte individual, soit l'acceptation sur un compte individual existant ;
  • tracer l'émetteur, le destinataire résolu éventuel, l'expiration et l'issue ;
  • servir de source d'onboarding et de source d'adhésion.

Règles V1 :

  • capability requise : adherents.manage ;
  • capability complémentaire requise : users.invite_without_waitlist ;
  • quota requis : users.invite_without_waitlist_per_subscription_month ;
  • permission membership requise : manage_structure_adherents ;
  • l'invitation sans waitlist reste une surcapacité de la gestion des adhérents, pas une feature autonome ;
  • quota consommé à l'envoi ;
  • pas de remboursement ;
  • pas de révocation structure-side en V1 ;
  • statuts V1 :
  • sent ;
  • accepted ;
  • declined ;
  • expired ;
  • unicité d'une invitation active par couple structure_id + normalized_email ;
  • une invitation declined bloque le ré-envoi self-serve en V1 ;
  • à l'acceptation :
  • le compte cible est toujours individual ;
  • l'adhésion StructureAdherent est créée ou réactivée en active ;
  • la source d'onboarding et la source d'adhésion sont tracées ;
  • si l'email existe déjà uniquement sur un compte pro, le flow est refusé en V1.

5. StructurePlanAssignment

Les capabilities et quotas pro doivent être lus au niveau de la structure.

La structure doit donc disposer d'une affectation de plan explicite, par exemple :

  • StructurePlanAssignment

Responsabilités :

  • donner à la structure son plan effectif ;
  • porter le cycle mensuel de souscription de la structure ;
  • servir de base aux capabilities et quotas effectifs de la structure.

Important :

  • on ne lit pas directement le plan du compte propriétaire au moment de l'action ;
  • le compte propriétaire peut rester la source commerciale ;
  • mais l'exécution produit lit la structure.

En V1 :

  • une structure catalogue non gérée peut rester sans plan ;
  • une structure gérée qui veut utiliser des features pro avancées doit avoir une affectation de plan.

6. Event

Le modèle cible de l'event doit distinguer :

  • qui crée ;
  • qui organise ;
  • où cela a lieu.

Champs cibles :

  • created_by_person_id obligatoire ;
  • organizer_structure_id nullable ;
  • venue_structure_id nullable ;
  • audience_scope pour les events pro.

Sémantique :

  • organizer_structure_id = NULL => event perso ;
  • organizer_structure_id != NULL => event pro ;
  • venue_structure_id est purement descriptif en V1.

7. EventParticipant

EventParticipant porte la participation réelle à l'event.

Responsabilités :

  • prise de place ;
  • waitlist ;
  • compteurs ;
  • conversation générale.

8. EventStaffMember

EventStaffMember porte le rattachement opérationnel à un event.

Responsabilités :

  • relier un compte à un event avec un titre libre ;
  • exister sans participation ;
  • afficher l'équipe de l'event ;
  • ouvrir un accès opérationnel de lecture.

Règles :

  • pro ou individual ;
  • pas de droits de gestion ;
  • pas de droits de solidarité ;
  • pas de place participant.

9. EventHelper

EventHelper reste réservé à la solidarité.

Règles :

  • individual only ;
  • pas participant ;
  • pas staff ;
  • pas d'accès à la conversation générale via ce seul statut.

10. EventInvitation

EventInvitation sert pour les events déjà créés.

Responsabilités :

  • ouvrir l'accès à un event si besoin ;
  • notifier / cibler une personne déjà éligible.

Deux effets V1 :

  • access ;
  • notify.

11. EventProposal

EventProposal garde sa nature actuelle :

  • objet amont ;
  • ne crée pas immédiatement un event ;
  • peut se convertir ensuite en event.

Extension cible côté pro :

  • proposal créée au nom d'une structure ;
  • audience_scope cohérent avec la structure ;
  • choix explicite du créateur sur sa participation lors de la conversion ;
  • à la conversion :
  • les personnes yes sur le créneau retenu deviennent directement participantes ;
  • le créateur suit le choix posé au niveau de la proposal.

Permissions et capabilities

Permissions de structure

Les permissions V1 portées par StructureMembership sont :

  • manage_structure_profile ;
  • manage_structure_media ;
  • manage_structure_activities ;
  • manage_structure_facilities ;
  • create_structure_events ;
  • manage_structure_adherents.

Non délégable en V1 :

  • gestion des accès de la structure.

Capabilities de structure

Les capabilities effectives de la structure sont distinctes des permissions.

Catalogue V1 cible :

  • events.pro.create ;
  • event_proposals.pro.create ;
  • events.audience.advanced ;
  • adherents.manage ;
  • users.invite_without_waitlist ;
  • event_solidarity.configure ;
  • event_solidarity.external_helpers.allow.

Quotas de structure

Catalogue V1 cible :

  • events.pro.create_per_subscription_month ;
  • event_proposals.pro.create_per_subscription_month ;
  • users.invite_without_waitlist_per_subscription_month ;
  • events.pro.max_seats_per_event ;
  • event_proposals.pro.max_seats_per_proposal ;
  • event_proposals.pro.max_invitees_per_proposal.

Principe :

  • la V1 retient des quotas mensuels de consommation ;
  • la V1 retient des quotas de gabarit ;
  • la V1 ne retient pas de quotas future_*.

Règles produit validées

Feeds et visibilité

  • individual apparaît dans les feeds people ;
  • pro apparaît aussi dans les feeds people ;
  • individual voit les feeds people et events ;
  • pro voit aussi les feeds people et events.

Participation aux events

  • individual peut s'inscrire à un event, sous réserve des règles métier et des capabilities / quotas individual ;
  • pro n'utilise pas son compte pro pour participer comme moover standard ;
  • si une même personne veut participer comme particulier, elle utilise son compte individual.

Adhérents

  • un individual peut être adhérent de plusieurs structures ;
  • un pro n'est pas adhérent via ce mécanisme ;
  • une structure peut afficher son nombre d'adhérents actifs ;
  • l'adhésion n'est pas publique par défaut en V1 ;
  • l'adhésion sert dès la V1 :
  • au badge ;
  • au ciblage d'events ;
  • aux invitations d'adhérents.
  • une structure peut inviter une adresse email à devenir adhérent sans passer par la waitlist globale ;
  • cette invitation est structure-level et email-only ;
  • l'acceptation est explicite :
  • soit via création d'un compte individual ;
  • soit via acceptation sur un compte individual existant ;
  • l'acceptation crée ou réactive automatiquement une adhésion active ;
  • si l'email était déjà présent dans la waitlist, l'entrée sort proprement de la waitlist ;
  • après cette sortie, les flows waitlist admin et les anciens tokens waitlist ne doivent plus rester exploitables.

Event pro

  • un compte pro crée toujours un event pro au nom d'une structure ;
  • s'il a plusieurs structures, il choisit organizer_structure_id ;
  • un event pro peut être public ou restricted ;
  • un event pro peut être créé directement ou via EventProposal.

Event pro et créateur

  • si le créateur pro ne participe pas :
  • il est automatiquement ajouté à EventStaffMember ;
  • s'il participe :
  • il devient participant normal ;
  • il n'est pas automatiquement EventStaffMember, sauf rôle explicite.

EventStaffMember

  • un EventStaffMember voit :
  • le détail complet de l'event ;
  • la liste des participants ;
  • la conversation générale ;
  • un EventStaffMember n'obtient pas :
  • de droit de gestion ;
  • de droit de participation automatique ;
  • d'accès à la solidarité.

Gestionnaires de structure et conversation d'event

  • un gestionnaire de structure disposant de la bonne permission peut voir le détail complet d'un event pro, même s'il n'est ni participant ni EventStaffMember ;
  • en revanche, ce gestionnaire n'accède pas à la conversation générale s'il n'est ni participant ni EventStaffMember.

Solidarité

  • la solidarité reste réservée aux comptes individual ;
  • un compte pro n'utilise pas son compte pro pour les parcours de solidarité ;
  • EventHelper reste une relation de solidarité, distincte de EventStaffMember.

Lieu de l'event

  • address et city_id restent la source de vérité du lieu ;
  • venue_structure_id est un lien optionnel vers une structure connue ;
  • un event peut avoir lieu dans une autre structure que son organisateur ;
  • en V1, aucun mécanisme d'autorisation inter-structures n'est géré ;
  • venue_structure_id n'ouvre donc aucun droit et ne donne aucun pouvoir à la structure hôte.

Audience des events pro

Scopes V1

  • everyone ;
  • invite_only ;
  • members_only ;
  • members_and_invitees.

Règles d'accès

  • everyone
  • accès complet pour tous les individual ;
  • invite_only
  • accès complet si invitation access ;
  • signal sinon ;
  • members_only
  • accès complet si adhésion active ;
  • signal sinon ;
  • members_and_invitees
  • accès complet si adhésion active ou invitation access ;
  • signal sinon.

Règles de visibilité

Le feed garde le modèle actuel :

  • carte event complète si l'utilisateur a l'accès complet ;
  • carte signal sinon.

Le détail complet reste refusé sans accès complet.

Invitations

Règles V1 :

  • invite_only => invitations access ;
  • members_only => invitations notify ;
  • members_and_invitees
  • access pour les non-adhérents ;
  • notify possible pour les adhérents ciblés ;
  • les invitations d'event ciblent uniquement des comptes individual ;
  • l'invitation n'inscrit jamais automatiquement.

Matrice finale V1

Compte

  • créer un compte individual
  • choix à la création du compte ;
  • créer un compte pro
  • choix à la création du compte ;
  • convertir un compte
  • non en V1.

Structure

  • une structure peut exister sans propriétaire
  • oui ;
  • une structure peut exister sans plan
  • oui ;
  • une structure peut être revendiquée
  • oui ;
  • une structure gérée peut avoir plusieurs pros
  • oui ;
  • propriétaire unique
  • oui.

Membership et adhérents

  • StructureMembership
  • pro only ;
  • permissions de gestion ;
  • StructureAdherent
  • individual only ;
  • appartenance métier sans admin.
  • StructureAdherentInvitation
  • invitation structure-level, email-only ;
  • quota à l'envoi ;
  • acceptation explicite ;
  • auto-adhésion active ;
  • une invitation active par email + structure.

Event perso

  • organisateur métier
  • la Person ;
  • organizer_structure_id
  • NULL.

Event pro

  • organisateur métier
  • la Structure ;
  • organizer_structure_id
  • obligatoire sur le plan métier ;
  • créateur technique
  • toujours une Person.

Event et lieu

  • venue_structure_id
  • optionnel ;
  • peut pointer vers une structure non gérée
  • oui ;
  • peut pointer vers une autre structure gérée
  • oui, sans autorisation inter-structures en V1 ;
  • le lieu donne des droits
  • non.

Staff / participant / helper

  • EventStaffMember
  • rôle opérationnel, sans admin ;
  • EventParticipant
  • prise de place ;
  • EventHelper
  • solidarité uniquement.

Sujets explicitement laissés pour plus tard

  • mécanisme d'autorisation inter-structures pour l'usage d'une structure hôte ;
  • event staff avec permissions au niveau event ;
  • modération / validation par la structure hôte d'un event référencé comme lieu ;
  • quotas d'adhérents actifs ;
  • révocation structure-side d'une invitation adhérent ;
  • quotas future_* ;
  • overrides plus fins des capabilities / quotas au niveau structure ;
  • support d'une couche de billing au-dessus de plusieurs structures si le produit en a besoin plus tard.

Trajectoire d'implémentation et état d'avancement

La trajectoire ci-dessous a servi de feuille de route. À date, le socle V1 prévu dans ce document est largement implémenté.

Étape 1 — implémentée

  • account_type est porté par Person ;
  • le choix individual / pro est branché à la création du compte ;
  • le type de compte est exposé dans les DTO utiles.

Étape 2 — implémentée

  • StructureMembership existe ;
  • les permissions de structure existent ;
  • les flows de gouvernance structure sont branchés sur ce modèle.

Étape 3 — implémentée

  • StructureAdherent existe ;
  • les statuts d'adhésion V1 sont branchés ;
  • les events pro members_only et members_and_invitees s'appuient sur cette relation.

Étape 4 — implémentée

  • l'affectation de plan à une structure existe ;
  • les capabilities et quotas pro sont lus au niveau structure ;
  • les contrôles effectifs sont branchés dans les flows pro.

Étape 5 — implémentée

  • organizer_structure_id est branché sur l'event ;
  • la création d'events pro au nom d'une structure est supportée ;
  • audience_scope est supporté ;
  • EventStaffMember est supporté.

Étape 6 — implémentée

  • venue_structure_id est branché comme enrichissement optionnel ;
  • address et city_id restent la source de vérité du lieu ;
  • aucun droit n'est déduit du lieu en V1.

Étape 7 — implémentée

  • EventInvitation est supporté ;
  • les scopes d'audience et les règles de feed / détail sont branchés ;
  • les proposals pro sont alignées sur le modèle structure-backed ;
  • la conversion proposal -> event pro conserve ce cadre de gouvernance.

Étape 8 — implémentée

  • StructureAdherentInvitation est supporté comme objet métier dédié ;
  • le flow d'envoi batch structure-side est branché avec quota mensuel ;
  • les flows publics view / signup / decline et le flow authentifié accept sont exposés ;
  • l'acceptation crée ou réactive automatiquement une adhésion active ;
  • si l'email était dans la waitlist, l'entrée en sort proprement et les anciens flows waitlist ne restent pas exploitables.

Garde-fous

  • Ne pas faire porter toute la logique par ROLE_PRO seul.
  • Ne pas faire dépendre l'existence d'une structure d'un compte pro ou d'un plan.
  • Ne pas confondre organisateur et lieu.
  • Ne pas déduire de droits à partir de venue_structure_id.
  • Ne pas faire porter les permissions d'un event pro par EventStaffMember.
  • Garder created_by_person_id comme source de vérité d'audit.
  • Garder une implémentation incrémentale et rétro-compatible autant que possible.