API
Routes HTTP d'admin et publiques, et fonctions serveur importables pour lire un formulaire sans aller-retour HTTP.
Le module expose ses formulaires de trois façons : des routes HTTP d'admin, deux routes publiques, et des fonctions serveur pour le code qui tourne dans le même processus.
Règle absolue : depuis un Server Component ou un bloc, ne jamais appeler la route publique de lecture avec fetch. C'est un aller-retour réseau vers le processus courant. Importer @lrvo/module-forms/server.
Import
| Sous-chemin | Runtime | Contenu |
|---|---|---|
@lrvo/module-forms | serveur | manifest, register, createTables, dropTables. |
@lrvo/module-forms/server | serveur | Lecture publique d'un formulaire. Aucun React. |
@lrvo/module-forms/public | client | FormEmbed et FormRenderer. |
@lrvo/module-forms/client | client | Enregistrement de la page d'admin. Aucun export. |
import { getPublicFormById } from '@lrvo/module-forms/server';@lrvo/module-forms/server est délibérément séparé de /public : il ne contient aucun composant, et reste donc importable depuis un Server Component sans tirer de code client. C'est ce qu'utilise le bloc du BlockEditor. Voir Affichage.
API
| Signature | Retour | Description |
|---|---|---|
getPublicFormById(id) | Promise<Form | null> | Formulaire actif par son identifiant. |
getPublicFormBySlug(slug) | Promise<Form | null> | Formulaire actif par son slug. |
Les deux renvoient null quand le formulaire n'existe pas ou qu'il n'est pas actif. Aucune permission n'est vérifiée : elles servent le rendu public.
Forme du résultat
{ id, slug, title, description, fields, submitLabel, success }C'est une projection volontairement réduite. Les réglages internes ne sortent jamais : ni les destinataires de notification, ni les sujets de courriel, ni le seuil anti-robots.
import { getPublicFormById } from '@lrvo/module-forms/server';
const form = await getPublicFormById(block.formId);
if (!form) return null;success porte le mode et le message ou l'URL de redirection, dont le composant de rendu a besoin pour réagir après l'envoi.
Routes HTTP
Toutes sont montées sous le préfixe /lrvo/api, comme le veut core/api.
Admin
Toutes exigent d'abord une session d'administration, c'est-à-dire la permission admin.access du core, puis la permission de la route.
| Méthode | Chemin | Permission |
|---|---|---|
GET | /forms/admin | forms.view |
POST | /forms/admin | forms.manage |
GET | /forms/admin/submissions | forms.view |
GET | /forms/admin/submissions/:id | forms.view |
PATCH | /forms/admin/submissions/:id | forms.manage |
DELETE | /forms/admin/submissions/:id | forms.manage |
GET | /forms/admin/submissions/:id/file/:idx | forms.view |
GET | /forms/admin/:id | forms.view |
PUT | /forms/admin/:id | forms.manage |
POST | /forms/admin/:id/duplicate | forms.manage |
DELETE | /forms/admin/:id | forms.manage |
GET /forms/admin accepte status, limit (200 par défaut) et offset, et renvoie chaque formulaire avec son nombre de soumissions.
GET /forms/admin/submissions accepte formId, status, limit (50 par défaut) et offset. La réponse porte total, le nombre de soumissions correspondant au filtre avant pagination, sur lequel repose la pagination de l'admin.
GET /forms/admin/submissions/:id renvoie la soumission enrichie du titre, du slug et de la définition des champs du formulaire, ce qui permet d'afficher les réponses en face de leur libellé même si le formulaire a changé depuis.
GET /forms/admin/submissions/:id/file/:idx diffuse une pièce jointe par sa position dans le tableau files. C'est le seul accès aux fichiers d'une soumission, il n'existe aucune URL publique.
POST /forms/admin/:id/duplicate crée une copie, titre suffixé de (copie), slug ré-unicifié, et statut inactive.
L'ordre de déclaration compte : les chemins de soumissions sont déclarés avant /forms/admin/:id, sans quoi submissions serait pris pour un identifiant. Le routeur du core retient la première correspondance, sans préférer un segment fixe à un paramètre.
Public
| Méthode | Chemin | Auth |
|---|---|---|
GET | /forms/public/:slug | aucune |
POST | /forms/public/:slug/submit | aucune |
GET /forms/public/:slug renvoie la même projection réduite que les fonctions serveur. Elle répond 404 si le formulaire est absent ou inactif. C'est ce qu'appelle FormEmbed.
POST /forms/public/:slug/submit est le point de soumission. Il exige un corps en multipart/form-data, refuse le JSON, et attend en plus des champs du formulaire les deux champs techniques _hp et _t. Voir Soumissions.
En cas d'erreur de validation, la réponse 400 porte, à côté du message général, un objet fieldErrors indexé par nom de champ. Les composants livrés par le module ne l'exploitent pas, une intégration maison le peut.
Aucune de ces routes n'est ouverte à un autre domaine
Les deux routes publiques n'exigent ni session ni permission, mais le routeur du core applique une vérification d'origine sur toute requête modifiante. La soumission depuis un domaine tiers est donc refusée par construction, et sans NEXT_PUBLIC_URL renseignée, toute soumission l'est. Voir Configuration.
Notes
- Les routes d'admin vérifient la session puis la permission avant d'atteindre le handler. Ne jamais court-circuiter cette vérification.
- Il n'existe aucune route d'export de soumissions, ni au format CSV, ni autrement.
GET /forms/public/:slugrépond404avec le même message qu'un formulaire soit introuvable ou inactif, ce qui ne révèle pas l'existence d'un formulaire fermé. Le point de soumission, lui, distingue les deux cas par son message : « Ce formulaire n'accepte plus de soumissions » indique un formulaire existant mais fermé.