Invitation (Invitation)
En une phrase : le sas d'entrée contrôlé de la plateforme — aucune personne ne devient active sans avoir cliqué un lien secret reçu par e-mail, qu'il lui ait été accordé (invitation) ou qu'elle l'ait demandé (auto-inscription voyageur).
Rôle métier
La plateforme n'a pas d'inscription libre pour les comptes métier : l'accès se donne. L'invitation matérialise ce don d'accès : elle relie un compte utilisateur provisionné (pending) à un lien secret envoyé par e-mail, dont l'acceptation active le compte (pose du mot de passe) et concrétise les appartenances préparées. Les voyageurs, eux, peuvent s'auto-inscrire : la même table sert alors de ticket d'activation prouvant la propriété de l'e-mail.
Quatre chemins créent des invitations, la consommation étant commune :
- Invitation directe par un super-admin — accorde n'importe quelle combinaison de casquettes : organisations + rôle, voyageur, super-admin. Une invitation doit accorder au moins quelque chose.
- Approbation d'une candidature d'organisation — quand une organisation passe
approved, son organisateur en attente reçoit sa toute première invitation, exactement une fois (les ré-approbations ne re-spamment jamais). - Invitation de membre par une organisation (
POST /organizations/:id/members) — un super-admin ou un manager de l'organisation invite par e-mail + langue + rôle. Un e-mail inconnu provisionne un compte-coquille (noms vides, complétés à l'acceptation) ; une personnependingest ré-invitée (token rafraîchi) ; une personne déjà active rejoint immédiatement, sans invitation. - Auto-inscription voyageur (
POST /auth/register) — ici l'invitation sert de ticket d'activation : personne n'a accordé l'accès (invited_bynull), le mot de passe est posé d'emblée, et le lien reçu active le compte viaPOST /auth/activate/{token}sans en redemander un.
La création d'organisation par un super-admin réutilise le même mécanisme pour un manager encore pending. L'émission du token est centralisée dans Invitation::issueFor().
Cycle de vie
Émise → (rafraîchie) → acceptée ou expirée (7 jours).
- Une seule invitation en attente par personne : ré-inviter quelqu'un rafraîchit son lien (l'ancien devient invalide) plutôt que d'empiler des invitations concurrentes.
- Acceptée (
accepted_at) — la personne a posé son mot de passe : compteactive, appartenances basculéesactive, l'invitation est consommée et ne peut pas resservir. Un compte-coquille (noms vides) doit aussi compléter son identité :first_name/last_namedeviennent obligatoires à l'acceptation ; un compte déjà nommé n'est jamais renommé par un token. - Expirée — le lien ne fonctionne plus ; il faut ré-inviter.
- Orpheline — retirer un membre encore
invitedde l'organisation ne révoque pas son invitation : l'accepter ensuite active un compte sans aucune appartenance (propriété assumée, partagée avec la création d'organisation).
Relations métier
| Relation | Sens métier |
|---|---|
→ Utilisateur (user_id) | Le compte que l'invitation provisionne / réclame |
→ Utilisateur (invited_by) | L'administrateur qui a donné l'accès (traçabilité de la décision) ; le lien peut disparaître, l'invitation reste |
| ⇒ Appartenances | Les rattachements invited préparés en amont, activés à l'acceptation |
Règles métier
- Le token est le secret : il circule uniquement dans l'e-mail, est stocké haché, et reste hors du journal d'audit. Les pages d'acceptation sont publiques — c'est le token qui authentifie.
- L'invitation est envoyée dans la langue de l'invité, choisie par l'invitant au moment de l'invitation.
- Pas d'auto-login à l'acceptation : la personne se connecte ensuite normalement.
- La révocation et le listing des invitations en attente ne sont pas encore exposés ; l'invitation « super-admin seul » passe par le même flux mais sans organisation.

