Propriétaire vs auteur : la visibilité multi-source
Deux sources de visibilité, pas une
Jusqu'ici, la visibilité d'une demande dérivait de l'affectation de son compte (leçons précédentes). Mais toutes les demandes n'ont pas de compte : un email qui arrive dans une boîte non encore rattachée à un client n'a pas d'account_id. Comment décider qui le voit ?
Deuxième source : la propriété du flux d'entrée. Un connecteur email (une boîte) peut être :
- partagé (au tenant) → tout le monde voit ce qui en sort ;
- personnel (à un utilisateur) → seul son propriétaire (et les admins) le voit.
On matérialise ça avec une seule colonne sur le connecteur, owner_user_sub : NULL = partagé, = <sub> = personnel. Bonus : les connecteurs déjà existants ont owner_user_sub à NULL → partagés par défaut, aucune migration de données.
La policy request combine donc les deux sources :
Lecture d'une request (session_with_operator)
├─ admin ? ───────────────────────────────► visible
├─ a un compte ?
│ ├─ compte non affecté ───────────────► visible (tous)
│ └─ affecté à moi ? ──────oui─────────► visible
│ non────────► invisible
└─ pas de compte (inbox) :
owner_user_sub NULL (partagé) ───────► visible (tous)
owner_user_sub = moi (perso) ────────► visible
owner_user_sub = autre ──────────────► invisible
Le piège : propriétaire ≠ auteur
Une distinction qui fait ou défait la feature : ne jamais utiliser « qui a créé la ligne » (created_by_user_sub) comme clé de visibilité.
- auteur (
created_by_user_sub) = qui a cliqué / déclenché la création. Utile pour l'audit, jamais pour la visibilité. - propriétaire (
owner_user_sub) = à qui appartient le flux dont la ligne est issue.
Pourquoi c'est vital : un admin peut créer une demande sur la boîte personnelle d'un commercial ; c'est le commercial (propriétaire du flux) qui doit la voir, pas l'admin qui a cliqué. Et surtout, brancher la visibilité sur l'auteur rouvrirait la faille qu'on a fermée à la leçon précédente (« suit le compte, pas l'auteur »). La visibilité doit dériver de faits structurels stables (propriété, affectation), jamais de l'acteur qui a produit la ligne.
L'attribution se fait à l'ingestion
Où pose-t-on owner_user_sub ? À l'ingestion, pas à l'affichage. Le collecteur (le poll email) tourne en session privilégiée : il relève toutes les boîtes actives, pour tout le monde, et estampille chaque demande avec le propriétaire de la boîte dont elle vient (request.owner_user_sub = mailbox.owner_user_sub). La visibilité s'applique ensuite, en lecture HTTP, via la RLS.
C'est un découplage propre : la collecte ne connaît pas la visibilité, elle ne fait qu'attribuer une propriété stable ; la visibilité est une conséquence, calculée à la lecture. Un seul point d'écriture (owner_user_sub à l'ingestion), zéro logique de visibilité dans le collecteur.
Une demande SANS compte rattaché (inbox) est visible selon…