Skip to content

TODO — Visibilité par auteur des échanges et rappels

Points ouverts à trancher avant merge de la branche feature/contact-visibility-by-author dans main.

Contexte : la branche refond la sémantique PRIVATE/SHARED pour qu'un même contact PRIVATE puisse porter des échanges/rappels créés par plusieurs membres, chacun ne voyant que les siens (admin voit tout). En mode SHARED, l'auteur est tracé sur chaque item.


1. Asymétrie d'édition en mode SHARED entre Exchange et Reminder

Constat. Aujourd'hui, sur un contact SHARED :

  • Exchange : canEditItem(item, contact, ctx) (dans apps/api/src/contacts/privacy.ts) retourne true en SHARED quel que soit l'auteur → User B peut éditer/supprimer l'échange créé par User A.
  • Reminder : le middleware Prisma (apps/api/src/prisma/prisma.service.ts lignes 87-92) bloque toujours les writes non-admin à ownerUserId === ctx.userId → User B ne peut pas éditer le rappel créé par User A, même si le contact est SHARED.

Cette asymétrie est pré-existante (Reminder a toujours été owner-only en write), mais elle devient visible avec la nouvelle sémantique "SHARED = tout le monde voit + on logge l'auteur". Un utilisateur dira légitimement : "pourquoi je peux modifier l'échange d'un collègue mais pas son rappel sur le même contact SHARED ?".

Options.

OptionEffetImpact code
A — Aligner sur Exchange : retirer la restriction ownerUserId du middleware Prisma pour Reminder en writeEn SHARED, n'importe quel membre peut éditer le rappel de n'importe qui. En PRIVATE, il faudrait ajouter un check applicatif (comme pour Exchange).Modifier prisma.service.ts:87-92 + ajouter canEditItem dans RemindersService.update/remove.
B — Aligner sur Reminder : ajouter canEditItem strict sur ExchangePersonne ne peut éditer l'échange d'un autre, ni en SHARED ni en PRIVATE (sauf admin). Plus restrictif.Modifier ExchangesService.update/remove pour utiliser un helper plus strict.
C — Laisser tel quelAsymétrie assumée — à documenter dans CLAUDE.md.Aucun code, juste de la doc.

À décider : quelle politique veut-on pour les items d'autres membres sur un contact SHARED ?


2. Affichage de l'auteur sur les anciens échanges

Constat. La migration 20260522130000_exchange_reminder_author backfill Exchange.authorUserId depuis contact.ownerUserId, mais authorEmail est laissé à '' pour les lignes historiques (on n'a pas l'email d'un user à partir de son seul userId).

Conséquence : en mode SHARED, les anciens échanges n'affichent rien à l'emplacement "par X" (le v-if="ex.authorEmail" skip le bloc). Comportement actuel = dégradé silencieux.

Options.

OptionAffichageHonnêteté UX
A — Statu quo (rien)Anciens échanges : pas de mention d'auteur.Silencieux — l'utilisateur ne sait pas si l'auteur est inconnu ou si la feature n'est pas active.
B — Italique gris "(auteur inconnu)"Anciens échanges : par (auteur inconnu).Explicite — clair pour l'utilisateur que la donnée est manquante historiquement.
C — Backfill par jointure avec Console AdminRécupérer les emails via l'API Console Admin à la migration.Propre mais nécessite un script de migration applicatif (pas SQL pur) et la disponibilité de Console Admin.

À décider : préfère-t-on l'affichage silencieux (A) ou explicite (B) ? Option C est probablement overkill pour des données historiques.


Autres choses à faire avant merge

  • Vérification navigateur : pas faite. Smoke test minimal à 2 users : créer un contact PRIVATE, switcher de compte, vérifier que chaque user ne voit que ses propres items ; basculer en SHARED, vérifier l'affichage "par X" sur chaque échange/rappel.
  • E2E Playwright : un scénario à 2 users serait utile (User A + User B sur même contact PRIVATE → isolation visible).
  • Mettre à jour docs/DUAL-COMPTE.md et/ou docs/EXCHANGES.md pour refléter la nouvelle sémantique (la section §4 de DUAL-COMPTE décrit l'ancien modèle "masquage par owner-du-contact").