Edge functions décentralisées : 1 logique = 1 fichier _shared
L'erreur la plus coûteuse : copier 200 lignes d'auth/CORS/validation dans chaque edge function. Au 3e fork, une logique diverge et un bug ne se reproduit que sur 2 fonctions sur 5.
Structure _shared (DRY edge functions)
supabase/functions/
├── _shared/
│ ├── cors.ts # corsHeaders unique
│ ├── auth.ts # verifyJwt, requireAdmin
│ ├── rateLimit.ts # RPC rate limit IP/user
│ ├── gsc.ts # logique Google Search Console
│ └── errors.ts # ApiError, formatError
├── my-function/index.ts # 30-50 lignes maxAnti-pattern : redéfinir corsHeaders
Si vous voyez const corsHeaders = { ... } dans index.ts → refactor immédiat vers import { corsHeaders } from "../_shared/cors.ts". Sinon, le jour où vous ajoutez un header (x-trace-id), vous l'ajoutez dans 12 fichiers et en oubliez 3.
Erreurs typées 4xx/5xx
Une seule classe ApiError(status, code, message) partagée. Chaque function attrape et formate. Côté client, 1 seul handleApiError qui mappe status → toast. Plus jamais de return new Response("error", { status: 500 }) brut.
Adapter une fonction = adapter pour tous
Quand vous modifiez une logique partagée (ex: gsc.ts mutualisée entre gsc-metrics et gsc-sync), un test d'intégration doit couvrir les 2 consommateurs. Sinon, vous corrigez un bug et en créez un autre.
Partager