Skip to content

Test d'Intégration - Form Submission + Queue (L1+L2+L3)

Test d'Intégration - Form Submission + Queue (L1+L2+L3)

Documentation technique

Objectif : Tester l’infrastructure complète L1+L2+L3 avec un formulaire de contact
Statut : En cours d’implémentation

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

┌─────────────────────────────────────────────────────────┐
│ 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

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/rejected
  • submittedAt (datetime) : Date de soumission
  • processedAt (datetime) : Date de traitement

3.2. L3 - Worker form-handler1/2

Dossier : services/form-handler/

Fichiers :

  • wrangler.toml : Configuration avec Queue producer
  • package.json : Dépendances (zod pour validation)
  • src/index.ts : Handler HTTP avec validation
  • tsconfig.json : Configuration TypeScript

3.2. L3 - Worker form-handler2/2

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-processor1/2

Dossier : services/submission-processor/

Fichiers :

  • wrangler.toml : Configuration avec Queue consumer
  • package.json : Dépendances (@sanity/client)
  • src/index.ts : Handler Queue
  • tsconfig.json : Configuration TypeScript

3.3. L3 - Worker submission-processor2/2

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 Astro1/2

Fichiers :

  • apps/web/src/pages/contact.astro : Page contact avec formulaire
  • apps/web/src/pages/api/submit.ts : API endpoint pour proxy vers Worker
  • apps/web/src/scripts/contact-form.js : Script JavaScript client

3.4. L2 - Page Contact Astro2/2

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

4.1. Prérequis

⚠️ Important : Suite à des problèmes de dépendances, il faut nettoyer et réinstaller :

Terminal window
cd /home/anderson/PP
rm -rf node_modules pnpm-lock.yaml
npx pnpm@12.3.4 install

4.2. Vérifier le schema Sanity

  1. Démarrer le Studio Sanity :
Terminal window
task dev:studio
  1. Aller sur http://localhost:3333
  2. Vérifier que le type “Form Submission” est disponible
  3. Créer un document de test pour vérifier les champs

4.3. Tester le Worker form-handler localement1/4

  1. Démarrer le Worker form-handler :
Terminal window
task dev:form-handler

Le Worker sera accessible sur http://localhost:8787.

  1. Tester l’endpoint health :
Terminal window
curl http://localhost:8787/health

4.3. Tester le Worker form-handler localement2/4

Résultat attendu :

{
"status": "healthy",
"environment": "dev",
"timestamp": "2026-09-09T11:28:41.170Z"
}
  1. Tester l’endpoint submit :

4.3. Tester le Worker form-handler localement3/4

Terminal window
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"
}'

4.3. Tester le Worker form-handler localement4/4

Résultat attendu :

{
"success": true,
"message": "Form submitted successfully",
"id": "2c9b3ede-7ef7-419d-aeea-962d2c10d868"
}

4.4. Tester la page contact Astro

  1. Démarrer le dev server Astro :
Terminal window
task dev
  1. Accéder à http://localhost:4321/contact
  2. Remplir le formulaire avec des données valides
  3. Soumettre le formulaire
  4. Vérifier le message de succès avec l’ID de soumission

4.5. Configurer les secrets Sanity pour submission-processor1/2

Le worker submission-processor a besoin des secrets Sanity pour stocker les documents dans Sanity.

Terminal window
cd services/submission-processor
npx wrangler secret put SANITY_PROJECT_ID
npx wrangler secret put SANITY_DATASET
npx wrangler secret put SANITY_API_WRITE_TOKEN

4.5. Configurer les secrets Sanity pour submission-processor2/2

Ou utiliser le script fourni :

Terminal window
./inject_secret_to_cloudflare.sh submission-processor

4.6. Tester le Worker submission-processor localement1/5

  1. Démarrer le Worker submission-processor :
Terminal window
task dev:submission-processor
  1. Tester l’endpoint health :
Terminal window
curl http://localhost:8788/health

4.6. Tester le Worker submission-processor localement2/5

Résultat attendu :

{
"status": "healthy",
"service": "submission-processor",
"environment": "dev",
"sanityProjectIdPrefix": "4wa7…",
"sanityDataset": "development",
"timestamp": "2026-09-13T..."
}

