Forms gère des formulaires modulaires. Un formulaire publie une surface publique (anonyme, identifiée par un slug) et, à la soumission, peut créer automatiquement une tâche/ticket dans Work.
- Base URL — prod :
https://forms.api.puwapi.com· dev :http://localhost:5900 - Auth : JWT + gating
forms(Business+). Les routes publiques sont anonymes.
Modèle¶
- Form —
title,slug(unique globalement car il identifie l'organisation à la soumission),schema(liste de champs{key,label,type,required,options}),honeypotField,allowedOrigins,visibility(public|organization),notifyEmails, et unworkConfigoptionnel{createWorkItem, type, projectId, fieldMapping}. - Types de champ :
text,textarea,email,number,tel,date,select,checkbox. - Soumission —
data(JSON),sourceIp,workItemId?.
Gestion (authentifiée)¶
Base : /api/forms
| Méthode | Route | Rôle |
|---|---|---|
| GET | /api/forms | Lister les formulaires |
| GET | /api/forms/{id} | Détail |
| POST | /api/forms | Créer (slug auto aléatoire si non fourni) |
| PATCH | /api/forms/{id} | Modifier |
| DELETE | /api/forms/{id} | Supprimer |
| GET | /api/forms/{formId}/submissions | Lister les soumissions (isolé par organisation) |
Surface publique (anonyme)¶
Base : /api/forms/public
| Méthode | Route | Rôle |
|---|---|---|
| GET | /api/forms/public/{slug} | Rendu public du formulaire (sans secrets, formulaire actif seulement) |
| POST | /api/forms/public/{slug}/submit | Soumettre |
À la soumission :
- L'organisation est dérivée du slug.
- Honeypot rempli →
200silencieux, rien n'est persisté. - Origine non autorisée (
allowedOrigins) →403. - La soumission est enregistrée.
- Si
workConfig.createWorkItem,title/descriptionsont mappés viafieldMappingpuis un item Work est créé (best-effort ; l'workItemIdest tracé). - E-mails : les
notifyEmailsreçoivent la soumission ; si le schéma porte un champemailrenseigné, le soumetteur reçoit un accusé de réception (best-effort).
Visibilité organization¶
Un formulaire organization ne révèle ses champs qu'à un membre de l'organisation. La
surface publique lit le tenant du JWT (si présent) ; un non-membre reçoit RequiresAuth=true
en lecture et 403 à la soumission. L'app publique affiche alors un écran de connexion.
Temps réel¶
Notif Convex forms.submission_received (/forms/notify) → le tableau Work se rafraîchit
en direct quand une soumission crée un item.