# 01-foundations – Vue fonctionnelle

## 1. Contexte

Les fondations définissent les règles de base du “monde interne” de Skyboard, indépendamment
des packs, de l’UI ou des licences. Elles doivent rester stables et simples, car :

- toute fonctionnalité future (progression, relations, interactions, logique, droits, communauté)
  s’appuiera dessus ;
- une erreur à ce niveau se répercute partout (effet château de cartes) ;
- à l’inverse, des fondations bien posées rendent les décisions locales beaucoup plus faciles.

Les fondations couvrent principalement :

1. **Identité & adressage**
   - Comment identifier de façon stable un board, un item (node), un workspace, une colonne.
   - Comment “pointer” un élément depuis n’importe où dans le système.

2. **Sélection universelle**
   - Comment permettre à une fonctionnalité de demander à l’utilisateur :
     “désigne-moi un (ou plusieurs) item/container n’importe où”.

3. **Sémantique `container` / `leaf`**
   - Ce que signifie structurellement un container et un leaf.
   - Ce qui est permis ou interdit (enfants, conversions, etc.).

4. **Tags (philosophie générale)**
   - Rôle des tags comme données (état, type, catégorie…).
   - Différence entre tags système et tags utilisateur.
   - Relation entre tags et comportement (règles, assistans).

5. **Temps & événements**
   - Comment le temps est représenté (timestamps, échéances…).
   - Notion d’événement métier (item créé, terminé, tag ajouté, échéance dépassée…).
   - Ce qui peut déclencher automatiquement des règles.

Ces fondations ne décrivent pas encore “comment” c’est implémenté (Commands, RulesEngine, etc.).
Elles fixent le **langage commun** que les phases suivantes pourront utiliser sans se contredire.


## 2. Objectifs

Les fondations doivent permettre, fonctionnellement, de :

1. **Identifier sans ambiguïté n’importe quel élément adressable**
   - Avoir une forme d’“adresse” claire pour un node ou un container,
     réutilisable partout (relations, actions, permissions, publication, etc.).
   - Distinguer nettement “ce que l’on pointe” (l’élément) de “qui y a accès” (droits).

2. **Désigner un élément via l’interface de manière universelle**
   - Permettre à n’importe quelle fonctionnalité d’ouvrir un “mode sélection”
     et de récupérer des adresses (board + node), sans se soucier du geste précis (clic droit, menu, bouton).
   - Garantir une expérience cohérente pour l’utilisateur (signal clair, possibilité d’annuler).

3. **Garantir une base structurelle simple et solide**
   - Définir clairement ce qu’est un `container` et un `leaf` au niveau fonctionnel.
   - Éviter que la structure (container/leaf) soit utilisée pour encoder des comportements métiers confus.
   - Encadrer les transformations container ↔ leaf par des règles simples, avec un sens de “promotion” mieux défini que la rétrogradation.

4. **Clarifier le rôle des tags**
   - Affirmer que les tags sont d’abord des **données** (états, types, catégories), pas de la magie cachée.
   - Poser la différence entre :
     - tags système (réservés, documentés, interprétés par des règles),
     - tags utilisateur (libres, non interprétés globalement).
   - Éviter l’apparition de tags “mystiques” qui changent silencieusement la sémantique.

5. **Poser un modèle fonctionnel du temps & des événements**
   - Introduire l’idée qu’un item peut porter des informations temporelles (création, modification, échéance).
   - Introduire la notion d’événements déclencheurs (ex. “l’item est terminé”, “la date est dépassée”)
     qui pourront être exploités plus tard par les systèmes de progression, de relations, d’interactions, etc.

L’objectif global : que Progression, Relations, Interactions, Logic, Teams et Community puissent
**parler le même langage** (adresses, tags, temps, container/leaf) sans se marcher dessus.


## 3. Scénarios d’usage (exemples)

### 3.1. Sélection d’un container comme cible d’une opération

- L’utilisateur ouvre un side panel (par exemple “Actions” ou “Relations”).
- Il clique sur “Choisir un container cible…”.
- L’interface passe en **mode sélection** :
  - un message clair apparaît (“Cliquez sur un container n’importe où dans ce board pour le sélectionner”),
  - le reste de l’UI est légèrement grisé,
  - un bouton “Annuler” est disponible.
- L’utilisateur clique sur un container dans un autre workspace.
- Le système récupère une **adresse** de la forme `{ boardId, nodeId }` pour ce container.
- Cette adresse est réutilisée par la fonctionnalité qui en avait besoin (déplacement, relation,
  action, permission, etc.).

### 3.2. Création d’une relation de dépendance entre deux items

