Blueprint CRUD¶
Le blueprint crud initialise le cycle de vie applicatif classique d'une
entité : create, get, list, update et delete. Il compose les primitives
déjà fournies par Arclith, mais laisse les champs, invariants, autorisations et
politiques métier au projet généré.
Créer La Feature¶
En une commande avec l'entité :
| Bash | |
|---|---|
Ou sur une entité existante :
| Bash | |
|---|---|
Prévisualiser avant d'écrire :
| Bash | |
|---|---|
Fichiers Créés¶
Pour le package todo_service, la feature todo produit :
Le document créé dans le projet est local à la feature. Il rappelle les points à personnaliser avant d'exposer un contrat public.
Contrat Des Opérations¶
| Opération | Entrée | Résultat | Comportement initial |
|---|---|---|---|
create |
CreateTodoCommand |
CreateTodoResult |
construit l'entité puis utilise BaseService.create |
get |
GetTodoQuery |
GetTodoResult |
retourne l'entité active ou lève TodoNotFoundError |
list |
ListTodoQuery |
ListTodoResult |
pagination par offset et limit, avec total |
update |
UpdateTodoCommand |
UpdateTodoResult |
vérifie la version attendue puis délègue l'incrément |
delete |
DeleteTodoCommand |
DeleteTodoResult |
applique la politique de soft delete configurée |
duplicate et purge existent dans les primitives génériques d'Arclith mais
ne font pas partie du CRUD. Ils doivent être ajoutés comme cas d'usage explicites
si le métier en a besoin.
Champs Métier Et Validation¶
Lorsque le blueprint est appliqué à une entité existante, il copie ses champs
métier déclaratifs dans CreateTodoCommand. Les types, contraintes Field,
aliases et valeurs par défaut Pydantic sont conservés pour la création. Les
champs modifiables sont aussi projetés dans UpdateTodoCommand, où chacun
devient optionnel en présence : un champ absent n'est pas modifié, tandis
qu'une valeur fournie reste soumise aux mêmes contraintes. Un champ Final
requis est réservé à la création et n'est jamais ajouté à la commande de mise à
jour. Les champs techniques
d'Entity (uuid, audit, soft delete et version) ne sont jamais copiés comme
des données métier modifiables.
Les aliases explicites définis avec Field(alias=...) ou
Field(validation_alias=...) sont conservés, à condition d'être exprimés par
des chaînes littérales, AliasPath ou AliasChoices, et de ne pas réutiliser
les clés techniques uuid ou version de la commande de mise à jour. Une
configuration globale model_config.alias_generator, y compris déclarée comme
paramètre de la classe Pydantic, n'est pas projetée. La
CLI refuse aussi une configuration assemblée indirectement (**CONFIG) dont
elle ne peut pas exclure statiquement la présence d'un générateur, ainsi qu'une
configuration déclarée dans un bloc conditionnel de classe. De même, les
options dynamiques Field(**OPTIONS), les constructeurs bas niveau
FieldInfo(...) et les métadonnées Pydantic encapsulées dans une constante, un
helper ou un alias de type réutilisable doivent être développés directement sur
le champ avec Field(...). Une métadonnée Annotated importée depuis un paquet
extérieur au projet est également refusée : la CLI ne peut pas l'inspecter sans
exécuter ce paquet. La même règle s'applique aux valeurs par défaut et annotations
issues d'un paquet tiers non inspectable ; les types sûrs de la bibliothèque
standard, de Pydantic et d'Arclith restent acceptés. La CLI interrompt la
génération avant toute écriture lorsqu'elle ne peut pas prouver que le contrat
projeté est équivalent. Elle
demande alors de déclarer les aliases d'entrée sur chaque champ afin que le
contrat public reste statique et vérifiable.
Le parcours recommandé pour une entité concrète est donc :
arclith-cli add-entity Todo --profile minimal;- déclarer les champs et invariants de
Todo; arclith-cli add-blueprint crud --entity Todo;- installer puis projeter le transport choisi.
Le raccourci add-entity Todo --profile crud reste valide pour démarrer avec
les seuls champs techniques. Comme tous les fichiers du blueprint deviennent
ensuite propriété du projet, les champs ajoutés au modèle après cette commande
doivent être reportés explicitement dans les commandes applicatives ; une
relance ne les écrase pas silencieusement.
Les erreurs TodoNotFoundError et TodoVersionConflictError sont des erreurs
applicatives. La projection FastAPI les traduit respectivement en 404 et
409; cette traduction reste dans l'adapter et n'appartient pas aux use cases.
Le contrôle de version généré évite une mise à jour manifestement obsolète dans
le processus courant. Le port Repository[T] générique ne garantit pas à lui
seul un compare-and-swap atomique entre plusieurs processus. Si le métier exige
cette garantie, définir un port outbound spécialisé et l'implémenter avec une
transaction adaptée à MongoDB ou PostgreSQL.
Choisir Les Adapters Ensuite¶
La feature est immédiatement testable avec le repository mémoire configuré par défaut. Les choix techniques restent séparés :
expose-feature exige que l'adapter FastAPI soit déjà installé. La commande ne
crée ni adapter ni persistence et consomme le manifeste canonique
.arclith/features/todo.yaml sans déduire le CRUD depuis les noms de fichiers.
Elle planifie les cinq bindings ensemble avant la première écriture : une
collision sur une seule opération rejette donc toute la projection.
Sans --path, le chemin déterministe utilise la feature en kebab-case :
todo devient /v1/todo et shopping_item devient /v1/shopping-item. La CLI
ne pluralise pas un nom métier ; fournir --path /v1/todos rend le contrat
public explicite.
Contrat FastAPI Généré¶
| Méthode | Chemin | Succès | Erreurs applicatives |
|---|---|---|---|
POST |
/v1/todos |
201 + CreateTodoResponse |
validation 422 |
GET |
/v1/todos/{uuid} |
200 + GetTodoResponse |
404, validation 422 |
GET |
/v1/todos?offset=0&limit=100 |
200 + ListTodoResponse |
validation 422 |
PATCH |
/v1/todos/{uuid} |
200 + UpdateTodoResponse |
404, 409, validation 422 |
DELETE |
/v1/todos/{uuid} |
200 + DeleteTodoResponse |
404, validation 422 |
Le paramètre uuid est extrait du chemin et réinjecté par le mapper dans la
Command ou Query applicative ; il n'est pas dupliqué dans le body ou la query
string. PATCH et DELETE répondent avec un body typé, donc utilisent 200
plutôt que 204. Changer cette convention exige de versionner explicitement le
contrat et son presenter.
Les contrats et routes sont créés une fois puis deviennent propriété du projet.
Les registres, le composition root et le manifeste de bindings restent générés.
Une relance préserve les personnalisations et n'ajoute pas une seconde étape de
recette. Utiliser --dry-run pour revoir tout le plan sans écriture.
FastAPI est la seule projection de feature fournie dans cette version. Les projections MCP, RabbitMQ ou LangGraph restent des décisions séparées à concevoir selon leur sémantique propre ; elles ne doivent pas recopier mécaniquement REST.