La commande make:public-form dans Forge¶
forge make:public-form génère un formulaire public d'enregistrement à partir d'une entité.
Le visiteur saisit des données qui sont insérées en base par du SQL visible.
Le code correspondant est dans cli/public/public_form.py.
1. Rôle¶
La commande lit la définition JSON validée d'une entité et en déduit un formulaire public.
Elle réalise trois actions :
- elle écrit un gabarit Jinja sous
mvc/views/public/<pluriel>/form.html; - elle écrit ou complète le contrôleur
mvc/controllers/public_<pluriel>_controller.pyavec deux méthodes :new(affichage du formulaire) etcreate(validation puis insertion) ; - elle déclare deux routes publiques :
GET /<pluriel>/newetPOST /<pluriel>.
Les champs de saisie et leur type d'input HTML sont déduits de la définition de l'entité (type SQL, type Python, nom du champ).
Les champs sensibles sont exclus du formulaire public : id, password, password_hash, token, secret, is_admin, is_active, les horodatages, ainsi que tout champ contenant password, token, secret ou _hash.
Les clés primaires, les clés étrangères (*_id), les types non simples et les colonnes binaires ou JSON sont également écartés.
La méthode create générée valide les champs requis, puis insère en base avec un INSERT paramétré (SQL visible dans le contrôleur, principe 5).
Le SQL utilise des placeholders ? et passe les valeurs séparément, ce qui protège contre l'injection SQL.
Forge ne réécrit jamais un fichier utilisateur en silence (principe 9).
Le gabarit suit le mode write-if-new ; le contrôleur et les routes sont complétés par insertion.
2. Vue d'ensemble rapide¶
| Élément | Valeur |
|---|---|
| Commande forge | forge make:public-form <Entite> |
| Module Python | cli.public.public_form |
| Catégorie | génération de pages publiques (CLI) |
| Rôle | générer un formulaire public d'enregistrement pour une entité |
| Entrées | un nom d'entité ; la définition JSON validée mvc/entities/<snake>/<snake>.json |
| Sorties | un gabarit de formulaire, un contrôleur avec new et create, deux routes |
| Fichiers touchés | mvc/views/public/<pluriel>/form.html, mvc/controllers/public_<pluriel>_controller.py, mvc/routes/__init__.py |
| Mode Forge | lit la définition d'entité, génère (write-if-new pour le gabarit), complète par insertion |
| ADR | ADR-013 (nullable / required), ADR-029 (convention de routes) |
3. Schémas UML¶
3.1 Diagramme de classe¶
Le diagramme montre les structures déduites de l'entité.
classDiagram
direction LR
class PublicFormField {
+str name
+str column
+str label
+str input_type
+bool required
+str python_type
}
class PublicFormSpec {
+str entity
+str plural
+str table
+str class_name
+str route_path
+str template_name
+list fields
}
class MakePublicFormResult {
+PublicFormSpec spec
+list created
+list preserved
+list warnings
}
PublicFormSpec --> PublicFormField : contient 0..*
MakePublicFormResult --> PublicFormSpec : décrit
À retenir :
public_form_fields(definition)produit la liste desPublicFormFieldpublics, après filtrage des champs sensibles ;build_public_form_spec(definition)assemble laPublicFormSpec(table, classe, routes, gabarit) ;MakePublicFormResultcollecte les fichiers créés, préservés et les avertissements.
3.2 Diagramme de séquence¶
Le diagramme montre le déroulé d'un appel à forge make:public-form puis la soumission du formulaire par un visiteur.
sequenceDiagram
actor Dev as Développeur
participant Forge as forge CLI
participant Cmd as make_public_form
participant FS as Système de fichiers
actor Visiteur
Dev->>Forge: forge make:public-form Article
Forge->>Cmd: main(["Article"])
Cmd->>FS: lit mvc/entities/article/article.json
Cmd->>Cmd: build_public_form_spec(definition)
Cmd->>FS: écrit form.html si absent
Cmd->>FS: insère new et create dans le contrôleur
Cmd->>FS: insère les routes GET .../new et POST ...
Cmd-->>Dev: affiche créés, préservés, avertissements
Visiteur->>Forge: GET /articles/new
Visiteur->>Forge: POST /articles (champs)
Forge->>FS: INSERT paramétré en base
À retenir :
- la définition d'entité est lue puis validée avant toute génération ;
- la méthode
createvalide les champs requis avant d'insérer ; - l'insertion utilise un
INSERTparamétré (placeholders?).
4. API publique / Commande¶
Invocation :
La commande attend exactement un argument ; sinon elle affiche Usage : forge make:public-form <Entite>.
Si l'entité est introuvable ou si son JSON est invalide, la commande affiche l'erreur et sort avec le code 1.
| Symbole | Signature | Rôle |
|---|---|---|
public_form_fields |
public_form_fields(definition: dict[str, Any]) -> list[PublicFormField] |
champs de saisie publics d'une entité |
build_public_form_spec |
build_public_form_spec(definition: dict[str, Any]) -> PublicFormSpec |
construit la spécification du formulaire |
build_public_form_new_method |
build_public_form_new_method(spec: PublicFormSpec) -> str |
produit la méthode new (affichage) |
build_public_form_create_method |
build_public_form_create_method(spec: PublicFormSpec) -> str |
produit la méthode create (validation et insertion) |
make_public_form |
make_public_form(entity_name: str, *, entities_root: Path \| None = None, output_root: Path \| None = None) -> MakePublicFormResult |
exécute la génération complète |
main |
main(args: list[str], *, root: Path \| None = None) -> MakePublicFormResult |
point d'entrée de forge make:public-form |
PublicFormField / PublicFormSpec / MakePublicFormResult |
dataclasses | champ, spécification et résultat |
5. Contextes d'utilisation¶
| Besoin | Commande / Élément |
|---|---|
| Recueillir des données depuis un visiteur (inscription, dépôt) | forge make:public-form |
| Ne jamais exposer les champs sensibles | filtrage automatique dans public_form_fields |
| Lister les champs publics d'une entité | public_form_fields(definition) |
| Récupérer la table et les routes déduites | build_public_form_spec(definition) |
6. Exemples d'utilisation¶
Générer un formulaire public pour l'entité Article :
Sortie typique :
Formulaire public généré : Article
Routes : GET /articles/new POST /articles
Template : mvc/views/public/articles/form.html
Contrôleur : mvc/controllers/public_articles_controller.py
Appel direct depuis du code Python :
from cli.public.public_form import make_public_form
result = make_public_form("Article")
for f in result.spec.fields:
print(f.name, f.input_type, f.required)
7. Sécurité et limites¶
Champs sensibles exclus
Les champs sensibles ne figurent jamais dans le formulaire public : identifiants, mots de passe, jetons, secrets, indicateurs d'administration, horodatages.
Les clés primaires, les clés étrangères (*_id) et les colonnes binaires ou JSON sont aussi écartées.
SQL visible et paramétré
L'INSERT généré reste lisible dans le contrôleur (principe 5).
Il utilise des placeholders ? et passe les valeurs séparément : aucune interpolation de chaîne dans la requête.
Entité sans champ public
Si aucun champ public n'est détecté, la commande génère quand même les fichiers mais émet l'avertissement « Aucun champ public affichable détecté ».
Voir aussi¶
- La commande make:public-page : page statique de base réutilisée.
- La commande make:public-contact : page de contact spécialisée.
- La commande make:public-list : liste publique paginée.
- La commande make:public-show : fiche détaillée publique.