Scaffold CLI Guidé¶
Intention¶
add-entity et add-usecase accélèrent le démarrage du cœur métier sans
inventer le métier. Les fichiers générés sont de courts repères modifiables :
- ils indiquent où placer champs, invariants, commandes, queries et résultats ;
- ils gardent le domaine indépendant des frameworks et des adapters ;
- ils utilisent les vrais chemins d'import du package détecté ;
- ils renvoient vers des exemples complets au lieu de les recopier dans chaque projet.
Le scaffold ne génère ni endpoint FastAPI, ni tool FastMCP, ni graphe LangGraph, ni mapping de base de données. Ces éléments viennent après le port inbound et le use case.
Commandes¶
Créer une entité guidée :
| Bash | |
|---|---|
Créer un use case lié à une entité détectée :
| Bash | |
|---|---|
Créer l'entité et le use case lié en une commande :
| Bash | |
|---|---|
Créer un use case transverse :
| Bash | |
|---|---|
Sans option, add-usecase propose les entités trouvées par analyse AST, puis
les choix « créer une nouvelle entité » et « transverse ». S'il n'existe aucune
entité, le wizard permet aussi d'annuler sans écriture. Pour les scripts, les
agents et la CI, toujours fournir l'une des trois options exclusives.
Position Hexagonale¶
| Emplacement | Responsabilité | Exemples |
|---|---|---|
domain/models |
état et invariants métier | Todo, TodoStatus |
domain/ports/inbound |
contrat offert aux entrées | CreateTodoCommand, CreateTodoPort |
domain/ports/outbound |
besoin du cœur envers l'extérieur | Repository[Todo], TodoLookupPort |
application/use_cases |
orchestration d'un objectif | CreateTodoUseCase |
adapters/inbound |
traduction HTTP, MCP, bus ou agent vers le port inbound | router, tool, handler, nœud |
adapters/outbound |
implémentation des dépendances externes | MongoDB, API distante, filesystem |
Un schéma de transport FastAPI ne devient pas automatiquement une commande du
domaine. L'adapter valide son contrat public puis construit le Command ou la
Query attendu par le port inbound.
Choisir Command, Query Et Result¶
- Une
Commanddemande une action ou une mutation : créer, terminer, importer. - Une
Querydemande une lecture sans intention de mutation : lister, rechercher, consulter. - Une entité peut être retournée directement lorsque c'est le résultat métier naturel d'une commande simple.
- Un
ResultPydantic explicite est préférable pour une pagination, un bilan d'import ou une réponse composée.
Le template lié utilise Command -> Entity comme point de départ fréquent. Le
template transverse utilise Command -> Result. Les exemples suivants montrent
comment les adapter vers Query ou vers un autre résultat.
Exemple 1 — CreateTodoUseCase¶
Le port inbound porte les données validées, sans dépendre du transport :
Le use case orchestre la création et dépend du port repository générique :
Exemple 2 — ListTodosUseCase¶
Une lecture paginée mérite une Query et un Result explicites :
Exemple 3 — CompleteTodoUseCase¶
Une mutation charge l'entité, vérifie la version attendue, applique l'invariant
dans le domaine, puis délègue l'audit et l'incrément de version au
UpdateUseCase générique Arclith.
| Python | |
|---|---|
complete() et les transitions autorisées appartiennent à Todo. La
conversion d'une exception en HTTP 404 ou 409 appartient à l'adapter FastAPI.
Le port Repository[T] partagé n'expose pas de compare-and-swap atomique entre
processus. Si cette garantie est requise, définir un port outbound métier et
une implémentation transactionnelle adaptée au store, sans gonfler le contrat
générique.
Exemple 4 — ImportCatalogUseCase Transverse¶
Un import coordonne plusieurs éléments et n'a pas nécessairement une entité
principale. Il dépend de ports outbound décrivant ses besoins, pas d'un
Repository[Any] artificiel.
Exemple 5 — FindByNameUseCase Et Port Outbound Spécifique¶
Ne pas ajouter find_by_name, find_overdue ou chaque requête métier au port
Repository[T] partagé. Lorsqu'une recherche exprime un besoin du domaine,
définir un petit port outbound dans le projet :
| Python | |
|---|---|
| Python | |
|---|---|
L'adapter MongoDB, PostgreSQL ou distant implémente ensuite TodoLookupPort.
Le contrat générique Repository[T] reste stable et centré sur le cycle de vie
des entités.
Tests Unitaires¶
Tester l'entité sans adapter pour prouver ses invariants :
| Python | |
|---|---|
Tester le use case avec un fake ou l'adapter memory :
Pour un port outbound spécifique, un fake minimal rend le test plus lisible qu'un mock d'un SDK MongoDB ou HTTP.
Validation Du Scaffold¶
Dans le dépôt Arclith :
| Bash | |
|---|---|
Dans le projet généré, compiler les fichiers puis écrire les tests métier avant de brancher les adapters :
Troubleshooting¶
Entité introuvable¶
--entity Todo ne se fie pas au seul nom de fichier. Le scanner AST doit
trouver une classe Todo qui hérite directement de Entity. Corriger la
classe ou utiliser --new-entity Todo si le fichier n'existe pas.
Fichier homonyme incompatible¶
--new-entity Todo refuse d'écraser domain/models/todo.py si ce fichier ne
déclare pas l'entité attendue. Renommer ou corriger manuellement le fichier,
puis relancer la commande.
Use case sans entité principale¶
Utiliser --no-entity. Le résultat ne contient pas de Repository[T] injecté ;
ajouter seulement les ports outbound réellement nécessaires à l'orchestration.