Type de ressource : Schéma Sanity (Document)
Fichier source :apps/studio/schemaTypes/submission.ts
Statut : Actif
Slice : 4 (Formulaire contact)
Version : 1.0
1. Vue dâensemble (DOC)
Section titled â1. Vue dâensemble (DOC)â1.1. Description
Section titled â1.1. DescriptionâSchĂ©ma pour les soumissions de formulaire de contact. Contient les informations du soumetteur (nom, email, message), le statut de traitement, et les horodatages de soumission et de traitement. Créé automatiquement par le worker submission-processor.
1.2. Objectif
Section titled â1.2. Objectifâ- ModĂ©liser les soumissions du formulaire de contact
- Permettre le suivi du statut de traitement
- Faciliter la gestion des soumissions dans le Sanity Studio
- Supporter lâhistorique des soumissions avec horodatage
1.3. Cas dâusage
Section titled â1.3. Cas dâusageâ- Stockage des soumissions du formulaire de contact
- Suivi du statut de traitement (pending, processed, rejected)
- Historique des soumissions avec horodatage
- Interface pour la gestion des soumissions dans le Sanity Studio
1.4. Relations avec dâautres schĂ©mas
Section titled â1.4. Relations avec dâautres schĂ©masâ| Relation | SchĂ©ma | Type | Description |
|---|---|---|---|
| Dépend de | Aucun | - | Schéma indépendant |
| Utilisé par | Aucun | - | Créé automatiquement par workers, non référencé |
2. Structure des données (DOC)
Section titled â2. Structure des donnĂ©es (DOC)â2.1. Champs principaux
Section titled â2.1. Champs principauxâ| Nom du champ | Type | Obligatoire | Description | Validation |
|---|---|---|---|---|
name |
string |
â | Nom du soumetteur | Rule.required().min(2).max(100) |
email |
string |
â | Email du soumetteur | Rule.required().email() |
message |
text |
â | Message du formulaire de contact | Rule.required().min(10).max(2000) |
status |
string |
â | Statut de traitement | Options: pending, processed, rejected |
submittedAt |
datetime |
â | Date et heure de soumission | initialValue: new Date().toISOString() |
processedAt |
datetime |
â | Date et heure de traitement | Aucune |
2.2. Champs SEO
Section titled â2.2. Champs SEOâAucun champ SEO spĂ©cifique nâest implĂ©mentĂ© dans ce schĂ©ma.
2.3. Champs de contenu riche
Section titled â2.3. Champs de contenu richeâAucun champ de contenu riche nâest implĂ©mentĂ© dans ce schĂ©ma.
3. Contrats dâEntrĂ©e/Sortie (SPEC)
Section titled â3. Contrats dâEntrĂ©e/Sortie (SPEC)â3.1. Inputs (crĂ©ation/modification)
Section titled â3.1. Inputs (crĂ©ation/modification)â| Champ | Type | Validation | Description |
|---|---|---|---|
name |
string |
Rule.required().min(2).max(100) | Nom du soumetteur |
email |
string |
Rule.required().email() | Email du soumetteur |
message |
text |
Rule.required().min(10).max(2000) | Message du formulaire |
status |
string |
Options: pending, processed, rejected |
Statut de traitement |
submittedAt |
datetime |
initialValue: new Date().toISOString() | Date de soumission |
processedAt |
datetime |
Aucune | Date de traitement (optionnel) |
3.2. Outputs (structure du document)
Section titled â3.2. Outputs (structure du document)â| Champ | Type | Description |
|---|---|---|
_id |
string |
ID unique du document |
_type |
string |
Type du document (submission) |
_createdAt |
string |
Date de création (généré par Sanity) |
_updatedAt |
string |
Date de derniÚre modification (généré par Sanity) |
name |
string |
Nom du soumetteur |
email |
string |
Email du soumetteur |
message |
string |
Message du formulaire |
status |
string |
Statut de traitement |
submittedAt |
string |
Date et heure de soumission |
processedAt |
string |
Date et heure de traitement (optionnel) |
3.3. Ătats du document
Section titled â3.3. Ătats du documentâ| Ătat | Description | Transition |
|---|---|---|
pending |
Soumission en attente de traitement | â processed ou rejected |
processed |
Soumission traitĂ©e avec succĂšs | â pending (retraitement) |
rejected |
Soumission rejetĂ©e | â pending (rĂ©examen) |
4. Implémentation (CODE)
Section titled â4. ImplĂ©mentation (CODE)â4.1. Code du schĂ©ma
Section titled â4.1. Code du schĂ©maâimport { defineType, defineField } from 'sanity'
export default defineType({ name: 'submission', title: 'Form Submission', type: 'document', fields: [ defineField({ name: 'name', title: 'Name', type: 'string', description: 'Nom du soumetteur', validation: (Rule) => Rule.required().min(2).max(100), }), defineField({ name: 'email', title: 'Email', type: 'string', description: 'Email du soumetteur', validation: (Rule) => Rule.required().email(), }), defineField({ name: 'message', title: 'Message', type: 'text', description: 'Message du formulaire de contact', validation: (Rule) => Rule.required().min(10).max(2000), }), defineField({ name: 'status', title: 'Status', type: 'string', options: { list: [ { title: 'Pending', value: 'pending' }, { title: 'Processed', value: 'processed' }, { title: 'Rejected', value: 'rejected' }, ], layout: 'radio', }, initialValue: 'pending', }), defineField({ name: 'submittedAt', title: 'Submitted At', type: 'datetime', description: 'Date et heure de soumission', initialValue: () => new Date().toISOString(), }), defineField({ name: 'processedAt', title: 'Processed At', type: 'datetime', description: 'Date et heure de traitement', }), ], preview: { select: { title: 'name', subtitle: 'email', description: 'message', }, prepare({ title, subtitle, description }) { return { title, subtitle: `${subtitle} - ${description?.substring(0, 50)}...`, } }, }, orderings: [ { title: 'Submitted At (Newest)', name: 'submittedAtDesc', by: [{field: 'submittedAt', direction: 'desc'}], }, { title: 'Submitted At (Oldest)', name: 'submittedAtAsc', by: [{field: 'submittedAt', direction: 'asc'}], }, ],})4.2. RequĂȘtes GROQ associĂ©es
Section titled â4.2. RequĂȘtes GROQ associĂ©esâRequĂȘte principale (soumissions pending)
Section titled âRequĂȘte principale (soumissions pending)â*[_type == "submission" && status == "pending"] { _id, name, email, message, submittedAt} | order(submittedAt desc)RequĂȘte dĂ©taillĂ©e (page unitaire)
Section titled âRequĂȘte dĂ©taillĂ©e (page unitaire)â*[_type == "submission" && _id == $id][0] { _id, name, email, message, status, submittedAt, processedAt}4.3. Types TypeScript (gĂ©nĂ©ration automatique)
Section titled â4.3. Types TypeScript (gĂ©nĂ©ration automatique)âNon implĂ©mentĂ© - sanity-typegen nâest pas configurĂ© dans le projet actuel.
// Types à implémenter manuellement si nécessaireexport type Submission = { _id: string; _type: 'submission'; name: string; email: string; message: string; status: 'pending' | 'processed' | 'rejected'; submittedAt: string; processedAt?: string;};5. Tests attendus (TEST)
Section titled â5. Tests attendus (TEST)â5.1. Tests unitaires
Section titled â5.1. Tests unitairesâ| ScĂ©nario | Description | RĂ©sultat attendu |
|---|---|---|
| Validation du nom | Créer une soumission sans nom | Erreur de validation |
| Validation de lâemail | CrĂ©er une soumission avec email invalide | Erreur de validation |
| Validation du message | Créer une soumission avec message < 10 caractÚres | Erreur de validation |
| Limite du message | Créer une soumission avec message > 2000 caractÚres | Erreur de validation |
| Status par défaut | Créer une soumission sans status | Valeur par défaut pending appliquée |
5.2. Tests dâintĂ©gration
Section titled â5.2. Tests dâintĂ©grationâ| ScĂ©nario | DĂ©pendances | Description | RĂ©sultat attendu |
|---|---|---|---|
| CrĂ©ation par worker | Form-handler â Queue â Submission-processor | Soumettre un formulaire via lâAPI | Document créé dans Sanity |
| Validation Zod | Frontend + Worker | Validation des entrées cÎté frontend | Erreur retournée si validation échoue |
| Stockage dans Sanity | Submission-processor + Sanity API | Création du document dans Sanity | Document créé avec tous les champs |
5.3. Tests E2E
Section titled â5.3. Tests E2Eâ| ScĂ©nario | Parcours utilisateur | Description | RĂ©sultat attendu |
|---|---|---|---|
| Soumission â Traitement | Formulaire â API â Sanity â Studio | Soumettre un formulaire complet | Document visible dans Sanity Studio |
| Traitement manuel | Studio â Changement status | Passer le status de pending Ă processed |
Status changé avec succÚs |
| Tri par date | Studio â Ordering | Trier les soumissions par date | Soumissions triĂ©es correctement |
6. IntĂ©gration (INTĂG)
Section titled â6. IntĂ©gration (INTĂG)â6.1. IntĂ©gration avec les composants
Section titled â6.1. IntĂ©gration avec les composantsâ| Composant | Type | RĂŽle | MĂ©thode dâintĂ©gration |
|---|---|---|---|
| Form-handler Worker | L3 | Validation et mise en queue | Reçoit la soumission et lâenvoie dans la Queue |
| Submission-processor Worker | L3 | Création du document Sanity | Consomme la Queue et crée le document |
| Sanity Studio | L1 | Gestion des soumissions | Interface pour visualiser et traiter les soumissions |
| Formulaire contact | L2 | Soumission du formulaire | Envoie les donnĂ©es vers lâAPI submit |
6.2. Points dâattention
Section titled â6.2. Points dâattentionâ- Ce schĂ©ma est créé automatiquement par le worker
submission-processor - Le champ
submittedAtest initialisé par le frontend,processedAtpar le worker - Les orderings personnalisés permettent un tri par date de soumission
- Le preview affiche un résumé du message (50 premiers caractÚres)
- Validation stricte des entrées cÎté frontend (Zod) et backend (Sanity)
- Le flux complet : Formulaire â API â form-handler â Queue â submission-processor â Sanity
6.3. Vérification de cohérence
Section titled â6.3. VĂ©rification de cohĂ©renceâ- Le schĂ©ma ne casse aucun schĂ©ma existant
- Les requĂȘtes GROQ retournent les donnĂ©es attendues
- Les types TypeScript sont générés correctement (à implémenter)
- Le flux de soumission fonctionne de bout en bout
7. Sécurité
Section titled â7. SĂ©curitĂ©â7.1. MĂ©canismes de sĂ©curitĂ©
Section titled â7.1. MĂ©canismes de sĂ©curitĂ©â- â Validation stricte des entrĂ©es cĂŽtĂ© frontend (Zod)
- â Validation des entrĂ©es cĂŽtĂ© backend (Sanity)
- â Les permissions Sanity sont configurĂ©es par rĂŽle
- â Les emails sont validĂ©s automatiquement
7.2. Validation des entrées
Section titled â7.2. Validation des entrĂ©esâ- â Le champ name est validĂ© (min 2, max 100 caractĂšres)
- â Le champ email est validĂ© (format email)
- â Le champ message est validĂ© (min 10, max 2000 caractĂšres)
- â Le champ status est limitĂ© aux options valides
8. Performance et limites
Section titled â8. Performance et limitesâ8.1. Limites Sanity
Section titled â8.1. Limites Sanityâ| Limite | Valeur | StratĂ©gie dâoptimisation |
|---|---|---|
| Taille du document | 16 MB | Ăviter les messages trop volumineux |
| Profondeur des références | 10 niveaux | Pas applicable (pas de références) |
8.2. Optimisations appliquées
Section titled â8.2. Optimisations appliquĂ©esâ- â Utilisation de Queue Cloudflare pour le traitement asynchrone
- â Limitation de la taille du message (max 2000 caractĂšres)
- â Orderings personnalisĂ©s pour un tri efficace
9. Débogage et troubleshooting
Section titled â9. DĂ©bogage et troubleshootingâ9.1. ProblĂšmes courants
Section titled â9.1. ProblĂšmes courantsâ| SymptĂŽme | Cause probable | Solution |
|---|---|---|
| Soumission non créée | Queue non configurée | Vérifier la configuration Queue dans wrangler.toml |
| Document sans processedAt | Worker échoué | Vérifier les logs du worker submission-processor |
| Validation échoue | Données invalides | Vérifier les rÚgles de validation Zod et Sanity |
| Status ne change pas | Permissions insuffisantes | Vérifier les permissions Sanity Studio |
9.2. Commandes de debug
Section titled â9.2. Commandes de debugâ# Extraire le schĂ©ma depuis Sanitynpx sanity schema extract
# Générer les types TypeScript (à implémenter)npx sanity typegen generate
# Logs du worker submission-processorwrangler tail submission-processor10. Bonnes pratiques
Section titled â10. Bonnes pratiquesâ10.1. Architecture
Section titled â10.1. Architectureâ- â Toujours utiliser des types gĂ©nĂ©rĂ©s par sanity-typegen (Ă implĂ©menter)
- â
Centraliser les requĂȘtes GROQ dans
src/lib/queries.ts(Ă implĂ©menter) - â Documenter les champs et leurs validations
10.2. Code
Section titled â10.2. Codeâ- â
Utiliser
defineFieldpour chaque champ - â Configurer le preview pour une meilleure UX dans Studio
- â Utiliser des validations appropriĂ©es
- â Configurer les orderings pour un tri efficace
10.3. Maintenance
Section titled â10.3. Maintenanceâ- â Mettre Ă jour ce fichier lors de toute modification du schĂ©ma
- â RĂ©gĂ©nĂ©rer les types aprĂšs modification (Ă implĂ©menter)
- â Tester le flux de soumission aprĂšs modification
11. Ăvolutions et roadmap
Section titled â11. Ăvolutions et roadmapâ11.1. AmĂ©liorations planifiĂ©es
Section titled â11.1. AmĂ©liorations planifiĂ©esâ- ImplĂ©mentation de sanity-typegen pour la gĂ©nĂ©ration de types
- Ajout de champs pour les piĂšces jointes
- Notification automatique lors de nouvelles soumissions
- Centralisation des requĂȘtes GROQ dans un fichier dĂ©diĂ©
11.2. Limitations connues
Section titled â11.2. Limitations connuesâ- â Pas de champs SEO spĂ©cifiques
- â Types TypeScript non gĂ©nĂ©rĂ©s automatiquement
- â Pas de support pour les piĂšces jointes
- â Pas de notification automatique
12. Ressources liées
Section titled â12. Ressources liĂ©esâ- Documentation Sanity : Schema Types
- DAT L1 : §4 - Modélisation et Schémas des Données
- Schémas dépendants : Aucun (schéma indépendant)
- Workers associés :
services/form-handler,services/submission-processor - Pages Astro :
apps/web/src/pages/contact.astro,apps/web/src/pages/api/submit.ts - Queue Cloudflare :
submissions-queue-dev/submissions-queue-prod - Configuration :
services/form-handler/wrangler.toml,services/submission-processor/wrangler.toml
13. Historique des modifications
Section titled â13. Historique des modificationsâ| Date | Version | Description | Auteur |
|---|---|---|---|
| 2026-09-15 | 1.0 | Création initiale | Devin |