Files
flowdeck/docs/Guide_Complet_Notion_sharing_collaborartion.md
T
bruno b60cc8a7c6
FlowDeck CI / test (push) Failing after 6s
FlowDeck CI / docker (push) Skipped
feat(collab): v4.9.0 Collaboration - commentaires inline, mentions @, notifications in-app + email
2026-09-04 23:40:21 -04:00

230 lines
16 KiB
Markdown

# 📘 Guide d'Implémentation : Fonctionnalités de Partage et Collaboration (Style Notion pour Flowdesk)
> Sources officielles consultées : [Sharing & permissions](https://www.notion.com/help/sharing-and-permissions), [Comments, mentions & reactions](https://www.notion.com/help/comments-mentions-and-reminders), [Suggested edits](https://www.notion.com/help/suggested-edits), [Create & manage groups](https://www.notion.com/help/create-and-manage-groups), [Who's who in a workspace](https://www.notion.com/help/whos-who-in-a-workspace), [Collaborate in a workspace](https://www.notion.com/help/collaborate-within-a-workspace).
## 1. Vue d'ensemble des fonctionnalités cibles
Pour reproduire l'expérience de collaboration de Notion, le clone Flowdesk doit intégrer cinq piliers fonctionnels :
1. **Partage granulaire** : Invitation de membres, d'invités externes (guests, par email), partage avec des groupes, des teamspaces, ou partage public par lien / publication web.
2. **Niveaux d'accès (RBAC)** : `Full access`, `Can edit`, `Can edit content`, `Can create`, `Can comment`, `Can view` — avec sémantique précise (voir §2 et §4).
3. **Permissions au niveau des pages de base de données (Page-Level Access)** : Règles d'accès dynamiques basées sur les propriétés « Personne » ou « Créé par ».
4. **Droits sur les rôles du workspace** : membres, membres restreints, invités (guests), membres temporaires, propriétaires, admins de membres, groupes (dont groupes synchronisés via SCIM).
5. **Collaboration synchrone & asynchrone** : présence en temps réel (avatars), édition simultanée, commentaires (page, bloc, propriété), mentions (@), réactions, suggestions d'édition (suggested edits) et verrouillage de page.
---
## 2. Guide d'utilisation (Flux Utilisateur)
*L'agent IA doit reproduire ces flux interactifs :*
### 2.1 Initier le partage
1. L'utilisateur clique sur **« Partager »** en haut à droite de la page.
2. La modale propose trois actions : **inviter des personnes**, **copier le lien de la page**, **publier sur le web** (onglet `Publish`, distinct du simple partage par lien).
3. Pour inviter, l'utilisateur tape un nom (membre ou groupe) ou un email d'invité externe. Le système propose une autocomplétion en temps réel.
4. Un menu déroulant à côté de chaque nom permet de choisir le niveau d'accès, puis l'utilisateur clique sur **Inviter**.
### 2.2 Configurer l'accès général (General access)
Un sélecteur définit la visibilité par défaut de la page :
- **`Only people invited`** : seuls l'utilisateur et les personnes invitées y ont accès.
- **`Everyone at {workspace}`** : tous les membres du workspace y accèdent via la recherche ou le lien — avec option **« Hide in search »** pour masquer la page des résultats de recherche.
- **`Anyone on the web with link`** : toute personne disposant du lien peut y accéder, même sans compte Notion (connexion requise uniquement pour commenter/modifier) — avec option **« Link expires »** pour faire expirer le lien.
Pour chaque groupe d'accès général, on peut attribuer un niveau d'accès indépendant.
> **Note (sécurité Enterprise)** : les propriétaires peuvent désactiver les liens publics via `Settings → Security → Disable publishing sites, forms and public links`.
### 2.3 Demander l'accès (Request access)
- **Aucune page accessible** : en ouvrant une page, l'utilisateur voit un bouton `No access` → envoie une demande, notifie le créateur/éditeur qui peut accepter ou refuser.
- **Accès en lecture/commentaire** : `Share → dropdown de son propre niveau → Request edit access`. La demande est envoyée au créateur de la page.
### 2.4 Règles de base de données (Page-level access, optionnel)
1. Ouvrir la **base source** (pas une vue liée).
2. `Share` → section **`Page-level access`** → **`Add a new rule`**.
3. Choisir une propriété `Person` ou `Created by`, puis un niveau d'accès → **`Create rule`**.
Exemple : « Les personnes dans la propriété `Assigné à` peuvent **modifier** leur propre ligne ». Les règles s'appliquent à **toutes les vues** de la base, y compris les **vues liées**. Chaque source de données (data source) d'une base multi-sources peut avoir ses propres règles.
### 2.5 Arrêter de partager
- Glisser la page vers la section **`Private`** de la sidebar (supprime l'accès de tous les autres).
- Ou `Share` → dropdown de chaque personne/groupe/teamspace → **`Remove`**.
---
## 3. Représentation Visuelle (UI/UX) pour l'Agent IA
*Instructions de conception d'interface pour la génération de code frontend :*
### Bouton de partage
En haut à droite, dans la barre de titre de la page. Bouton secondaire avec icône de partage (ou libellé « Partager »).
### Modale de partage (Share Modal)
- Champ de saisie en haut avec placeholder « Inviter des personnes... ».
- Liste verticale des utilisateurs/groupes ayant accès. Chaque ligne : **Avatar + Nom/Email + Dropdown de permission (ex. « Peut modifier » ▼) + Icône X (suppression)**.
- Section **« General access »** avec le sélecteur principal et les options conditionnelles (case « Hide in search », expiration du lien).
- Section **« Page-level access »** (base de données uniquement) listant les règles existantes + bouton « Add a new rule ».
- **Validation en lecture seule** : la modale doit montrer à l'utilisateur courant son niveau d'accès courant, avec la possibilité de « Request edit access ».
### Indicateurs de présence (Presence Bar)
- Barre horizontale en haut de la page, alignée à droite, affichant les avatars des utilisateurs ayant accès.
- **Avatar plein** : personne actuellement sur la page.
- **Avatar estompé (opacité réduite)** : personne récemment partie.
- **Avatars mobiles** : en collaboration simultanée, les avatars se déplacent **à côté des blocs** que chacun lit/édite.
- **Au survol** : infobulle avec Nom, Email et « Dernière activité il y a X ».
- **Au clic** : la vue défile jusqu'à la position de lecture/édition de la personne ciblée.
- **Historique** : menu `•••` en haut à droite → bas du menu : « Dernière modification par X, il y a Y ».
### Système de commentaires
- **Discussion de page (top-level)** : au survol du haut de la page, bouton « Add comment ».
- **Commentaires inline** (plusieurs déclencheurs) : sélection de texte → « Comment » ; icône `⋮⋮` à gauche du bloc → « Comment » ; bouton `💬` au survol du bloc ; raccourci `Ctrl/Cmd + Shift + M` ; clic sur un `💬` existant pour répondre.
- **Panneau de commentaires (Comments pane)** : icône `💬` en haut de page (pastille rouge si non-lus). Filtrage par personne / statut (ouverts / résolus). Tri par dernier message.
- **Indicateur de résolution** : ✔️ pour résoudre, `•••` → Éditer / Supprimer, `↪️` pour rouvrir un commentaire résolu.
- **Réactions** : surligner un texte → `🙂` → emoji ; survol d'un commentaire → `🙂` → emoji.
- **Commentaires de base de données** : `💬` associé aux lignes (table/board/gallery) ; `⋮⋮`/`•••` → « Comment » ; commentaires sur les **propriétés** (survol d'une propriété → `💬`).
- **Mentions (@)** : la saisie de « @ » ouvre un menu contextuel (Popper) à trois types : **Personnes/groupes**, **Pages** (lien inline + backlink auto), **Date** (aujourd'hui/demain/hier ou date).
- **Mode Suggestion (Suggested edits)** : activé via `•••` → « Suggest edits ». Bandeau `Suggesting` en haut. Les suggestions (ajout/suppression) apparaissent dans la marge, acceptables (✔️) ou refusables (❌), réactives (emoji) et commentables.
### Verrouillage de page / base
- **Lock page** (`•••` → `Lock page`) : page en lecture seule pour tous, badge `Locked` dans le breadcrumb.
- **Lock database** : verrouille la structure (vues/propriétés) tout en permettant l'édition des données.
- **Déverrouillage** : `Locked` → `Unlock for me` (déverrouille pour soi uniquement) ou `Unlock for everyone`.
---
## 4. Guide d'Implémentation Technique (Architecture & Données)
*Spécifications pour que l'agent IA génère le backend et la logique métier :*
### A. Modèle de données (Schéma relationnel simplifié)
```sql
-- Principaux (Utilisateurs et Groupes)
CREATE TABLE principals (
id UUID PRIMARY KEY,
type VARCHAR(20), -- 'user' | 'group' | 'teamspace' | 'guest'
name VARCHAR(255),
email VARCHAR(255) UNIQUE, -- NULL pour les groupes
workspace_role VARCHAR(20), -- 'member' | 'restricted_member' | 'guest' |
-- 'temporary_member' | 'workspace_owner' |
-- 'membership_admin' | 'organization_owner'
is_scim_managed BOOLEAN DEFAULT false -- groupes synchronisés via identité externe
);
-- Appartenance utilisateur -> groupe (N:N)
CREATE TABLE group_members (
group_id UUID REFERENCES principals(id),
member_id UUID REFERENCES principals(id),
PRIMARY KEY (group_id, member_id)
);
-- Ressources (Pages, Bases de données)
CREATE TABLE resources (
id UUID PRIMARY KEY,
type VARCHAR(50), -- 'page' | 'database'
parent_id UUID, -- Héritage des permissions
workspace_id UUID,
is_locked BOOLEAN DEFAULT false -- verrou de page
);
-- Permissions (RBAC avec héritage)
CREATE TABLE permissions (
id UUID PRIMARY KEY,
resource_id UUID REFERENCES resources(id),
principal_id UUID REFERENCES principals(id),
access_level VARCHAR(20), -- 'full' | 'edit' | 'edit_content' | 'create' | 'comment' | 'view'
is_inherited BOOLEAN DEFAULT false -- true si hérité du parent / teamspace / workspace
);
-- Règles d'accès au niveau de la page de base de données (Page-Level Access)
CREATE TABLE page_level_rules (
id UUID PRIMARY KEY,
database_id UUID REFERENCES resources(id),
target_property_name VARCHAR(50), -- propriété 'Person' OU 'Created by'
access_level VARCHAR(20), -- 'edit' | 'comment' | 'view' (etc.)
data_source_id UUID NULL -- en cas de base multi-sources
);
-- Commentaires
CREATE TABLE comments (
id UUID PRIMARY KEY,
resource_id UUID REFERENCES resources(id),
block_id UUID NULL, -- NULL = discussion de page ; sinon bloc/propriété ciblé
author_id UUID REFERENCES principals(id),
content TEXT,
thread_id UUID NULL, -- pour les réponses groupées
is_resolved BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT NOW()
);
-- Réactions
CREATE TABLE reactions (
id UUID PRIMARY KEY,
target_type VARCHAR(20), -- 'comment' | 'text' | 'suggestion'
target_id UUID,
author_id UUID REFERENCES principals(id),
emoji VARCHAR(8)
);
-- Suggestions d'édition (Suggested edits)
CREATE TABLE suggestions (
id UUID PRIMARY KEY,
resource_id UUID REFERENCES resources(id),
block_id UUID,
author_id UUID REFERENCES principals(id),
operation VARCHAR(10), -- 'insert' | 'delete'
payload TEXT, -- contenu proposé / supprimé
status VARCHAR(20), -- 'open' | 'accepted' | 'rejected'
created_at TIMESTAMP DEFAULT NOW()
);
```
### B. Sémantique exacte des niveaux d'accès
| Niveau | Effets |
|---|---|
| `Full access` | Modifier tout le contenu **et** partager la page avec qui l'on veut. |
| `Can edit` | Modifier le contenu, **sans** pouvoir partager. |
| `Can edit content` | **Pages de base de données uniquement** : créer/modifier des pages de la base et leurs propriétés, sans toucher à la structure (propriétés, vues, tris, filtres). |
| `Can create` | **Pages de base de données uniquement** (Business/Enterprise) : créer de nouvelles pages, sans voir/modifier les pages existantes (soumissions de tickets, formulaires...). |
| `Can comment` | Commenter et suggérer des modifications, sans éditer ni partager. |
| `Can view` | Lecture seule. |
### C. Logique de résolution des permissions
1. Vérifier une permission **explicite** pour l'utilisateur **ou** l'un de ses groupes sur la ressource cible.
2. Si aucune permission explicite, remonter l'arbre (`parent_id`) pour vérifier les permissions **héritées** de la page parente, du teamspace ou du workspace.
3. Pour les bases de données, évaluer dynamiquement les `page_level_rules` : si l'ID de l'utilisateur correspond à la valeur de la propriété `target_property_name` de la ligne, appliquer le niveau d'accès de la règle.
4. **Principe du niveau le plus large** : Notion respecte **toujours le niveau d'accès le plus étendu** accordé à un utilisateur (permission personnelle + groupe + workspace + règle de base).
> ⚠️ **Piège à implémenter** : une règle `Can view` sur une personne est écrasée si l'utilisateur reçoit « Everyone at workspace → Full access ». L'agent doit sommer toutes les sources d'accès et retenir le maximum (ordre : `full > edit > edit_content > create > comment > view`).
5. **Sans accès à la base** mais avec une règle de page : l'utilisateur n'accède qu'aux lignes concernées via une **notification** ou une **vue liée** ; il ne peut pas créer de nouvelles pages (il faut un formulaire).
### D. Collaboration en temps réel (Stack technique recommandée)
- **Synchronisation d'état** : CRDT (**Yjs** ou **Automerge**) pour l'édition simultanée sans verrou (Notion ne verrouille pas un bloc en cours d'édition — le dernier changement l'emporte).
- **Transport** : **WebSockets** (Socket.io, Hocuspocus, ou Liveblocks) pour diffuser les mises à jour de contenu, les événements de présence et les commentaires.
- **Gestion de la présence** : registre en mémoire des `user_id` connectés à un `resource_id`, avec diffusion des avatars actifs et de leur **position de bloc** (curseur/édition) aux clients connectés, à la connexion/déconnexion et périodiquement.
### E. Endpoints API clés à générer
- `POST /api/resources/:id/share` : ajoute/met à jour une entrée dans `permissions` (invitation membre, invité, groupe).
- `GET /api/resources/:id/access-check` : retourne le niveau d'accès **effectif** (calcul d'héritage + règle la plus large).
- `POST /api/resources/:id/page-level-rules` : crée une règle d'accès par propriété Person/Created by.
- `POST /api/comments` : crée un commentaire (gestion du `block_id`/`thread_id` pour l'inline).
- `POST /api/suggestions` : crée une suggestion d'édition ; `POST /api/suggestions/:id/accept` / `reject`.
- `POST /api/access-requests` : crée une demande d'accès / d'édition.
- `POST /api/resources/:id/lock` : verrouille/déverrouille une page ou la structure d'une base.
- `WS /ws/collaboration?resourceId=:id` : canal WebSocket pour CRDT, présence et commentaires temps réel.
---
## 5. Recommandations spécifiques pour le clone Flowdesk
1. **Adaptation métier** : pour un usage support/tickets, prioriser les **Page-Level Access rules** (`Can create` pour les soumissions, `Can edit` sur la propriété « Assigné à »). C'est le mécanisme qui permet à un client de ne voir/modifier que « son » ticket sans accéder à toute la base.
2. **Sécurité** : chaque requête API (lecture/écriture) doit passer par le middleware de résolution des permissions **avant** tout accès BDD. Ne jamais faire confiance au client. Appliquer le principe du niveau le plus large côté serveur, de façon centralisée.
3. **Émuler le verrouillage** : implémenter `is_locked` au niveau ressource (et structure vs données pour les bases) pour éviter les modifications accidentelles sans révoquer les droits.
4. **Notifier intelligemment** : reproduire les règles Notion — pas de notification si la personne a la page ouverte, email uniquement si Notion est fermé, pas de notification si la personne n'a pas accès à la page mentionnée.
5. **Bibliothèques Frontend suggérées** : composants « headless » **Radix UI** ou **Headless UI** pour la modale de partage, les dropdowns, les infobulles de présence et le menu de mentions.
---
## 6. Glossaire rapide des rôles (Who's who)
- **Member** : personne de l'organisation, facturée sur les plans payants.
- **Restricted member** : accès limité aux teamspaces/pages assignés ; ne peut pas créer de teamspace.
- **Guest** : personne externe, invité page par page ; ne reçoit jamais d'accès workspace-wide et ne peut pas être ajouté à un groupe.
- **Temporary member** : consultant Marketplace avec accès à durée limitée (expiration automatique).
- **Workspace owner** : admin gérant les paramètres, les membres et la suppression du workspace.
- **Membership admin** : (Enterprise) ajoute/retire des membres sans changer les paramètres.
- **Organization owner** : (Enterprise) gère plusieurs workspaces d'une organisation.
- **Group owner** : gère la composition d'un groupe sans être admin du workspace.