Politiques
Aujourd'hui, ce qui restreint une action s'écrit en gardes : les select guards d'une skill, et
le submit guard de la station. Core les applique quoi que dise le modèle. D'autres clés restreignent
aussi : depends_on et on_loss (un item d'une skill ne se choisit qu'une fois remplie la part
dont elle dépend), et les tâches du playbook ouvert : leur ordre (after), qui refuse un choix trop tôt, leurs choix
(one_of) et leurs conditions (when), qui refusent une méthode qui n'est pas la bonne, et les
tâches obligatoires, qui bloquent le submit. Il n'y a pas encore de
politiques réutilisables, de permissions, de budgets ni de politiques smart
(Politiques).
Les select guards : avant qu'un item entre dans la sélection
select:
max_items: 1 # un seul : en choisir un autre remplace le premier
guards: # une liste ordonnée ; chaque garde est UNE de ces quatre
- form: # ce que la PERSONNE remplit, dans la carte
address: {type: text, required: true, label: "Adresse de livraison"}
zone: {type: text, required: true, enum: [dakar, thies, rufisque]}
- name: zone-desservie # une condition qui doit tenir
require: "$item.fields.zone in ['dakar', 'thies']"
reason: "Nous ne livrons pas encore à Rufisque."
- check: checkDeliverable # le tenant dit si l'item est admissible
- update: {price: getDeliveryPrice} # le tenant calcule le prix pour CETTE demande
- {check: checkThiesRoute, when: "$item.fields.zone == 'thies'"}
| garde | fait | phase |
|---|---|---|
form | des valeurs que la personne donne ; elles deviennent les champs de l'item | 3 |
require | une condition qui doit tenir (voir Les conditions) | 3 |
check | l'opération du tenant dit si l'item est admissible | 5 |
update | l'opération du tenant fixe une valeur de l'item ; seul price existe | 6 |
Core les exécute par phase, et dans une phase dans l'ordre écrit : d'abord ce que la personne
répond et les conditions de la station, puis ce qui appelle le tenant. Le tenant n'est donc jamais
appelé pour un item déjà refusé. Un item refusé n'entre pas. La raison d'un check est celle du
tenant ; les valeurs que la personne a tapées y sont remplacées par le nom de leur champ.
- Au plus un
formet au plus unupdatedans la liste ; une garde qui nomme deux de ces quatre clés, ou aucune, refuse la station au chargement. max_itemsdit combien d'items la part de la skill peut tenir. Il est sur la skill seulement :kinds.<k>.selectne porte queguards({}veut dire « aucune garde »).- Chaque garde peut porter
when:: elle ne s'applique que si la condition tient. Unformdont lewhenest faux pour un item n'est pas demandé pour cet item. - Un
requireporte aussiname(le nom de son refus, unique dans la liste) etreason(la phrase que lisent la personne et l'agent). Sansreason:this choice does not meet the condition '<name>', outhis choice does not meet a condition of this offersansname.nameetreasonne s'écrivent que sur unrequire. - Un
requireseul n'est pas une étape de la carte : Core ajoute l'item, ou dit pourquoi non. Il ne fait pas de la ligne un choix unique et ne retire pas les boutons −/+ ; il s'exécute à chaque ajout.
Chaque champ du formulaire a un type, obligatoire, pris dans la table des types ;
un type hors de la table refuse la station au chargement, en nommant le champ. Ses autres clés :
required, label, placeholder, enum (une liste fermée de réponses) et identifies. Core
vérifie chaque réponse selon son type : un price attend un nombre, un quantity un nombre entier.
Les valeurs du formulaire deviennent les champs de l'item : $item.fields.address. Un champ marqué
identifies: true identifie aussi la room, qui ne le redemande plus (Auth).
nameUn champ name écrase le nom affiché de l'item : la ligne de livraison montrerait le nom du client
au lieu de « Demain 8h-12h ». Écrivez customer_name.
Les conditions : require et when
Une condition est un texte que Core lit lui-même, dans une grammaire fermée ; elle n'est jamais exécutée comme du code.
| écrire | sens |
|---|---|
==, !=, <, <=, >, >= | comparer |
in, not in | dans une liste ([...], exact), ou dans un texte (sans tenir compte des majuscules) |
and, or, not, ( ) | combiner |
5, 'texte' ou "texte", true, false, null, ['a', 'b'] | des valeurs |
$item.fields.<nom> | un champ de l'item : déclaré dans present.fields, ou demandé par le form de ce select |
$item.price, $item.price_cadence, $item.ref, $item.kind, $item.id | ce que l'item porte lui-même |
- Refusé au chargement : une faute de syntaxe ; toute autre référence (
$params…,identity…,$fields…, un champ non déclaré) ; une valeur seule (5,'oui'), qui n'est pas une condition ; plus de 500 caractères, 16 niveaux, 50 éléments de liste ou 18 chiffres. - Une condition lit un champ du formulaire seulement après la garde
formdans la liste, et lewhend'unformne lit pas ses propres champs. Seules les réponses aux champs du formulaire entrent dans l'item : une valeur sous un autre nom n'est pas gardée. - Pas de
$item.priceà côté d'unupdate: l'updatefixe le prix en dernier, une condition lirait le prix d'avant le devis. Pas de$item.quantity: une garde voit la quantité d'un ajout, pas celle de la ligne. - Les valeurs.
truen'est jamais un nombre. Un nombre écrit en texte est un nombre ("460" > 0).==et!=sont exacts :149et"149"diffèrent. Une valeur absente vautnull:!=etnot insont donc vrais pour une valeur absente ($item.fields.pays != 'US'admet un item sans pays ; écrivez$item.fields.pays != null and …pour l'exiger). - Ce qui ne peut pas être su. Une valeur absente ou illisible ne se compare pas avec
<,>… Alors Core ferme : unrequirequi n'est pas sûr de tenir refuse ; unwhenqui ne peut pas être su applique sa garde.
Le submit guard : une fois, avant tout
submit_guard:
form:
accept_terms: {type: boolean, required: true, label: "J'accepte les conditions générales"}
confirm: true # un oui explicite de la personne
Il s'applique à toute la sélection, avant la première opération. S'il échoue, rien n'est
exécuté. Core exige la confirmation de la personne à chaque submit, quelle que soit la porte, et que
confirm soit déclaré ou non.
Qui soumet
Le modèle ne peut pas soumettre : il faut la confirmation que Core remet à l'écran de la personne, jamais au modèle. Ce n'est pas une authentification : un script qui lit la room obtient cette confirmation comme le widget (voir Auth). Voir Le submit.