create-cmpnnt
Compétence pour créer un nouveau composant (cmpnnt) — commande, procédure, sous-commande, Yew-composant
ou crate entier — dans le style littéraire org-babel documenté dans ~/.claude/CLAUDE.md. Basé
sur les fichiers réels de code/ads-back (crates/api/create-card.org, crates/api/retrve-card.org,
crates/cli/main.org, crates/svc/main.org, config.org racine, env.org).
Étape 0 — détermination du variant
Par défaut (sans arguments explicites), détermine le variant à partir de la demande de l'utilisateur ;
en cas d'ambiguïté — pose une question de clarification via AskUserQuestion, ne devine pas en silence :
- A. Procédure/commande dans un crate existant — cas typique (ex. nouveau handler
rocketdanscrates/api, nouvelle fonction de bibliothèque danscrates/db). Un nouveau fichier org, sans modification deconfig.org. - B. Sous-commande d'une
CLIexistante — nouveau fichier<sous-commande>.org(mod) + insertion dans lemain.orgexistant de ce crate (mod,Command:Éléments,Variantes). - C. Composant
Yew(ads-front) — structure proche decrates/app/marker.org: section "Propriétés" avec les propriétés du composant, blocsHtml. Même squelette (Déclarations avant Définition, un titre par concept), autre terminologie des blocs. - D. Nouveau crate ("fédéré
cargo") — lorsque le composant ne rentre logiquement dans aucun crate existant. Alors, en plus du composant lui-même, il fautconfig.org,env.org,main.orgdu nouveau crate et l'enregistrement dans leconfig.orgracine (voir Étape 4).
N'attribue pas le variant D "au cas où" — seulement quand l'utilisateur demande explicitement un nouveau crate, ou quand aucun crate existant ne convient logiquement (et que cela est confirmé par l'utilisateur).
Étape 1 — langue du fichier org
La langue dépend de la situation, non fixée à l'avance. Avant de créer le fichier, regarde la langue des
fichiers org voisins dans le répertoire cible (code/ads-back/env.org — en anglais, la plupart des
crates/api/*.org — en ukrainien) : si le répertoire a une majorité claire — écris dans la même langue ;
si c'est un nouveau répertoire ou si la langue des voisins est ambiguë — demande à l'utilisateur en une
question, ne devine pas.
Étape 2 — squelette commun (tous les variants)
Quel que soit le variant, chaque nouveau fichier org avec sa propre cible :tangle :
-
#+title: ...— nom du composant (dans la langue de l'étape 1). -
Si nécessaire — paragraphe avec un lien vers la spécification (
[[https://...][spécification]]), comme danscreate-card.org. -
Premier titre (
* Module/* Fichier/* Crate— nom selon l'exemple des fichiers voisins du même répertoire, ce n'est pas strictement fixé) avec un bloc squelette :#+begin_src rust :noweb yes :mkdirp yes :tangle src/NOM_DU_FICHIER.rs <<Déclarations>> <<Définitions>> #+end_src -
Immédiatement après le squelette — section
* Exécuteur(pour procédure/commande) avec deux blocs ::noweb-ref Déclarations(imports, y compris les typesRequest/Responsedeads_api) et:noweb-ref Définitions(la fonction elle-mêmepub fn run(...), dont le corps est principalement<<Actions>>à l'intérieur dedb::cnnctn().transaction(...), si une transaction est nécessaire). -
Chaque petit élément de logique suivant (vérification, obtention d'un champ, insertion dans une table, etc.) — titre séparé
*/**avec ses propres:noweb-ref Déclarations(si de nouveauxusesont nécessaires) et:noweb-ref Actions— dans cet ordre (déclaration avant utilisation, comme partout ailleurs). Ne regroupe pas toute la logique dans un seul bloc — chaque étape significative doit avoir son propre titre, comme danscreate-card.org(15+ titres séparés pour une seule procédure). -
Si une étape engendre une fonction auxiliaire (ex.
upsert_phonedanscreate-card.org) — propre:noweb-ref Définitionspour la signature de la fonction, et le corps via unnoweb-refnommé (upsert-phone:Actions), et des sous-titres**/***pour chaque action à l'intérieur.
Le variant B (sous-commande CLI) diffère en ce qu'il n'y aura pas de nouveau bloc squelette — à la
place, ajoute dans le main.org existant trois blocs noweb sans nouveau titre-squelette :
:noweb-ref Déclarations (mod nouvelle_sous_commande;), :noweb-sep ",\n" :noweb-ref Command:Éléments
(variant enum Command avec champs-arguments), et
:noweb yes :noweb-sep ",\n" :noweb-ref Variantes (Command::Variant { ... } => crate::module::run(...)) —
chacun dans son propre titre *, nommé par l'action (ex. * Création d'organisation), et l'implémentation
elle-même dans un nouveau fichier org de sous-commande séparé selon le squelette commun (étape 2, variant A).
Le variant C (composant Yew) diffère par les noms des sections : au lieu d'"Exécuteur" — section
"Propriétés" (struct ...Props, une propriété = un sous-titre **, :noweb-sep ",\n" :noweb-ref NomProps:Propriétés), et section "Composant" (#[function_component(...)], corps —
<<Nom:État>>, <<Nom:Effets>>, <<Nom:Gestionnaires>>, html! { <<Nom:Html>> }). Regarde
code/ads-front/crates/app/marker.org comme exemple vivant de ce variant.
Étape 3 — fonction main typique (variant D, d'abord)
La première version de main.org d'un nouveau crate doit être la plus simple possible — sans gestion
d'erreurs, sans Result, sans async, sans initialisation du logger/env, tant qu'il n'y a pas de
besoin spécifique :
#+title: NOM DU CRATE
* Fichier
#+begin_src rust :noweb yes :mkdirp yes :tangle src/main.rs
<<Déclarations>>
<<Définitions>>
fn main() {
<<Actions>>
}
#+end_src
<<Actions>> peut d'abord être complètement vide (le nouveau crate ne fait encore rien) — c'est une
première étape normale, les titres suivants le remplissent progressivement, comme dans
crates/cli/main.org/crates/svc/main.org. La gestion d'erreurs (Result, ?), async,
l'initialisation de dotenv/env_logger etc. doivent être ajoutés par des titres séparés plus tard,
quand l'étape spécifique le nécessite vraiment — pas à l'avance.
Étape 4 — nouveau crate : config.org et enregistrement dans le config.org fédéré
-
crates/NOM/config.org— fichier du crate (voircrates/cli/config.orgcomme exemple) :#+title: Fichier =Cargo= * Fichier #+begin_src toml :noweb yes :tangle Cargo.toml [package] name = "NOM" version = "0.1.0" edition = "2021" [dependencies] <<Dépendances>> #+end_srcChaque dépendance — titre
* =nom_du_crate=séparé avec:noweb-ref Dépendances(nom = { workspace = true }), ordonné selon la règle deCLAUDE.md(tiers →forge→ crates du projet, sinon — alphabétique). Les blocs* Version =Rust=/* Configuration locale(rust-toolchain.toml/.cargo/config.toml) sont copiés duconfig.orgvoisin uniquement si c'est déjà la pratique dans ce répertoire — ne les ajoute pas "au cas où" si aucun crate voisin ne le fait. Si tu copies, le fichier devient multi-cible (plusieurs:tangledifférents), donc tous les blocs noweb (y comprisDépendances) passent à des noms préfixés (Cargo:Dépendances,config:Définitionsetc., voir CLAUDE.md) — comme dans leconfig.orgracine ci-dessous. -
Dans le
config.orgRACINE (workspace), ajoute un nouveau titre* =NOM=avec deux blocs — selon le modèle des sections* =db=/* =api=à la racine :#+begin_src toml :noweb-sep ",\n" :noweb-ref Cargo:Crates "crates/NOM" #+end_src #+begin_src toml :noweb-ref Cargo:Dépendances NOM = { path = "crates/NOM" } #+end_src -
env.org— si le nouveau crate n'introduit pas ses propres variables d'environnement, ne touche à rien. S'il en introduit — et qu'il existe déjà unenv.orgracine commun dans le projet — ajoute une nouvelle section*avec son propre:noweb-ref(comme* Accès base de données/* Paramètres =JWT=), plutôt que de créer un fichier séparé. Crée unenv.orgSÉPARÉ pour le nouveau crate uniquement lorsqu'il s'agit d'un déploiement indépendant (son propre.env, pas le même processus) et qu'aucunenv.orgcommun n'existe. Dans tous les cas, le premierenv.orgpeut rester complètement sans variables spécifiques (peut être sans valeurs, juste le fichier principal) — juste un squelette :#+title: Fichier =dotenv= * Fichier de configuration #+begin_src conf :noweb yes :tangle .env.example <<Définitions>> #+end_srcet le remplir avec des sections
* =X= parametersspécifiques plus tard, quand les vraies variables apparaissent.
Étape 5 — vérification après chaque modification
Après chaque modification significative de la source org :
Tangleréel viaemacsclient --eval(n'écris jamais le contenu des fichiers.rs/.toml/.env.examplemanuellement — voir la règle globale correspondante).cargo check -p CRATE(ajoute--target wasm32-unknown-unknownpourads-front) — zéro avertissement et erreur.- Exécute la compétence
org-lintsur le fichier modifié et corrige immédiatement les résultats "CERTAINS", examine les "nécessite vérification". - Pour la prose fraîchement écrite/modifiée —
(font-lock-ensure)+org-fill-paragraphvia le mêmeemacsclient, pas manuellement.
Ne présente pas le composant comme prêt à l'utilisateur tant que ces quatre points n'ont pas été passés pour chaque fichier org nouveau ou modifié.