Skip to content

Multi-tenancy

L’application utilise stancl/tenancy pour isoler les données par cabinet/structure. Chaque Tenant possède sa propre base de données. Les données partagées (utilisateurs, subscriptions, networks) vivent en base centrale.

graph LR
    subgraph Central DB
        central_users
        tenants
        tenant_users["tenant_users (pivot)"]
        tenant_invitations
        subscriptions
        networks
        retrocession_accounts
    end
    subgraph Tenant DB["Tenant DB (1 par tenant)"]
        users["users (sync depuis central)"]
        patients
        appointments
        sites
        billing_entities
    end
    central_users -. "ResourceSyncing" .-> users

graph TD
    Tenant["🏢 Tenant (cabinet/structure)"]
    Tenant --> Site1["📍 Site 1 (lieu physique)"]
    Tenant --> Site2["📍 Site 2"]
    Tenant --> Sub["💳 Subscription (Stripe)"]
    Site1 --> UserA["👤 User A (orthoptiste)"]
    Site1 --> UserB["👤 User B (secrétaire)"]
    Site1 --> Agenda["📅 Agenda, WaitingRoom..."]
    Site2 --> UserC["👤 User C (ophtalmo)"]

Le tenant est l’entité principale. Il représente un cabinet ou une structure médicale.

Modèle : src/Domain/Tenant/Models/Tenant.php

  • Étend Stancl\Tenancy\Database\Models\Tenant
  • Traits : Billable (Cashier), TenantSubscription, HasDatabase
  • Porte toutes les infos de billing, quotas, features du plan
  • Relation N-N avec CentralUser via la pivot tenant_users

Un site est un lieu physique au sein d’un tenant (cabinet, clinique).

Modèle : src/Domain/Site/Models/Site.php

  • Appartient à un tenant (via la tenant DB)
  • A des users (N-N avec pivot : billing_entity_id, billing_entity_mode, proofreadings, expired_at)
  • A des agendas, salles d’attente, types de RDV
  • Peut avoir une intégration Doctolib (doctolib_client_id, doctolib_sync)
  • Configurable : thème documents (DocumentLayoutTheme), mode rétrocession (SiteRetrocessionMode)
ModèleBaseRôle
CentralUserCentraleAuth, profil global, tenants, networks, chat
UserTenantCopie sync, relations locales (appointments, sites, proofreaders)

Les attributs sont synchronisés automatiquement via Stancl\Tenancy\ResourceSyncing. La liste des champs synchronisés est définie dans getSyncedAttributeNames().

Auth : CentralUser implémente Authenticatable + HasApiTokens (Passport).


ValeurDescription
userUtilisateur plateforme (patient)
prat_orthoptistOrthoptiste
prat_ophthalmologistOphtalmologue
prat_secretarySecrétaire
prat_helperAide/assistant

Les orthoptistes et ophtalmos doivent fournir un identifiant gouvernemental (prat_gouv_id). Les secrétaires et helpers nécessitent un token d’invitation pour s’inscrire.

ValeurDescription
managerAdministrateur du tenant (accès billing, invitations, settings)
userMembre standard

Stocké dans la pivot tenant_users.tenant_role.

UserAdminRole::ADMIN — super admin plateforme, accès au backoffice admin.


Chaque requête API dans un contexte tenant utilise 2 headers :

HeaderTypeDescription
X-TenantuuidID du tenant — initialise la tenancy (switch de DB)
X-SiteuuidID du site — contexte du lieu physique

Le middleware de tenancy résout X-Tenant pour initialiser la connexion à la bonne base tenant. Les routes protégées par subscribed vérifient que le tenant a un abonnement actif.


  • Base centrale (CentralConnection)
  • Contient : email, user_role, tenant_role, sites (array de site IDs)
  • Token aléatoire de 32 chars
  • Auto-purgée après 7 jours (Prunable)
  • Flow : send() → notification email → accept(CentralUser) → attach tenant + sites → delete invitation

Invitation relecteur (ProofreaderInvitation)

Section titled “Invitation relecteur (ProofreaderInvitation)”
  • Base tenant
  • Relie un requester_id (orthoptiste) à un proofreader_id (ophtalmo)
  • Flow : send() → notification → accept() (attach proofreaders) ou decline() (delete)

FichierRôle
src/Domain/Tenant/Models/Tenant.phpModèle tenant avec billing et subscription
src/Domain/Tenant/Models/TenantUsers.phpPivot tenant ↔ user (tenant_role, expired_at)
src/Domain/Tenant/Models/TenantInvitation.phpInvitation à rejoindre un tenant
src/Domain/User/Models/CentralUser.phpUtilisateur en base centrale (auth)
src/Domain/User/Models/User.phpUtilisateur en base tenant (sync)
src/Domain/User/Enums/UserRole.phpRôles métier
src/Domain/Tenant/Enums/TenantRole.phpRôles sur le tenant
src/Domain/Site/Models/Site.phpSite (lieu physique)