Soumissions de formulaire
Chaque soumission de formulaire produit un enregistrement durable. Par défaut, elle atterrit dans le registre intégré form_submissions — le journal canonique de la plateforme « ce formulaire a reçu une réponse » — et, lorsque submitTo.table est défini, dans votre propre table également. Les deux écritures sont transactionnelles, vous ne vous retrouvez donc jamais avec une entrée de registre promettant un enregistrement qui n'a jamais été écrit. Après la validation des écritures, onSuccess décide ce que le contributeur voit et onError couvre les échecs.
forms:
- id: 1
name: contact
submitTo:
table: leads
# storeSubmission defaults to true — table AND ledger
fields:
- { kind: table-field, column: email, required: true }
onSuccess:
type: toast
variant: success
message: Thanks! We'll be in touch.
Le registre de soumissions
Le registre form_submissions réside dans un schéma interne géré par Sovrium (reflétant l'isolation de auth.*) — vous ne le créez ni ne le gérez jamais vous-même. Chaque soumission écrit une ligne de registre par défaut ; définissez submitTo.storeSubmission: false pour vous désinscrire (auquel cas table ou automation devient obligatoire).
| Colonne | Type | Description |
|---|---|---|
id |
UUID | Id de soumission stable ; exposé aux modèles onSuccess via $submission.id. |
form_name |
text | Le forms[].name au moment de la soumission. |
form_id |
integer | Le forms[].id au moment de la soumission (dénormalisé pour les jointures). |
submitted_at |
timestamptz | Horodatage serveur de la création de la ligne. |
submitter_user_id |
UUID, nullable | L'utilisateur authentifié, lorsque le formulaire requiert l'authentification. |
submitter_ip |
inet, nullable | IP du contributeur (stockée hachée par défaut) — utilisée par l'anti-spam et l'audit. |
submitter_user_agent |
text, nullable | Chaîne user-agent du contributeur. |
data |
jsonb | La charge utile complète de réponse validée (reflète ce qui a été écrit dans submitTo.table). |
linked_record_table |
text, nullable | Le nom de la table liée, lorsque submitTo.table est défini. |
linked_record_id |
text, nullable | L'id de l'enregistrement inséré (typé text pour gérer les id integer / UUID / string). |
status |
enum | État du cycle de vie (voir ci-dessous). |
status_reason |
text, nullable | Brève raison lorsque status vaut failed ou spam. |
Statut du cycle de vie
| État | Signification | Transitions vers |
|---|---|---|
received |
Accepté ; écrit dans le registre et la table liée (le cas échéant). | processing (si automatisation), done (sinon). |
processing |
L'automatisation liée s'exécute. | done en cas de succès, failed en cas d'échec terminal. |
done |
Terminal — toutes les écritures et l'automatisation liée sont achevées. | — |
spam |
Terminal — le pipeline anti-spam l'a classé comme spam ; conservé pour modération. | — |
failed |
Terminal — une étape en aval a échoué et n'a pas été réessayée ; status_reason est défini. |
— |
Le contrat d'écriture double
Lorsque submitTo.table est défini, la soumission écrit une ligne dans cette table et une ligne de registre au sein d'une seule transaction. Si l'écriture dans la table échoue — violation de contrainte, erreur de type ou clé étrangère manquante — la ligne de registre est annulée elle aussi, et le contributeur reçoit une erreur HTTP 4xx/5xx avec fieldErrors:[{ name, message }] nommant la colonne fautive. Aucune entrée de registre « fantôme » n'est jamais laissée derrière.
Lorsque submitTo.automation est défini, l'automatisation est invoquée après la validation des deux écritures. Un échec d'automatisation n'annule pas les écritures — la soumission est enregistrée, status passe à failed, et la propre machinerie de réessai/échec de l'automatisation s'applique.
forms:
- id: 2
name: stream-event
submitTo:
automation: post-event-to-stream
storeSubmission: false # opt out — ledger is skipped; automation handles persistence
fields:
- { kind: standalone, name: event_payload, inputType: long-text }
Ne contournez le registre que lorsque vous le voulez vraiment. storeSubmission: false est le seul moyen de sauter le registre et est destiné aux formulaires à très haut volume qui acheminent vers un flux ou une file d'attente. Chaque fois qu'il est défini, submitTo doit toujours spécifier une table ou une automation, sinon la validation échoue — un formulaire qui ne persiste nulle part est un bug de configuration.
En cas de succès
L'objet onSuccess décide ce que le contributeur voit après une soumission réussie. C'est une union discriminée sur type.
type |
Comportement |
|---|---|
successPage |
Affiche une page de succès personnalisée (title, message, buttonLabel + buttonHref optionnels, actions[] optionnels, showSummary). |
redirect |
Navigue vers url après un delaySeconds optionnel (par défaut 2 ; 0 est immédiat). Prend en charge les variables de modèle $submission.id / $record.id. |
reset |
Vide le formulaire pour une nouvelle soumission, avec un message optionnel et preserveFields[] à conserver. |
toast |
Affiche un toast transitoire (message, variant optionnel : success / info). |
message |
Remplace le formulaire par un message en ligne à sa place. |
onSuccess:
type: redirect
url: /thank-you?ref=$submission.id
delaySeconds: 0
Une successPage peut afficher des boutons actions[] — chacun est soit action: reset (soumettre à nouveau) soit action: navigate (lien vers url) — et showSummary: true liste les valeurs soumises, en respectant les champs masqués et les permissions de lecture par champ.
En cas d'erreur
L'objet onError contrôle le message affiché lorsqu'une soumission échoue côté serveur.
| Propriété | Description |
|---|---|
type |
toast, message (en ligne), ou errorPage (page complète). |
message |
Message du corps. Prend en charge les clés $t:. |
title |
Titre optionnel (utilisé par errorPage). |
variant |
Variante de toast (error / warning) — significatif uniquement lorsque type: toast. |
onError:
type: message
message: Something went wrong saving your request. Please try again.
Les erreurs de validation au niveau du champ sont distinctes. Les échecs de validation côté serveur (par ex. un e-mail invalide ou une violation de clé étrangère) renvoient HTTP 400 avec une enveloppe fieldErrors:[{ name, message }] et sont affichés en ligne sur le champ fautif — indépendamment de onError, qui couvre les échecs de soumission entière.
Pages associées
- Présentation des formulaires —
submitTo,storeSubmission, et le schémaonSuccess/onError. - Champs de formulaire —
permissionspar champ qui masquent les exports de registre. - Téléversements de fichiers — métadonnées de fichier stockées dans la charge utile
datadu registre. - Présentation des tables — la table liée que l'écriture double cible.