Second Brain documentation

ADR 0109 – Archiver un projet

Accepté (2026-10-17, vague 3 du document d'idées)

← Toutes les décisions

ADR 0109 – Archiver un projet

Statut : Accepté (2026-10-17, vague 3 du document d’idées)

Un projet terminé encombre l’arbre et les vues, mais le mettre à la corbeille dit « à supprimer ». Il faut un état intermédiaire : « rangé », hors de vue, mais retrouvable.

Décision

État « archivé » : la colonne node.archived_at

La colonne existait depuis V1__init.sql sans être utilisée : aucune migration. Un nœud archivé garde son parent, ses aspects, ses liens et ses fichiers ; il n’est pas dans la corbeille (deleted_at reste nul).

  • Propagation : archiver un nœud archive aussi ses descendants hors corbeille qui ne l’étaient pas, avec la même date (now() d’une seule requête récursive). Ainsi les requêtes de l’arbre et des vues n’ont qu’une condition archived_at is null, sans remonter la hiérarchie.
  • Désarchiver remet le nœud et les descendants archivés avec la même date : ceux rangés à part, avant ou après, restent archivés. Un nœud archivé avec un ancêtre archivé se désarchive par cet ancêtre (409 sinon, avec le titre de l’ancêtre).
  • Idempotent dans les deux sens : déjà archivé, rien ne change (et pas de jeton d’annulation).
  • Rattachés par un champ : les tâches d’un projet ne sont pas ses enfants dans l’arbre, elles le désignent par tache.projet. La clé d’aspect archiveWith: [tache.projet] de config/aspects/projet.yaml (champs référence, contrôlés au chargement) fait suivre l’archivage aux nœuds dont ce champ désigne un nœud archivé, et à leurs propres enfants. Même date, donc même désarchivage. Sans la clé, seule la hiérarchie compte.
  • Générique : n’importe quel nœud peut être archivé ; aucun nom d’aspect, de statut ni de type dans le code. Le choix de quoi archiver (un projet terminé) est celui de l’utilisateur ; une action rapide ou un effet d’état pourra l’automatiser plus tard.

Ce que l’archivage masque, et ce qu’il laisse

Surface Archivé
Arbre (enfants, racines, nombre d’enfants) masqué
Vues, dashboards, compteurs (ViewRepository.fetch/count) masqué
Santé d’un projet (ADR 0108) les tâches archivées ne comptent plus
Progression des enfants (ADR 0026), prochaine action (ADR 0037) les archivés ne comptent plus et ne sont plus proposés
Recherche simple GET /api/nodes, /count masqué, sauf avec q : la recherche par texte les retrouve (archived: true dans le résultat, « archivé » dans la palette et la liste)
archived=true seulement les archives ; sans q, seulement les racines d’archivage (ni les enfants d’un archivé, ni les nœuds archivés en même temps que celui que désigne leur champ archiveWith)
Liens, rétroliens, mentions, fiche, journal inchangés (le nœud reste lisible et référençable)
Export, sauvegarde inchangés

Journal

Chaque nœud touché reçoit un node_event dans la même transaction : node.archived / node.unarchived, avec descendants (nombre) sur le nœud choisi et with (id de ce nœud) sur les descendants. Ces événements ne sont pas des modifications locales pour les connecteurs (ADR 0047) : archiver une tâche synchronisée ne bloque pas la version suivante.

API

Pas de route dédiée : deux opérations de l’API des lots (ADR 0041), ARCHIVE et UNARCHIVE, donc l’« Annuler » de l’ADR 0049 (l’annulation d’un archivage désarchive, et inversement). Nouveau paramètre archived de la recherche, archivedAt dans NodeView, archived dans NodeSummary.

Interface

  • Fiche : bouton « Archiver » (« Désarchiver » si archivée) avec « Annuler » ; bandeau « Archivé le … » avec « Désarchiver ». La fiche reste ouverte.
  • Section « Archives » (/archives) : menu de l’arborescence et commande de palette « Aller à : Archives ». Racines d’archivage, filtre par texte, « Désarchiver » avec « Annuler ».

Alternatives écartées

  • Statut « archivé » dans l’aspect projet : lie la fonctionnalité à un aspect (contraire à la règle « le domaine vit dans config/ ») et ne masque ni les enfants ni les autres nœuds.
  • Masquer par ancêtre à la lecture (CTE récursive dans chaque requête d’arbre et de vue) : coûteux partout et fragile ; la propagation à l’écriture la remplace par une condition triviale.
  • Réutiliser la corbeille : « supprimer » et « ranger » n’ont pas le même sens ; la corbeille se purge.
  • Tag archive : visible comme n’importe quel tag, filtrable par erreur, pas masqué de l’arbre.

Limites connues

  • Un nœud créé ou déplacé sous un parent archivé n’est pas archivé : il reste invisible dans l’arbre (son parent l’est) mais apparaît dans les vues.
  • Une tâche rattachée à un projet après son archivage n’est pas archivée (comme un enfant créé après).
  • La section « Archives » n’a pas de pagination au-delà de 200 résultats : on affine par texte.