- L’utilisateur sélectionne un item A dans un board.
- Il ouvre un panneau “Relations” et choisit “Ajouter une dépendance…”.
- L’UI demande :
  > “Sélectionnez l’item dont A dépend”.
- Le système passe en mode sélection, l’utilisateur clique sur un item B :
  - éventuellement dans un autre container,
  - voire dans un autre workspace du même board.
- Le système enregistre une relation fonctionnelle basée sur les **adresses** de A et B
  (et non sur leur position visuelle uniquement).

### 3.3. Déplacement d’un item vers un autre workspace

- L’utilisateur ouvre le menu d’un item et choisit “Déplacer dans…”.
- L’UI active le mode sélection avec un filtre “seulement les containers”.
- L’utilisateur navigue dans un autre workspace et clique sur le container cible.
- Le système déplace l’item vers ce container, en respectant les invariants structurels
  (pas de cycles, leaf sans enfants, ordre cohérent).

### 3.4. Règle basée sur le temps et les tags

- Un item porte un tag d’état “En cours” et une échéance “Deadline : 2025-03-10”.
- Le jour où la date est dépassée, un événement logique “échéance dépassée” est considéré comme vrai.
- Une règle (dans Progression ou Gestion) peut dire, au niveau fonctionnel :
  > “Si l’échéance est dépassée et l’item n’est pas terminé, appliquer le tag En retard”.
- La fondation définit simplement que :
  - les dates existent comme données,
  - l’événement “échéance dépassée” est un concept valable,
  - les tags d’état sont la manière de refléter l’état courant.

### 3.5. Utilisation des tags sans comportement implicite dangereux

- Un utilisateur applique un tag personnalisé “#urgent” sur un item.
- Ce tag n’a **pas** d’effet global magique en lui-même.
- Par contre, un système (par ex. Interactions) peut permettre au user avancé de dire explicitement :
  > “Quand un item passe à l’état Terminé ET possède le tag #urgent, alors envoyer une notification.”
- La fondation garantit que :
  - l’application d’un tag ne change pas toute la sémantique du système de façon cachée,
  - c’est toujours une règle déclarée (et donc visible) qui donne un effet métier.


## 4. Contraintes & invariants fonctionnels

### 4.1. Identité & adressage

- Chaque board possède un identifiant stable (`boardId`) qui ne change pas.
- Chaque node possède un identifiant stable (`nodeId`), **globalement unique** à l’échelle du logiciel.
- Une **adresse** logique minimale d’item est définie comme :
  - `{ boardId, nodeId }`.
- En V1, toutes les opérations métier (sélection, relations, actions, règles) sont **strictement intra‑board** :
  - une interaction déclenchée depuis un board ne propose que des items de ce même board,
  - une même commande ne DOIT JAMAIS référencer plusieurs `boardId` dans une seule payload.
- La présence explicite de `boardId` dans l’adresse permet d’anticiper de futurs scénarios multi‑boards,
  sans remettre en cause ce principe d’isolation stricte dans la première version.
- L’adresse d’un item :
  - ne dépend pas de sa position visuelle (ordre dans une liste),
  - ne dépend pas de son nom ou de son titre,
  - reste valable tant que l’item existe.

### 4.2. Sélection universelle

- Toute fonctionnalité qui a besoin que l’utilisateur désigne un item/container passe
  par un **même mécanisme de sélection** (mode “pending sélection”) :
  - visible (feedback clair),
  - annulable (Esc, bouton “Annuler”),
  - pouvant être filtré (containers seulement, items avec tels tags, etc.).
- **Contrat UX minimal** :
  - prévisualisation obligatoire avant exécution : nombre de cibles et aperçu des 3–5 premiers items,
  - si la sélection renvoie 0 item : bouton d’exécution désactivé + message clair “Aucune cible ne correspond à ces critères.”,
  - V1 ne persiste pas le résultat de la sélection (liste d’items) ; seuls les critères (scope + filtres) utilisés par une action sont conservés.
- La sélection ne fait en elle-même **aucune mutation** :
  - elle se contente de retourner une ou plusieurs adresses `{ boardId, nodeId }`
    à la fonctionnalité appelante.

### 4.3. Container vs leaf

- Un `container` est un node qui peut contenir des enfants.
- Un `leaf` est un node qui ne peut pas contenir d’enfants.
- Un `leaf` ne doit jamais avoir de children, et aucune fonctionnalité ne doit violer cette règle.
- Le type structurel (container/leaf) est :
  - **structurel**, pas un état métier (“projet”, “tâche”, “répertoire” sont des usages, pas des shapes),
  - utilisé comme support pour certaines fonctionnalités, mais ne doit pas être surchargé de sémantique cachée.
