# 03-relations – Vue fonctionnelle

Ce document décrit comment un utilisateur crée, modifie et exploite des relations entre items
dans l’interface, indépendamment de l’implémentation technique.

On parle ici du **comportement attendu** et de l’ergonomie globale du “Pack Relations”.

---

## 1. Contexte / Problème

Aujourd’hui, la hiérarchie dans Skyboard est essentiellement :

- **visuelle** : un container contient une liste ordonnée d’items (leaf ou containers),
- **structurelle** : l’arbre container/leaf permet de regrouper les items.

Mais il manque un niveau **fonctionnel** :

- exprimer qu’une tâche **dépend** d’une autre,
- marquer qu’un item **bloque** un autre,
- pouvoir **transformer une liste existante** en chaîne de dépendances réelles,
- visualiser facilement qui est bloqué par quoi et pourquoi.

Le Pack Relations vient combler ce manque en introduisant un **moteur de relations** entre items,
exploitable dans l’interface via :

- un **panneau “Relations”** sur chaque item,
- des assistants pour générer automatiquement des relations à partir de listes existantes,
- des indicateurs visuels pour montrer rapidement les dépendances et blocages.

---

## 2. Objectifs fonctionnels

### 2.1. Types de relations de base

L’utilisateur doit pouvoir manipuler au minimum :

- une relation de type **“dépend de”** (dépendance / hiérarchie fonctionnelle) :
  - “A dépend de B” = A ne peut pas être considéré comme complètement résolu tant que B ne l’est pas ;
- une relation de type **“bloque”** (blocage explicite) :
  - “A bloque B” = tant que A n’est pas respecté/terminé, B ne peut pas avancer ; **fait partie du même DAG de dépendance** (acyclique).
- (optionnel / à discuter) une relation de type **“lié à”** (lien souple / référence croisée) :
  - “A lié à B” = lien sémantique sans logique métier forte ; hors DAG, symétrique logique (stockée une seule fois).

Ces types sont vus **côté interface** comme des options simples dans un menu ou un picker,
éventuellement extensibles plus tard (via le pack Logique).

### 2.2. Panneau “Relations” par item

Chaque item (container ou leaf) expose un **panneau Relations** dans sa fenêtre d’édition :

- onglet ou section “Relations”,
- liste des relations existantes pour cet item,
- actions pour en ajouter, modifier ou supprimer.

Ce panneau fonctionne comme **point central** pour :

- voir **de quoi dépend** l’item (relations entrantes),
- voir **ce que l’item bloque / supporte** (relations sortantes),
- naviguer vers les items liés (clic = ouvrir l’item cible).

### 2.3. Listes fonctionnelles (assistant ponctuel)

Objectif fort : permettre à l’utilisateur de transformer rapidement une liste déjà remplie en
hiérarchie fonctionnelle, **sans** introduire de mode caché qui recalcule des relations à chaque
mouvement.

Sur un item de type container (une liste), le panneau Relations propose :

- une action du type **“Rendre cette liste fonctionnelle”** :
  - utilise l’ordre **actuel** des enfants pour proposer une chaîne de dépendances,
  - par exemple : dans une liste `[A, B, C, D]`, suggérer :
    - B dépend de A,
    - C dépend de B,
    - D dépend de C,
  - optionnellement, tous ces enfants peuvent aussi dépendre du container parent.
- l’UI affiche un **aperçu** de ces relations (liste ou mini-graph) avant validation.
- en cas de confirmation, des relations explicites sont créées une fois pour toutes ;
  par la suite :
  - les déplacements (drag & drop) n’entraînent **aucun recalcul automatique**,
  - l’utilisateur gère ensuite les relations comme n’importe quelles relations manuelles.

L’assistant est donc :

- un moyen rapide **d’initialiser** des relations cohérentes à partir d’une liste existante,
- mais il ne crée **aucun mode persistant** où la structure contrôle en continu le graphe.

### 2.4. Relation & structure visuelle : complémentarité

Les relations **n’annulent pas** la structure visuelle :

- un item peut être enfant d’un container sans être lié par une relation “dépend de”,
- une relation de dépendance peut exister entre des items situés dans des containers différents,
  voire dans des workspaces différents **du même board**.

Objectif UX :

- l’utilisateur comprend que :
  - la structure (container/leaf + ordre) = “où les choses sont rangées”,
  - les relations = “comment les choses dépendent les unes des autres” et servent de base aux calculs
    fonctionnels (progression agrégée, retards propagés, blocages expliqués, etc.).
