Test d'Intégration - Form Submission + Queue (L1+L2+L3)
Objectif : Tester l’infrastructure complète L1+L2+L3 avec un formulaire de contact
Statut : En cours d’implémentation
1. Vue d’ensemble
Section titled “1. Vue d’ensemble”Ce test valide que l’infrastructure complète fonctionne sur les 3 couches :
- L1 (Contenu) : Sanity Studio - schéma et stockage des soumissions
- L2 (Presentation) : Astro - page contact avec formulaire
- L3 (Backend) : Cloudflare Workers - form-handler + Queue + submission-processor
2. Architecture du flux
Section titled “2. Architecture du flux”┌─────────────────────────────────────────────────────────┐│ L2 (Presentation) - Astro ││ └─ /contact (Formulaire de contact) ││ └─ Submit → Worker L3 │└────────────────────┬────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────┐│ L3 (Backend) - Cloudflare Workers ││ └─ form-handler Worker ││ ├─ Validation des données ││ ├─ Envoi vers Queue (submissions-queue-dev) ││ └─ Réponse immédiate au client │└────────────────────┬────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────┐│ L3 (Backend) - Queue Consumer ││ └─ submission-processor Worker ││ ├─ Traitement asynchrone ││ ├─ Validation métier ││ ├─ Stockage dans L1 (Sanity) ││ └─ Notifications (optionnel) │└────────────────────┬────────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────┐│ L1 (Contenu) - Sanity Studio ││ └─ Schema : submission ││ └─ Documents soumissions stockées │└─────────────────────────────────────────────────────────┘3. Composants implémentés
Section titled “3. Composants implémentés”3.1. L1 - Sanity Schema
Section titled “3.1. L1 - Sanity Schema”Fichier : apps/studio/schemaTypes/submission.ts
Champs :
name(string) : Nom du soumetteur (2-100 caractères)email(string) : Email validémessage(text) : Message (10-2000 caractères)status(string) : pending/processed/rejectedsubmittedAt(datetime) : Date de soumissionprocessedAt(datetime) : Date de traitement
3.2. L3 - Worker form-handler
Section titled “3.2. L3 - Worker form-handler”Dossier : services/form-handler/
Fichiers :
wrangler.toml: Configuration avec Queue producerpackage.json: Dépendances (zod pour validation)src/index.ts: Handler HTTP avec validationtsconfig.json: Configuration TypeScript
Fonctionnalités :
- Endpoint POST
/api/submit - Validation des données avec Zod
- Envoi vers Queue
submissions-queue-dev - Réponse immédiate au client
- Gestion CORS
3.3. L3 - Worker submission-processor
Section titled “3.3. L3 - Worker submission-processor”Dossier : services/submission-processor/
Fichiers :
wrangler.toml: Configuration avec Queue consumerpackage.json: Dépendances (@sanity/client)src/index.ts: Handler Queuetsconfig.json: Configuration TypeScript
Fonctionnalités :
- Consommation des messages de la Queue
- Validation métier
- Création de documents Sanity
- Gestion des erreurs avec retry
3.4. L2 - Page Contact Astro
Section titled “3.4. L2 - Page Contact Astro”Fichiers :
apps/web/src/pages/contact.astro: Page contact avec formulaireapps/web/src/pages/api/submit.ts: API endpoint pour proxy vers Workerapps/web/src/scripts/contact-form.js: Script JavaScript client
Fonctionnalités :
- Formulaire HTML avec validation
- JavaScript client pour appel API
- Feedback utilisateur (succès/erreur)
- Affichage du message AMN (L1)
- Documentation du flux L1+L2+L3
4. Étapes de test
Section titled “4. Étapes de test”4.1. Prérequis
Section titled “4.1. Prérequis”⚠️ Important : Suite à des problèmes de dépendances, il faut nettoyer et réinstaller :
cd /home/anderson/PPrm -rf node_modules pnpm-lock.yamlnpx pnpm@12.3.4 install4.2. Vérifier le schema Sanity
Section titled “4.2. Vérifier le schema Sanity”- Démarrer le Studio Sanity :
task dev:studio- Aller sur http://localhost:3333
- Vérifier que le type “Form Submission” est disponible
- Créer un document de test pour vérifier les champs
4.3. Tester le Worker form-handler localement
Section titled “4.3. Tester le Worker form-handler localement”- Démarrer le Worker form-handler :
task dev:form-handlerLe Worker sera accessible sur http://localhost:8787.
- Tester l’endpoint health :
curl http://localhost:8787/healthRésultat attendu :
{ "status": "healthy", "environment": "dev", "timestamp": "2026-09-09T11:28:41.170Z"}- Tester l’endpoint submit :
curl -X POST http://localhost:8787/api/submit \ -H "Content-Type: application/json" \ -d '{ "name": "Test User", "email": "test@example.com", "message": "This is a test message for the integration test" }'Résultat attendu :
{ "success": true, "message": "Form submitted successfully", "id": "2c9b3ede-7ef7-419d-aeea-962d2c10d868"}4.4. Tester la page contact Astro
Section titled “4.4. Tester la page contact Astro”- Démarrer le dev server Astro :
task dev- Accéder à http://localhost:4321/contact
- Remplir le formulaire avec des données valides
- Soumettre le formulaire
- Vérifier le message de succès avec l’ID de soumission
4.5. Configurer les secrets Sanity pour submission-processor
Section titled “4.5. Configurer les secrets Sanity pour submission-processor”Le worker submission-processor a besoin des secrets Sanity pour stocker les documents dans Sanity.
cd services/submission-processor
npx wrangler secret put SANITY_PROJECT_IDnpx wrangler secret put SANITY_DATASETnpx wrangler secret put SANITY_API_WRITE_TOKENOu utiliser le script fourni :
./inject_secret_to_cloudflare.sh submission-processor4.6. Tester le Worker submission-processor localement
Section titled “4.6. Tester le Worker submission-processor localement”- Démarrer le Worker submission-processor :
task dev:submission-processor- Tester l’endpoint health :
curl http://localhost:8788/healthRésultat attendu :
{ "status": "healthy", "service": "submission-processor", "environment": "dev", "sanityProjectIdPrefix": "4wa7…", "sanityDataset": "development", "timestamp": "2026-09-13T..."}- Tester l’endpoint direct (bypass Queue pour test local) :
curl -X POST http://localhost:8788/test-direct \ -H "Content-Type: application/json" \ -d '{ "name": "Direct Test User", "email": "direct@example.com", "message": "Direct test message for Sanity integration" }'Résultat attendu :
{ "success": true, "sanityId": "submission-abc123...", "message": "Direct test: submission stored in Sanity"}- Vérifier dans le Studio Sanity que le document a été créé
Note : Le mode local simule la Queue mais les messages ne passent pas vraiment entre les workers. L’endpoint /test-direct permet de tester l’intégration Sanity directement.
4.7. Vérifier le stockage dans Sanity
Section titled “4.7. Vérifier le stockage dans Sanity”- Aller dans le Studio Sanity (http://localhost:3333)
- Naviguer vers “Form Submission”
- Vérifier que le document a été créé
- Vérifier les champs : name, email, message, status, submittedAt, processedAt
4.8. Lancer tous les services
Section titled “4.8. Lancer tous les services”Pour tester l’intégration complète, lancer les 4 services dans 4 terminaux séparés :
# Terminal 1task dev # apps/web (Astro SSR, port 4321)
# Terminal 2task dev:studio # apps/studio (Sanity Studio, port 3333)
# Terminal 3task dev:form-handler # services/form-handler (port 8787)
# Terminal 4task dev:submission-processor # services/submission-processor (port 8788)4.9. Déploiement sur Cloudflare (dev)
Section titled “4.9. Déploiement sur Cloudflare (dev)”⚠️ Ne pas déployer manuellement - utiliser GitHub Actions :
git add .git commit -m "feat: add form submission integration test L1+L2+L3"git push origin mainLe workflow .github/workflows/deploy-dev.yml :
- Détecte les modifications dans
services/* - Injecte les secrets Sanity pour submission-processor
- Déploie les workers modifiés sur Cloudflare
5. Checklist de validation
Section titled “5. Checklist de validation”L1 - Sanity
Section titled “L1 - Sanity”- Schema submission créé
- Schema disponible dans le Studio
- Document de test créable
- Documents soumissions stockés correctement
L2 - Astro
Section titled “L2 - Astro”- Page contact créée
- Formulaire fonctionnel
- Validation HTML5 active
- Appel API vers Worker fonctionnel
- Feedback utilisateur affiché
L3 - Workers
Section titled “L3 - Workers”- Worker form-handler installé
- Worker form-handler testé localement
- Worker submission-processor installé
- Worker submission-processor testé localement
- Queue submissions-queue-dev configurée
- Secrets Sanity injectés
Intégration complète
Section titled “Intégration complète”- Flux L2 → L3 → Queue → L3 → L1 fonctionnel
- Formulaire → Worker → Queue → Sanity end-to-end
- Déploiement Cloudflare complet testé
6. Résolution de problèmes
Section titled “6. Résolution de problèmes”| Problème | Solution |
|---|---|
| Schema non visible dans Studio | Vérifier que schemaTypes/index.ts inclut submission |
| Worker form-handler ne démarre pas | Vérifier npx pnpm@12.3.4 install dans services/form-handler |
| Queue non accessible | Vérifier que submissions-queue-dev existe dans Cloudflare |
| Secret Sanity manquant | Exécuter wrangler secret put ou utiliser inject_secret_to_cloudflare.sh |
| Soumission échoue | Vérifier les logs du Worker avec wrangler tail |
| Document non créé dans Sanity | Vérifier les logs de submission-processor et les droits du token |
| CORS error | Vérifier les headers CORS dans le Worker |
| Validation Zod échoue | Vérifier que les données du formulaire respectent les contraintes |
| Erreur rolldown | Nettoyer node_modules et réinstaller : rm -rf node_modules pnpm-lock.yaml && npx pnpm@12.3.4 install |
7. Commandes utiles
Section titled “7. Commandes utiles”# Développement localtask dev # apps/web (Astro SSR, port 4321)task dev:studio # apps/studio (Sanity Studio, port 3333)task dev:form-handler # services/form-handler (port 8787)task dev:submission-processor # services/submission-processor (port 8788)task dev:services # Info pour lancer les 2 services Workers
# Installationtask install # Installe les dépendances du monorepotask install:ci # Installe les dépendances (CI, lockfile figé)
# Buildtask build:all # Construit web + studiotask build:web # Construit l'application webtask build:studio # Construit le Sanity Studio
# Qualitétask typecheck:services # Vérifie les types des services Workerstask check:services # Vérifie qualité services Workers
# Secrets./inject_secret_to_cloudflare.sh submission-processor
# Queue managementnpx wrangler queues listnpx wrangler queues delete submissions-queue-dev8. Livrables produits
Section titled “8. Livrables produits”- Schema Sanity :
apps/studio/schemaTypes/submission.ts - Worker form-handler :
services/form-handler/ - Worker submission-processor :
services/submission-processor/ - Page contact :
apps/web/src/pages/contact.astro - API endpoint :
apps/web/src/pages/api/submit.ts - Script client :
apps/web/src/scripts/contact-form.js - Documentation : Ce fichier
9. Avantages de ce scénario
Section titled “9. Avantages de ce scénario”- ✅ Test réel d’un flux métier complet
- ✅ Validation de toutes les couches (L1, L2, L3)
- ✅ Utilisation réelle de Queue (asynchrone)
- ✅ Réutilisable comme template pour d’autres formulaires
- ✅ Documentation complète pour l’équipe
- ✅ Préparation pour la Golden Path
10. Prochaines étapes
Section titled “10. Prochaines étapes”Une fois ce test validé :
- Clôturer le test “Welcome, AMN” (L1+L2)
- Commencer la Golden Path selon l’ordre défini dans
Phase0-Ordre-Slices.md - Utiliser ce formulaire comme base pour d’autres formulaires métier
11. Mises à jour et corrections (2026-09-13)
Section titled “11. Mises à jour et corrections (2026-09-13)”Corrections apportées
Section titled “Corrections apportées”- TypeScript : Ajout de types explicites dans
submission-processor/src/index.tspour corriger les erreurs TS18046 - Port submission-processor : Changé de 8788 à 8789 pour éviter les conflits de port
- Frontend JavaScript : Correction de l’affichage de l’ID (
result.sanityIdau lieu deresult.id) - Message utilisateur : Mise à jour du message de succès pour refléter le flux local direct
- Secrets injection : Correction de l’injection des secrets Sanity (utiliser
devau lieu desubmission-processor)
Problèmes majeurs résolus
Section titled “Problèmes majeurs résolus”1. Erreur 1042 (Cloudflare Worker restriction)
Section titled “1. Erreur 1042 (Cloudflare Worker restriction)”Cause : Cloudflare bloque les requêtes HTTP directes entre Workers sur le même sous-domaine *.workers.dev pour des raisons de sécurité. Cela causait l’erreur 1042 (“HTTP request failed”) lorsque le Worker Astro tentait d’appeler le Worker form-handler.
Solution : Utilisation d’un Service Binding pour permettre au Worker Astro de communiquer directement avec le Worker form-handler en interne, sans passer par Internet.
Configuration :
apps/web/wrangler.toml: Ajout du bindingFORM_HANDLERversamn-form-handler-devapps/web/src/env.d.ts: Définition des types pour le bindingapps/web/src/pages/api/submit.ts: Utilisation du binding en production, fallback local en développement
2. Astro v6 Breaking Change
Section titled “2. Astro v6 Breaking Change”Cause : Astro v6 a supprimé Astro.locals.runtime.env et maintenant les bindings sont accessibles directement via context.locals.env.
Solution :
- Mise à jour de
apps/web/src/pages/api/submit.tspour utilisercontext.locals.envau lieu decontext.locals.runtime.env - Mise à jour de
apps/web/src/env.d.tspour retirer l’interfaceRuntimeet définir directementEnvdansApp.Locals
3. SSR nécessaire pour API routes
Section titled “3. SSR nécessaire pour API routes”Cause : L’application était configurée en mode static dans astro.config.mjs, ce qui empêchait le fonctionnement des API routes et des bindings Cloudflare.
Solution :
- Changement de
output: 'static'àoutput: 'server'dansapps/web/astro.config.mjs - Activation du SSR pour permettre le fonctionnement des API routes et des Service Bindings
Statut actuel
Section titled “Statut actuel”- ✅ Lint : OK
- ✅ Typecheck : OK
- ✅ Wrangler dry-run form-handler : OK (amn-form-handler-dev, Queue: submissions-queue-dev)
- ✅ Wrangler dry-run submission-processor : OK (amn-submission-processor-dev)
- ✅ Test direct Sanity : OK (document créé avec ID lPyiYMEwUkAEhOUiejqRVC)
- ✅ Form-handler production : OK (testé avec curl)
- ✅ Secrets Sanity injectés : OK (submission-processor-dev)
- ✅ Service Binding configuré : OK (amn-dev → amn-form-handler-dev)
- ✅ Astro v6 compatibilité : OK (nouvelle structure des locals)
- ✅ SSR activé : OK (output: ‘server’)
Note importante
Section titled “Note importante”En développement local, le flux utilise un bypass direct vers le processor (/test-direct) car la simulation Miniflare de Queue ne connecte pas correctement les deux workers locaux. En production, le flux complet utilise le Service Binding :
Form → Astro (via Service Binding) → form-handler → Cloudflare Queue → submission-processor → Sanity
URLs de production
Section titled “URLs de production”- Form-handler :
https://amn-form-handler-dev.anderson-metsanou.workers.dev/api/submit - Submission-processor :
https://amn-submission-processor-dev.anderson-metsanou.workers.dev - Astro :
https://amn-dev.anderson-metsanou.workers.dev