- Toute transformation container ↔ leaf doit être :
  - explicite,
  - encadrée par des règles simples :
    - il est possible de **promouvoir** un leaf en container (par ex. via des tags structurels noyau),
    - il est **impossible** de rétrograder automatiquement un container en leaf si des enfants existent ;
      toute opération de ce type doit passer par un flux clair (suppression/déplacement des enfants, puis conversion explicite).

### 4.4. Tags

- Un **tag** décrit un aspect de l’item (état, type, catégorie, relation logique, etc.).
- On distingue :
  - les **tags système** :
    - nommés dans un espace de noms clair (ex. `state/*`, `type/*`, `rel/*`, `structure/*`),
    - documentés, interprétés par des règles explicites,
  - les **tags utilisateur** :
    - libres, non interprétés globalement par le noyau.
- Les préfixes réservés (`state/`, `rel/`, `resource/`, `type/`, `assigned/`, `sys/`, `event/`, `team/`…) sont **interdits** pour les tags utilisateur ; toute tentative de création échoue avec un message explicite.
- Les comportements métiers ne naissent pas de tags “magiques” isolés, mais de :
  - **règles** qui disent explicitement : “si item possède tel tag, alors…”.
- Les tags structurels (comme ceux qui influent sur `container`/`leaf`) sont :
  - rares,
  - clairement définis comme tels,
  - traités avec une extrême prudence.

### 4.5. Temps & événements

- Les items peuvent porter des données temporelles :
  - date de création,
  - date de modification,
  - échéances, deadlines, jalons, etc.
- Certains états ou combinaisons de données peuvent être interprétés comme des **événements** :
  - “item marqué comme terminé”,
  - “échéance dépassée”,
  - “tag ajouté/supprimé”,
  - “relation créée/supprimée”.
- Visibilité minimale du temps/événements :
  - chaque item dispose d’un bloc “Historique” dans sa vue détaillée (création, dernière modification, dernière transition d’état),
  - Activity affiche tous les événements horodatés filtrés par Teams,
  - sur les vignettes, des aides visuelles peuvent afficher “modifié il y a X jours” et “échéance dans X jours / dépassée depuis X jours” à partir des timestamps.
- Les fondations se contentent de reconnaître que ces événements existent comme concepts ;
  leur exploitation concrète (progression automatique, notifications, actions…) sera définie
  dans les phases suivantes (Progression, Interactions, Logic).


## 5. Interactions avec les autres phases

### 5.1. Avec 02-gestion

- Gestion utilisera :
  - les adresses `{ boardId, nodeId }` pour cibler les items et containers,
  - les tags (états, étiquettes de progression) pour représenter où en est un item,
  - les événements temporels (échéances dépassées, item terminé) comme déclencheurs de mise à jour.
- Les fondations garantissent que :
  - la progression peut être calculée de manière stable, même si la structure visuelle change,
  - les états restent cohérents avec les invariants de base (pas de leaf avec enfants, etc.).

### 5.2. Avec 03-relations

- Relations utilisera :
  - les adresses pour relier clairement deux items, indépendamment de leur position,
  - le type container/leaf pour différencier certaines relations (ex. container logique d’un groupe).
- Les fondations garantissent que la structure de base (arbre container/leaf) ne sera pas
  cassée par l’ajout de relations.

### 5.3. Avec 04-interactions

- Interactions reposera fortement sur :
  - le système de sélection universelle pour choisir des cibles (précises ou génériques),
  - les tags et événements pour exprimer les conditions “Avant”,
  - les adresses pour exprimer les effets “Après” (sur quels items agir).
- Les fondations garantissent que toutes ces opérations utilisent la même notion d’adresse
  et de sélection, et ne créent pas d’ambiguïté.

### 5.4. Avec 05-logic

- Logic étendra :
  - les types de tags et de catégories,
  - les types d’événements et de conditions,
  - la manière dont on peut combiner conditions et actions.
- Les fondations fixent le socle minimal sur lequel le pack logique peut construire sans
  redéfinir la notion d’identifiant, de sélection, de temps ou de structure.

### 5.5. Avec 06-teams

- Teams s’appuiera sur :
  - les adresses `{ boardId, nodeId }` comme unités de permission,
  - la sélection universelle pour choisir “sur quoi” un droit doit s’appliquer (board, sous-arbre, item).
- Les fondations garantissent qu’un droit s’applique toujours à quelque chose
  d’identifiable et stable.

### 5.6. Avec 07-community

- Community reposera sur :
  - les adresses et les IDs pour savoir quelles parties d’un board sont rendues publiques,
  - les structures (containers/leaf) pour définir des “zones” publiées,
  - les tags/états/progression pour afficher l’état d’avancement.
- Les fondations garantissent que l’on peut exposer une partie du système (un board, un container)
  sans remettre en cause l’identité ou la cohérence interne.