4.6. Tester le Worker submission-processor localement3/5

  1. Tester l’endpoint direct (bypass Queue pour test local) :
Terminal window
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"
}'

4.6. Tester le Worker submission-processor localement4/5

Résultat attendu :

{
"success": true,
"sanityId": "submission-abc123...",
"message": "Direct test: submission stored in Sanity"
}

4.6. Tester le Worker submission-processor localement5/5

  1. 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

  1. Aller dans le Studio Sanity (http://localhost:3333)
  2. Naviguer vers “Form Submission”
  3. Vérifier que le document a été créé
  4. Vérifier les champs : name, email, message, status, submittedAt, processedAt

4.8. Lancer tous les services

Pour tester l’intégration complète, lancer les 4 services dans 4 terminaux séparés :

Terminal window
# Terminal 1
task dev # apps/web (Astro SSR, port 4321)
# Terminal 2
task dev:studio # apps/studio (Sanity Studio, port 3333)
# Terminal 3
task dev:form-handler # services/form-handler (port 8787)
# Terminal 4
task dev:submission-processor # services/submission-processor (port 8788)

4.9. Déploiement sur Cloudflare (dev)

⚠️ Ne pas déployer manuellement - utiliser GitHub Actions :

Terminal window
git add .
git commit -m "feat: add form submission integration test L1+L2+L3"
git push origin main

Le 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

L1 - Sanity

  • Schema submission créé
  • Schema disponible dans le Studio
  • Document de test créable
  • Documents soumissions stockés correctement

L2 - Astro

  • Page contact créée
  • Formulaire fonctionnel
  • Validation HTML5 active
  • Appel API vers Worker fonctionnel
  • Feedback utilisateur affiché

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

  • Flux L2 → L3 → Queue → L3 → L1 fonctionnel
  • Formulaire → Worker → Queue → Sanity end-to-end
  • Déploiement Cloudflare complet testé

6. Résolution de problèmes1/2

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

6. Résolution de problèmes2/2

Problème Solution
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

Terminal window
# Développement local
task 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
# Installation
task install # Installe les dépendances du monorepo
task install:ci # Installe les dépendances (CI, lockfile figé)
# Build
task build:all # Construit web + studio
task build:web # Construit l'application web
task build:studio # Construit le Sanity Studio
# Qualité
task typecheck:services # Vérifie les types des services Workers
task check:services # Vérifie qualité services Workers
# Secrets
./inject_secret_to_cloudflare.sh submission-processor
# Queue management
npx wrangler queues list
npx wrangler queues delete submissions-queue-dev

8. Livrables produits

  1. Schema Sanity : apps/studio/schemaTypes/submission.ts
  2. Worker form-handler : services/form-handler/
  3. Worker submission-processor : services/submission-processor/
  4. Page contact : apps/web/src/pages/contact.astro
  5. API endpoint : apps/web/src/pages/api/submit.ts
  6. Script client : apps/web/src/scripts/contact-form.js
  7. Documentation : Ce fichier

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

Une fois ce test validé :

  1. Clôturer le test “Welcome, AMN” (L1+L2)
  2. Commencer la Golden Path selon l’ordre défini dans Phase0-Ordre-Slices.md
  3. Utiliser ce formulaire comme base pour d’autres formulaires métier

11. Mises à jour et corrections (2026-09-13)

Corrections apportées

  • TypeScript : Ajout de types explicites dans submission-processor/src/index.ts pour 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.sanityId au lieu de result.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 dev au lieu de submission-processor)

Problèmes majeurs résolus

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 binding FORM_HANDLER vers amn-form-handler-dev
  • apps/web/src/env.d.ts : Définition des types pour le binding
  • apps/web/src/pages/api/submit.ts : Utilisation du binding en production, fallback local en développement

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.ts pour utiliser context.locals.env au lieu de context.locals.runtime.env
  • Mise à jour de apps/web/src/env.d.ts pour retirer l’interface Runtime et définir directement Env dans App.Locals

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' dans apps/web/astro.config.mjs
  • Activation du SSR pour permettre le fonctionnement des API routes et des Service Bindings

Statut actuel1/2

  • ✅ 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)

Statut actuel2/2

  • ✅ 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

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

  • 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
Switch to normal mode

Contents