Files
gestion_projets/docs/modele-donnees.md
Bertrand Benjamin 98ae311545 Frise multi-projets : outil de planification macro
Une frise chronologique unique où plusieurs projets s'empilent en couloirs
pliables, pour voir d'un coup d'œil où en est chacun et comment ils se situent
les uns par rapport aux autres. Ce n'est pas un outil de suivi quotidien : une
phase se compte en semaines, et il n'y a ni sous-tâches, ni tickets, ni
dépendances entre phases.

- Manipulation directe des barres (glisser, redimensionner), accrochées au lundi
- Couloirs pliables : plié, un projet devient une barre segmentée par phase
- Planning de référence figeable, avec barre fantôme et calcul de dérive
- En-tête à trois bandes : année, mois, numéro de semaine ISO 8601
- Frise qui s'élargit au défilement, pour planifier dans un futur encore vide
- Micro-serveur Python (bibliothèque standard) exposant GET/PUT sur /api/data,
  avec sauvegarde horodatée avant chaque écriture
- Zéro build : modules ES natifs, aucune dépendance à installer

50 tests unitaires sur la logique métier (node --test, sans dépendance).
Vérifié dans Chromium et Firefox.

Les arbitrages de conception et surtout leurs raisons sont consignés dans
docs/decisions.md — notamment l'abandon des dépendances entre phases, de la
File System Access API, du SVG et des niveaux de zoom.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 06:53:57 +02:00

5.3 KiB

Modèle de données

Tout le planning tient dans un seul fichier JSON, par défaut data/projets.json.

Le fichier est écrit indenté sur 2 espaces, avec les clés dans un ordre stable, pour rester lisible dans un diff git et éditable à la main.

Structure

{
  "version": 2,
  "projects": [
    {
      "id": "site-web",
      "name": "Refonte du site web",
      "color": "#3b82f6",
      "collapsed": false,
      "hidden": false,
      "baselineDate": "2026-06-12",
      "phases": [
        {
          "id": "cadrage",
          "name": "Cadrage",
          "start": "2026-08-01",
          "end": "2026-08-20",
          "status": "done",
          "milestone": false,
          "notes": "Ateliers avec les trois pôles.",
          "baseline": { "start": "2026-07-25", "end": "2026-08-10" }
        },
        {
          "id": "livraison",
          "name": "Mise en ligne",
          "start": "2026-11-02",
          "end": "2026-11-02",
          "status": "todo",
          "milestone": true,
          "notes": ""
        }
      ]
    }
  ]
}

Racine

Champ Type Description
version entier Version du format. Vaut 2. Sert à détecter un fichier trop ancien au chargement.
projects tableau Les projets, dans l'ordre d'affichage des couloirs.

Projet

Champ Type Description
id chaîne Identifiant parlant, dérivé du nom (Refonte du site website-web). Unique dans le fichier.
name chaîne Nom affiché. Non vide.
color chaîne Couleur du couloir, en hexadécimal #rrggbb.
collapsed booléen true si le couloir est plié.
hidden booléen true si le projet est masqué de la frise. Ses données restent intactes.
baselineDate chaîne ou absent Date à laquelle la référence a été figée. Absent si elle ne l'a jamais été.
phases tableau Les phases, triées par date de début croissante.

Phase

Champ Type Description
id chaîne Identifiant parlant, unique au sein de son projet.
name chaîne Nom affiché. Non vide.
start chaîne Date de début, AAAA-MM-JJ.
end chaîne Date de fin incluse, AAAA-MM-JJ.
status chaîne todo, doing, done ou blocked.
milestone booléen true pour un jalon.
notes chaîne Texte libre, éventuellement vide.
baseline objet ou absent Dates de référence : { "start": …, "end": … }. Absent tant que la référence n'a pas été figée.

Règles de validation

Appliquées par js/model.js et couvertes par tests/model.test.js.

  • end est postérieure ou égale à start.
  • Un jalon (milestone: true) a nécessairement start === end. Cocher « jalon » sur une phase de plusieurs jours ramène end sur start.
  • Les dates suivent strictement AAAA-MM-JJ et doivent exister réellement dans le calendrier (2026-02-30 est rejetée).
  • id de projet unique dans le fichier ; id de phase unique dans son projet.
  • Un id est engendré à partir du nom : minuscules, accents retirés, tout ce qui n'est ni lettre ni chiffre remplacé par un tiret. En cas de collision, un suffixe numérique est ajouté (cadrage-2). Un id ne change jamais si le nom est modifié ensuite — il identifie, il ne décrit pas.
  • status fait partie des quatre valeurs autorisées ; toute autre valeur est ramenée à todo.
  • color est un hexadécimal #rrggbb valide.

Un fichier invalide n'est jamais réparé en silence : le chargement échoue avec un message qui pointe le projet et la phase fautifs, pour que le fichier puisse être corrigé à la main.

Dates : conventions

Les dates sont manipulées comme des chaînes AAAA-MM-JJ, pas comme des objets Date. Cela évite tous les pièges de fuseau horaire : new Date("2026-08-01") est interprétée en UTC alors que new Date(2026, 7, 1) l'est en heure locale, ce qui décale d'un jour selon le fuseau. Les conversions n'ont lieu que dans les helpers de calcul de model.js.

end est incluse : une phase du 2026-08-01 au 2026-08-01 dure un jour.

Tout se compte en jours calendaires, week-ends et jours fériés compris.

Les numéros de semaine affichés dans l'en-tête suivent l'ISO 8601 : la semaine appartient à l'année où tombe son jeudi. semaineISO() renvoie donc le numéro et l'année correspondante, qui peut différer de celle de la date.

Bornes et dérive

  • Les bornes d'un projet vont de la plus petite start à la plus grande end de ses phases. Un projet sans phase n'a pas de bornes et s'affiche comme un couloir vide.
  • Figer la référence copie, pour chaque phase du projet, ses start et end courantes dans son champ baseline, et inscrit la date du jour dans baselineDate. L'opération est rejouable : la refiger après un arbitrage assumé repart d'une base propre.
  • La dérive d'un projet est l'écart, en jours, entre la plus grande end actuelle et la plus grande end de référence. Elle est affichée arrondie en semaines. Une phase créée après le figeage n'a pas de baseline et ne compte pas dans la référence, mais compte dans les dates actuelles : ajouter une phase en fin de projet crée donc bien une dérive, ce qui est le comportement voulu.