- Les agrégations fonctionnelles NE DOIVENT PAS être dérivées directement de “tous les enfants d’un container” :
  - si l’on veut qu’un container ou un item “regroupe” fonctionnellement d’autres items, il DOIT exister
    des relations explicites qui le relient à eux (ou des règles Logique qui définissent cette agrégation).

---

## 3. Scénarios d’usage

### 3.1. Ajouter une relation simple entre deux items

1. L’utilisateur ouvre la fenêtre d’édition de l’item A.
2. Il va dans l’onglet **Relations**.
3. Il clique sur un bouton **“Ajouter une relation”**.
4. Une petite interface apparaît :
   - champ “Type de relation” (menu : dépend de / bloque / lié à…),
   - champ “Cible” avec un bouton **“Choisir un item…”**.
5. En cliquant sur “Choisir un item…”, l’UI active le **mode de sélection universelle** :
   - message clair : “Cliquez sur l’item cible dans le board”,
   - overlay léger, bouton “Annuler” disponible.
6. L’utilisateur clique sur l’item B dans le board (même workspace ou autre workspace du même board).
7. La sélection se termine :
   - le panneau Relations affiche la nouvelle relation (ex. “A dépend de B”),
   - un indicateur (icône / badge) apparaît sur les deux items pour signaler la relation.

### 3.2. Voir qui bloque un item

1. L’utilisateur voit sur un item A une icône “Relations” (ex. un petit graphe, une chaîne, un warning).
2. Il ouvre la fenêtre d’édition de A, onglet Relations.
3. Il voit une section “Cet item **dépend de** :” listant les items dont A dépend.
4. Il voit une section “Cet item **bloque** :” listant les items bloqués par A.
5. Il peut cliquer sur un item de ces listes pour :
   - ouvrir son panneau d’édition,
   - se déplacer dans le board jusqu’à lui (scroll + highlight).

### 3.3. Rendre une liste existante “fonctionnelle” (et suivie)

1. L’utilisateur a un container L avec des enfants `[A, B, C, D]` dans un ordre précis.
2. Il ouvre la fenêtre d’édition de L, onglet Relations.
3. Il clique sur un bouton **“Rendre cette liste fonctionnelle (suivre l’ordre)”**.
4. L’UI affiche un aperçu :
   - “B dépendra de A”,
   - “C dépendra de B”,
   - “D dépendra de C”.
   (option : checkbox “Faire dépendre les enfants de L lui-même”).
5. L’utilisateur confirme.
6. Les relations sont créées dans le graphe ; la liste reste ensuite **une simple structure visuelle** :
   - déplacer B ou C ne recalcule pas automatiquement ces relations,
   - l’utilisateur peut ajuster ou supprimer les relations comme n’importe quelles relations manuelles.

### 3.3. Ajuster une relation depuis le board (raccourcis)

En complément du panneau d’édition, des raccourcis contextuels peuvent être proposés :

- Clic droit ou menu “trois points” sur un item A :
  - option **“Ajouter une dépendance…”** :
    - l’UI passe en mode sélection universelle,
    - l’utilisateur clique sur B,
    - résultat : “A dépend de B”.
  - option **“Voir les relations”** :
    - ouvre directement le panneau Relations de A.

Ces raccourcis utilisent toujours le même moteur de sélection/relations ;
ils ne doublent pas la logique, ils offrent juste des points d’entrée plus rapides.

### 3.4. Supprimer / casser une relation

1. Dans le panneau Relations de A, l’utilisateur voit une ligne :
   - “A dépend de B” avec une icône de suppression (poubelle / croix).
2. En cliquant sur la suppression :
   - une confirmation rapide peut être demandée si la relation est critique,
   - la relation est supprimée.
3. Les indicateurs visuels sur A et B sont mis à jour en conséquence.

---

## 4. Contraintes & invariants métiers

### 4.1. Pas de cycles fonctionnels

- Il ne doit jamais être possible de créer un **cycle de dépendances** logique, du type :
  - A dépend de B, B dépend de C, C dépend de A.
- Toutes les relations porteuses de dépendance (`depends=true`, incluant “bloque”) appartiennent à ce même graphe acyclique.
- L’interface doit :
  - soit prévenir en amont (option grisée, message),
  - soit refuser avec une explication claire.

(La manière exacte de détecter les cycles sera traitée dans la partie technique.)

### 4.2. Relations cross-workspaces (même board)

