Référence de config/
Le format de chaque fichier YAML qui décrit le domaine.
Chaque fichier porte un name égal au nom du fichier (sans extension). Noms d’aspects et de champs en camelCase sans accents (dateReception), types, liens, vues et dashboards en kebab-case. Les libellés sont en français. Un fichier invalide est ignoré et signalé sur la page Définitions.
| Dossier | Contenu |
|---|---|
aspects/ |
jeux de champs typés |
types/ |
types de nœud et leurs aspects obligatoires |
links/ |
types de liens |
templates/ |
modèles de nœud |
views/ |
vues |
dashboards/ |
dashboards (l’accueil) |
reviews/ |
revues guidées |
captures/ |
syntaxe de la capture en une ligne |
connectors/ |
connecteurs : sources externes dont les éléments deviennent des nœuds |
Aspects
name: tache
label: Tâche
icon: task_alt # Material Symbols
version: 2 # à incrémenter lors d'un changement cassant
schema: # JSON Schema 2020-12, champs de premier niveau
type: object
required: [statut]
properties:
statut: { type: string, title: Statut, enum: [a-faire, en-cours, en-attente, plus-tard, fait, abandonne], default: a-faire }
echeance: { type: string, format: date, title: Échéance }
debut: { type: string, format: date, title: Début }
heure: { type: string, format: time, title: Heure } # heure locale HH:mm (ADR 0046)
recurrence: { type: string, format: recurrence, title: Récurrence } # règle RRULE (ADR 0046)
estimation: { type: integer, minimum: 0, title: Estimation (minutes) }
projet: { type: string, format: node-ref, title: Projet, x-target: { aspects: [projet] } }
ui:
order: [statut, echeance, debut, estimation, projet]
listColumns: [statut, echeance, projet]
workflow: # transitions autorisées (ADR 0023)
field: statut # champ requis à énumération
transitions:
a-faire: [en-cours, en-attente, plus-tard, fait, abandonne]
fait: [a-faire]
# … chaque état en clé ; [] = sans sortie
final: [fait, abandonne] # états terminés (ADR 0026)
enter: # effets de l'entrée dans un état (ADR 0065)
fait: { set: { termineLe: "{{today}}" } }
abandonne: { set: { termineLe: "{{today}}" }, require: [raisonAbandon] }
leave: # effets de la sortie d'un état
fait: { unset: [termineLe] }
abandonne: { unset: [termineLe, raisonAbandon] }
quickActions: # actions rapides (ADR 0025, 0041 ; ancien nom : postpone)
- { label: Demain, icon: today, set: { echeance: "{{today + 1d}}" } }
- { label: Terminée, when: "tache.statut != 'fait'", set: { statut: fait } } # when : langage des vues
- { label: Un jour peut-être, icon: snooze, set: { statut: plus-tard }, unset: [echeance] }
deferUntil: debut # masque le nœud des vues jusqu'à cette date (ADR 0039)
urgency: # score d'urgence (ADR 0064) : champ calculé tache.urgence des vues
field: urgence
label: Urgence
terms: # points ajoutés quand la condition (langage des vues) est vraie
- { when: "tache.echeance < today", points: 12 }
- { when: "tache.priorite == 'haute'", points: 6 }
- { when: "blocked", points: -5 }
recurrence: # tâches récurrentes (ADR 0046)
field: recurrence # champ format: recurrence qui porte la règle
date: echeance # champ date avancé d'une occurrence à l'autre
shift: [debut] # autres dates décalées d'autant
on: [fait] # états qui créent l'occurrence suivante
reset: { statut: a-faire } # valeurs de la nouvelle occurrence
link: occurrence-suivante # lien de l'occurrence terminée vers la suivante (une seule cible)
Annotations de champ :
| Clé | Rôle |
|---|---|
format: node-ref + x-target |
champ référence vers un nœud qui porte ces aspects / types (ADR 0005) |
x-default: "{{today}}" |
valeur par défaut dynamique (today, now, ± N d/w/m), exclusive de default (ADR 0017) |
title |
libellé du champ (colonnes, formulaires) |
x-sequence: archive |
sur un champ type: integer de premier niveau : le serveur lui donne le numéro suivant du compteur nommé quand il est absent à l’écriture (numéro de rangement, ADR 0050) ; exclusif de default et x-default |
format: time |
heure locale HH:mm (sans fuseau, contrairement au JSON Schema standard) |
format: recurrence |
règle de récurrence, sous-ensemble du RRULE : FREQ=DAILY|WEEKLY|MONTHLY|YEARLY, INTERVAL=N, BYDAY=MO,TH (semaines), BYMONTHDAY=5 ou -1 (mois), X-FROM=COMPLETION (à compter de la fin) |
Prochaine action (ADR 0037), sur l’aspect projet :
nextAction:
label: Prochaine action
field: prochaineAction # champ référence qui force le choix
from: tache.projet # tâches qui pointent vers le projet
states: [a-faire, en-cours]
sort: [tache.echeance asc, tache.priorite desc]
Effets des changements d’état
workflow.enter et workflow.leave associent à un état des effets sur les champs de l’aspect (ADR 0065). Chaque effet a trois clés, toutes facultatives :
| Clé | Rôle |
|---|---|
set |
champs écrits ; les variables {{today}} et {{now}} (avec décalage) sont résolues dans le fuseau du serveur |
unset |
champs retirés |
require |
champs à remplir (texte non blanc) ; à l’entrée seulement |
Quand l’état passe de A à B, les effets de sortie de A s’appliquent, puis ceux d’entrée dans B, avant la validation du schéma. Un champ que l’écriture change elle-même n’est ni écrit ni retiré : la saisie explicite l’emporte. Un champ require vide donne un refus 400 sur aspects.<aspect>.<champ>. Créer un nœud (ou ajouter l’aspect, ou changer de type) directement dans un état compte comme y entrer : les champs absents sont écrits, mais require n’est pas exigé.
Règles du chargeur (le fichier est ignoré et signalé sinon) :
- les états sont ceux de l’énumération, et les champs sont connus de l’aspect ;
- ni le champ d’état, ni un champ référence (
node-ref), ni un numéro attribué (x-sequence) ne peut être écrit ou retiré ; - un champ requis par le schéma n’est pas retiré, et un même champ n’est pas à la fois retiré et écrit ou requis ;
- les valeurs de
setsont conformes au schéma une fois les variables résolues ; requiren’est pas admis dansleave.
Une action rapide qui fait entrer dans un état doit aussi écrire les champs que cet état exige : elle ne passe pas par le dialogue de l’interface.
Types
name: facture-fournisseur
label: Facture fournisseur
icon: request_quote
mandatoryAspects: [document, facture, courrier]
suggestedAspects: [] # proposés, non imposés
Liens
name: bloque-par
label: Bloquée par
inverseLabel: Bloque
cardinality: many # one | many
blocking: true # la source attend la cible (ADR 0027)
source: { aspects: [tache] }
target: { aspects: [tache] } # aspects et / ou types admis
derivedFrom: # lien dérivé d'un champ référence (ADR 0033), jamais saisi
- { aspect: tache, field: projet }
Le nom wiki est réservé aux liens [[Titre]].
Modèles
name: facture-papier
label: Facture reçue par la poste
icon: local_post_office
type: facture-fournisseur
title: "Facture du {{today}}"
tags: [administratif]
aspects:
courrier: { canal: poste, dateReception: "{{today}}" }
facture: { echeance: "{{today + 30d}}" }
body: |
## Notes
Variables : {{today}} et {{now}}, avec décalage ± N d|w|m. Pas de champ référence dans un modèle.
Un modèle peut créer des enfants avec le nœud (ADR 0051) : trois niveaux et 50 enfants au plus. Dans un enfant, un champ référence peut valoir "{{root}}" (le nœud créé) ou "{{parent}}" (le nœud juste au-dessus) :
name: projet-renovation
label: Projet de rénovation
type: projet
title: "Rénovation : "
children:
- title: Demander trois devis
type: tache
aspects:
tache: { echeance: "{{today + 1w}}", projet: "{{root}}" }
- title: Choisir l'artisan
type: tache
aspects:
tache: { echeance: "{{today + 3w}}", projet: "{{root}}" }
children:
- { title: Signer le devis, type: tache, aspects: { tache: { projet: "{{root}}" } } }
Vues
name: maintenant
label: Maintenant
icon: bolt
folder: true # aussi dans l'arborescence, comme dossier intelligent (ADR 0058) ; pas pour une vue contextuelle
query:
aspects: [tache] # le nœud porte tous ces aspects
types: [tache] # l'un de ces types
tags: [maison] # tous ces tags, sous-tags compris
where: "(tache.statut == 'a-faire' || tache.statut == 'en-cours') && tache.estimation <= 15"
sort: [tache.priorite desc, tache.echeance asc] # 5 clés au plus, vides en dernier
limit: 200 # 1 à 1000
showDeferred: false # montrer les nœuds masqués par deferUntil
text: '"avant la pluie" -tondre' # recherche plein texte (ADR 0043), facultative
display:
mode: list # table | list | kanban
columns: [title, tache.estimation, tache.contexte, link:concerne-projet]
groupBy: tache.statut # enum, type, booléen ; hors kanban, une date se regroupe par jour
filters: [tache.contexte] # puces de filtre (enum, type, booléen)
swimlaneBy: tache.priorite # kanban : couloirs (valeurs fermées, ou référence comme tache.projet)
wip: { en-cours: 3 } # kanban : limite par colonne
styles: # mise en forme conditionnelle (ADR 0040)
- { when: "tache.echeance < today", style: danger, column: tache.echeance, label: En retard }
- { when: "blocked", style: muted, label: Bloquée } # danger | warn | success | muted | strong
context: # vue contextuelle (ADR 0036)
types: [projet]
Langage where : champs (title, type, parent, blocked, createdAt, updatedAt, unblockedAt, <aspect>.<champ>, et node pour le nœud courant d’une vue contextuelle), == != < <= > >=, && || !, parenthèses, 'texte', nombres, true, false, null, today et now ± N d|w|m. Un booléen absent vaut faux ; == et != traitent l’absence comme une valeur ; une comparaison d’ordre avec une valeur absente est fausse.
blocked est vrai quand une dépendance bloquante n’est pas terminée (même règle que la fiche) ; il ne sert ni au regroupement ni aux filtres. Une règle de styles met en forme la ligne, ou la seule cellule de column, quand when est vrai ; label dit son sens aux lecteurs d’écran et en infobulle.
Colonnes : title, type, tags, blocked, createdAt, updatedAt, <aspect>.<champ>, link:<type de lien>.
Dashboards
name: aujourdhui
label: Aujourd'hui
icon: today
default: true # accueil (le premier par nom)
widgets: # dans l'ordre ; width 1 (défaut) ou 2
- { kind: view, view: revue-retards, label: En retard, limit: 10, reschedule: tache.echeance }
- { kind: counter, view: factures-a-payer, label: Factures à payer }
- { kind: inbox, limit: 5 }
- { kind: templates, templates: [tache-semaine], label: Créer, width: 2 }
reschedule désigne un champ date d’aspect, réécrit à aujourd’hui ou demain par le bouton « Replanifier ».
Revues
name: hebdomadaire
label: Revue hebdomadaire
icon: fact_check
description: Videz l'inbox, rattrapez les retards…
steps:
- { label: Inbox, inbox: true, help: Classez chaque élément capturé. }
- { label: En retard, view: revue-retards, help: Replanifiez, terminez ou abandonnez. }
Chaque étape montre l’inbox ou une vue, avec un compteur et une aide.
Captures
name: tache
label: Tâche
default: true # syntaxe utilisée par la capture (la première par nom)
type: tache # type donné quand une date ou une marque est reconnue
date: tache.echeance # champ date d'aspect qui reçoit la date
time: tache.heure # champ format: time qui reçoit l'heure (« à 14 h »)
recurrence: tache.recurrence # champ format: recurrence qui reçoit la récurrence (« tous les lundis »)
markers: # préfixes « + », « ! », « @ », chacun une fois
- { prefix: "+", field: tache.projet } # champ référence (format: node-ref)
- { prefix: "!", field: tache.priorite, aliases: { "!": haute, h: haute } } # champ à énumération
- { prefix: "@", field: tache.contexte, aliases: { tel: telephone } }
# est réservé aux tags. Les alias mènent à des valeurs admises de l’énumération. Sans date, heure, récurrence ni marque reconnue, la capture entre dans l’inbox sans type (ADR 0042, 0046).
Connecteurs
Un connecteur reçoit les éléments d’une source externe et en fait des nœuds (ADR 0047). Seul le genre webhook existe : la source envoie un JSON, lu par des pointeurs (/titre, /fields/due).
name: capture
label: Webhook de capture
kind: webhook
secret: SB_WEBHOOK_CAPTURE # variable d'environnement qui contient le jeton ; absente : connecteur inactif
source: capture # valeur de externe.source ; par défaut, le nom du connecteur
type: tache # type du nœud créé ; sans type, il entre dans l'inbox
inbox: false # facultatif ; par défaut vrai sans type, faux avec
id: /id # identifiant chez la source (obligatoire dans chaque charge)
url: /lien
etag: /version # même version qu'à la dernière réception : rien n'est écrit
updatedAt: /modifieLe # date ISO avec fuseau ; sert aux conflits, l'heure de réception sinon
deleted: /supprime # booléen : le nœud est marqué, jamais supprimé
fields: # cible ← pointeur ; title obligatoire
title: /titre
body: /texte
tags: /tags # liste ou texte « a, b »
tache.echeance: /echeance # champ d'aspect, hors champ référence
L’identité externe est portée par l’aspect qui déclare la clé external (un seul, externe dans l’exemple) :
external: # champ de l'aspect qui porte chaque donnée (ADR 0047)
source: source
id: idExterne
url: url
etag: etag
syncedAt: synchroLe # date-heure
deletedAt: supprimeALaSource # date-heure
Le jeton n’est jamais dans config/ : seul le nom de la variable y figure. Le fonctionnement (conflits, suppressions, état) est décrit dans Connecteurs et webhook.