- Il est autorisé de créer des relations :
  - entre items du même container,
  - entre items de containers différents,
  - entre items de workspaces différents, **tant que c’est le même board**.
- Le fait de changer un item de workspace (via déplacement) ne casse pas la relation :
  - les relations suivent l’item via son `nodeId`.

Les relations **cross-board** sont, à ce stade, considérées comme hors périmètre (à discuter plus tard).

### 4.3. Lisibilité & UX

- Un utilisateur doit pouvoir, depuis n’importe quel item :
  - **voir rapidement** s’il est impliqué dans des relations,
  - **comprendre le sens** de la relation (qui dépend de qui, qui bloque quoi).
- Les indicateurs visuels doivent rester sobres :
  - pas de surcharge de graphes complexes dans le board,
  - mais suffisamment d’indices (icônes, badges, nombres de relations) pour encourager l’exploration.

### 4.4. Respect de la structure container/leaf

- Les relations ne doivent jamais violer les invariants structurels :
  - un leaf ne devient pas “container” pour les besoins d’une relation,
  - un container reste un container visuellement et structurellement.
- Certaines relations pourront être plus naturelles entre certains types d’items (par exemple :
  - “Cette phase (container) dépend de ce livrable (leaf)”
  - “Cette tâche (leaf) dépend de cette sous-tâche (leaf)”),
  mais c’est du ressort de la partie technique / des règles, pas de la structure de base.

### 4.5. Assistants : pas de mode caché ni de tag magique

- L’assistant “Rendre cette liste fonctionnelle” est une **action ponctuelle explicite** :
  - il propose un plan de relations à partir de la structure existante,
  - puis, en cas de validation, crée des relations explicites une fois pour toutes.
- Il ne DOIT PAS exister de mode persistant ou de tag “magique” qui, appliqué à un container,
  change silencieusement sa sémantique ou recalcule des relations à chaque DnD :
  - aucune configuration cachée ne lie durablement “ordre des enfants” et “graphe des relations”,
  - les tags système (`state/*`, `type/*`, `rel/*`, etc.) restent des **données** interprétées par des règles,
    pas un mécanisme générique pour piloter la structure ou les modes internes.

---

## 5. Interactions avec les autres systèmes

### 5.1. Avec Progression / Gestion (retards)

- Une relation “A dépend de B” peut influer sur :
  - l’affichage de la progression (A ne peut pas être à 100 % si B ne l’est pas),
  - l’explication d’un retard (A est en retard car B est en retard).
- Le panneau Relations sert de **point d’explication** :
  - “Cet item est bloqué car il dépend de X qui n’est pas terminé.”
- Les packs Gestion et Logique exploitent donc le **graphe de relations** pour calculer progression agrégée,
  retards et blocages, et non la simple structure container/leaf.

### 5.2. Avec Interactions (actions ciblées)

- Les conditions “Avant” des actions pourront cibler :
  - “tous les items qui dépendent de X”,
  - “tous les items bloqués par Y”.
- Les effets “Après” pourront :
  - marquer plusieurs items à partir d’une chaîne de dépendances,
  - créer ou supprimer des relations en réponse à un événement.

L’interface d’Interactions pourra proposer des filtres basés sur les relations
(sans réinventer la logique de relations elle-même).

### 5.3. Avec Logique (règles custom)

- Logique pourra :
  - définir de nouveaux types de relation (`rel/custom/*`),
  - définir des règles du type “si X dépend de Y et Z, alors…”.
- L’interface Relations reste le **point de contact utilisateur** pour manipuler les relations,
  même si Logique en ajoute des types ou des comportements.

### 5.4. Avec Teams (droits)

- Les permissions de lecture/écriture des relations suivent les droits sur les items :
  - si un utilisateur ne peut pas voir un item, il ne voit pas non plus les relations qui y mènent,
  - si un utilisateur ne peut pas modifier un item, il ne peut pas modifier ses relations.

(Les détails seront définis dans la phase Teams.)

### 5.5. Avec Community (publication)

- Lorsqu’un container ou un board est publié :
  - certaines relations peuvent pointer vers des items non publiés,
  - l’interface Community devra décider comment les afficher (anonymiser, résumer, masquer).
- Le Pack Relations fournit l’information (“cet item dépend d’un autre non visible”),
  Community décide de la rendre plus ou moins explicite.

---

Ce document reste volontairement centré sur **l’expérience utilisateur** :
la partie technique décrira ensuite comment encoder ces relations (modèle de données, invariants,
règles de détection de cycles, etc.) en respectant ces attentes fonctionnelles. 
