THE UNIFIED PLATFORM BIBLE — ADDENDUM 07
Triple Vérification — Pipeline de Migration & Correctifs Juin 2026
Version: 1.0
Date: 16 juin 2026
Auteur: Alain Bessette, CFO/Product Owner, ABI Conglomerate
Domaine: GoWeBa.com
Statut: Addendum stratégique officiel — Spécification contraignante
Contraintes: ZÉRO perte de données · ZÉRO force-reset · ZÉRO interruption email
⚠️ AVIS CRITIQUE
Cet addendum a la MÊME autorité que la Partie 1, la Partie 2 et tous les addendums précédents de la Bible.
Tous les correctifs décrits ci-dessous sont déployés en production et sauvegardés en checkpoint.
Aucune modification de schéma incompatible n'a été effectuée.
📋 TABLE DES MATIÈRES
- Contexte & Objectif
- Phase M — Vérification du Google Pull
- Phase C — Vérification de la Classification V10
- Phase E — Correctif Email Forward/Reply
- Phase A — Onglet ARCHIVED & Grille 15 cartes
- Correctif Bounce Address
- Registre de Domaines — Seed initial
- État de la Base de Données
- Verdict Final & Recommandations
- Fichiers modifiés — Inventaire complet
- Chronologie des Checkpoints
<a id="contexte"></a>
SECTION 1 : CONTEXTE & OBJECTIF
Après plusieurs itérations sur le pipeline de migration Google → GoWeBa, cet addendum documente la triple vérification exhaustive effectuée le 16 juin 2026 avant le lancement officiel des migrations utilisateur.
Les phases vérifiées couvrent l'ensemble du cycle de vie :
| Phase | Portée | Statut |
|---|---|---|
| M | Migration automatisée (Google Pull API) | ✅ Vérifié |
| C | Classification V10 (cascade 12 couches) | ✅ Vérifié |
| E | Email Forward/Reply (attachments + From) | ✅ Corrigé & déployé |
| A | Onglet ARCHIVED + grille 15 cartes | ✅ Corrigé & déployé |
| Bounce | Correctif adresses bounce inbound | ✅ Corrigé & déployé |
| Domain Registry | Seed initial 333 domaines | ✅ Exécuté |
<a id="phase-m"></a>
SECTION 2 : PHASE M — VÉRIFICATION DU GOOGLE PULL
2.1 Architecture de récupération
Le module lib/migration/google-pull.ts gère l'extraction des données Google via les API natives (People, Gmail, Calendar, Drive) sans dépendance au package googleapis.
2.2 Paramètres de performance vérifiés
| Paramètre | Valeur | Justification |
|---|---|---|
QUERIES_PER_MIN | 200 | Sous la limite Gmail de 250/min |
MICRO_BATCH | 8 requêtes concurrentes | Parallélisme contrôlé |
DELAY_BETWEEN_BATCHES_MS | 2 400 ms | 8 / 2,4s ≈ 3,33 req/sec = 200/min |
MACRO_BATCH_SIZE | 2 250 | Lots de traitement par chunks |
FLUSH_SIZE | 200 | Flush vers DB tous les 200 emails |
MAX_RETRIES | 4 | Tentatives avec backoff exponentiel |
INITIAL_BACKOFF_MS | 2 000 ms | Backoff initial (2s → 4s → 8s → 16s) |
MAX_CONSECUTIVE_ERRORS | 20 | Arrêt de sécurité |
2.3 Mécanismes de robustesse
- Backoff exponentiel : 2s → 4s → 8s → 16s + jitter aléatoire de 1s
- Détection rate limit : Fonction
isRateLimitError()détecte les codes HTTP 429 et erreurs Google spécifiques - Arrêt préventif : Après 20 erreurs consécutives, l'import s'arrête proprement avec un message d'erreur explicite
- Flush progressif : Les emails ne sont pas gardés en mémoire — ils sont flushés vers la DB par lots de 200
- Logs de progression : Un log est émis tous les ~500 emails avec le temps écoulé
- Estimation temporelle : Le système calcule et affiche le temps estimé restant
2.4 Verdict
<a id="phase-c"></a>
SECTION 3 : PHASE C — VÉRIFICATION DE LA CLASSIFICATION V10
3.1 Cascade 12 couches
Le fichier lib/weba/classification-cascade.ts implémente la cascade V10 complète, telle que documentée dans le Guide de Classification WebaBox V10 (Document 2) :
| Couche | Nom | Confiance | Description |
|---|---|---|---|
| 1 | USER SENDER RULES | 1.00 | Règles utilisateur — BLOCK→SPAM, ALLOW→skip |
| 2 | GMAIL STARRED | 0.95 | isStarred=true → URGENT |
| 3 | EXPLICIT URGENCY | 0.92 | Regex juridique/urgence (FR/EN/ES) |
| 4 | DOMAIN REGISTRY | 0.90 | lookupDomain() — 333 domaines mappés |
| 5 | FROM-ADDRESS PATTERNS | 0.88 | noreply→OFFICE, newsletter→JOURNAL |
| 6 | GMAIL CATEGORY LABELS | 0.85 | CATEGORY_SOCIAL→SOCIAL, etc. |
| 7 | SUBJECT LINE PATTERNS | 0.72 | Correspondance mots-clés trilingue |
| 8 | TEMPORAL ANALYSIS | 0.70 | Deadlines→URGENT/IMPORTANT |
| 9 | CONTACT GRAPH | 0.68 | Contact CRM connu → IMPORTANT |
| 10 | LLM INTELLIGENCE | variable | GPT-4.1-mini + 6E few-shot |
| 11 | (partie de L10) | — | Few-shot injecté dans le prompt LLM |
| 12 | FALLBACK | 0.10 | NONE |
3.2 Classification batch (Migration V10)
Le endpoint POST /api/weba/migration/start gère la classification en masse :
- Lots de 50 threads (configurable jusqu'à 100)
- Self-chaining automatique : Le serveur se rappelle lui-même via
selfChain()pour traiter le lot suivant - Retry du self-chain : 3 tentatives (localhost → URL externe → fallback)
- Action combinée :
action: 'both'permet de classifier + archiver en une seule opération - Compteurs cumulatifs :
_totalProcessedet_totalChangedsuivent la progression globale
3.3 Feature Flags
Tous les flags V10 sont activés par défaut (via lib/weba/feature-flags.ts) :
| Flag | Fonction |
|---|---|
V10_WEBABOX_UI | Interface grille 4×4 |
V10_NEW_CATEGORIES | TRAVEL, SOCIAL, PROMOTIONS |
V10_AUTO_ARCHIVE | Auto-archivage cron 90 jours |
V10_CONTACT_CLASSIFIER | Classification types de contacts |
V10_SECURITY_SCORER | Scoring sécurité emails |
V10_DOMAIN_REGISTRY | Registre de domaines (couche 4) |
V10_REALTIME_PIPELINE | Pipeline cascade temps réel |
3.4 Verdict
<a id="phase-e"></a>
SECTION 4 : PHASE E — CORRECTIF EMAIL FORWARD/REPLY
4.1 Problème identifié
Deux bugs dans la fonction Forward/Reply de WebaBox :
- Attachments non transférés : Lors d'un Forward, les pièces jointes de l'email original n'étaient pas incluses dans le nouveau message.
- Compte d'envoi incorrect : Le sélecteur "From" ne se positionnait pas sur le compte email associé au thread.
4.2 Correctifs appliqués
4.2.1 Attachments Forward
Fichiers modifiés :
app/(app)/inbox/compose-modal.tsx— Ajout de la propinitialAttachments+ logique de chargement (presigned URL → base64)app/(app)/inbox/webabox-client.tsx— Ajout des attachments dansreplyComposeStateapp/(app)/inbox/ongoing/[threadId]/ongoing-client.tsx— Même propagation pour le mode thread
Fonctionnement : Quand l'utilisateur clique "Forward", les attachments de l'email original sont récupérés via presigned URL, convertis en base64, et pré-chargés dans le formulaire de composition.
4.2.2 Compte From par défaut
Fichier modifié : app/(app)/inbox/compose-modal.tsx
Bug : Le useEffect qui chargeait les comptes email écrasait systématiquement le selectedAccountId initial.
Fix : Ajout de la condition if (!initialAccountId && ...) pour ne pas écraser un compte déjà sélectionné.
4.3 Verdict
<a id="phase-a"></a>
SECTION 5 : PHASE A — ONGLET ARCHIVED & GRILLE 15 CARTES
5.1 Changements UI
| Avant | Après |
|---|---|
| Onglet "Unread" en haut | Onglet "Archived" en haut |
| 16 cartes (4×4 avec ARCHIVED) | 15 cartes (3×4 + 1×3, sans ARCHIVED) |
| ARCHIVED dans la grille | ARCHIVED accessible via l'onglet dédié |
5.2 Disposition de la grille
| Rangée | Catégories |
|---|---|
| 1 | Urgent · Important · Conversations · Awaiting |
| 2 | Journal · Office · Reply Later · Set Aside |
| 3 | Travel · Social · Promotions · Clips |
| 4 | Snooze · Spam · Trash |
5.3 Fichiers modifiés
app/(app)/inbox/webabox-client.tsx— Remplacement de l'onglet, suppression de la carte ARCHIVED, mise à jour des totauxapp/api/inbox/snapshot/route.ts— Ajout du compteurarchiveddans les totaux
5.4 Verdict
<a id="bounce-fix"></a>
SECTION 6 : CORRECTIF BOUNCE ADDRESS
6.1 Problème identifié
Les emails entrants affichaient des adresses d'expéditeur de type :
[email protected]
au lieu de l'adresse réelle de l'expéditeur. Ceci rendait les fonctions Reply et Forward inutilisables.
6.2 Cause racine
Fichier : app/api/webhooks/sendgrid-inbound/route.ts
Fonction : handleRawMode()
Le code extrayait correctement l'adresse réelle depuis l'en-tête MIME From: via parsed.from.address, mais l'écrasait ensuite avec envelope.from — l'adresse technique de rebond (return-path) fournie par le service de relay email.
// ❌ AVANT — Bug
const envelopeFrom = parsed.from.address; // ← Correct au départ
if (envelope.from) envelopeFrom = envelope.from; // ← ÉCRASE avec le bounce
// ✅ APRÈS — Correctif
const mimeFrom = parsed.from.address; // ← Adresse réelle (MIME From:)
let envelopeFrom = mimeFrom; // ← Copie pour spam checks
if (envelope.from) envelopeFrom = envelope.from; // ← Envelope pour SPF/DKIM uniquement
// mimeFrom → stocké en DB et utilisé pour contacts
// envelopeFrom → utilisé uniquement pour checkSpamAndSpoofing()
6.3 Impact
| Contexte | Avant | Après |
|---|---|---|
fromEmail en DB | [email protected] | vraiexpé[email protected] |
| Fonction Reply | Répond au bounce | Répond à la vraie personne |
| Fonction Forward | Affiche le bounce | Affiche le vrai expéditeur |
| Contact auto-créé | Contact bounce | Contact réel |
| Anti-spam/SPF | ✅ Fonctionne | ✅ Fonctionne (inchangé) |
6.4 Mode Parsed
Le mode "Parsed" de SendGrid (handleParsedMode()) n'était pas affecté — il utilisait déjà extractEmailAddress(fromRaw) depuis le champ from du formulaire, qui contient toujours l'adresse MIME réelle.
6.5 Limitation connue
30 messages existants dans la base de données ont encore des adresses bounce comme fromEmail. Seuls les nouveaux emails entrants sont corrigés. Un script de migration rétroactive peut être exécuté sur demande.
6.6 Verdict
<a id="domain-registry"></a>
SECTION 7 : REGISTRE DE DOMAINES — SEED INITIAL
7.1 Découverte
Lors de la triple vérification, il a été constaté que la table DomainRegistry était vide (0 entrées). La couche 4 de la cascade V10 (Domain Registry) ne pouvait donc pas fonctionner.
7.2 Action corrective
Exécution du seed depuis lib/weba/domain-registry-seed-data.ts :
- 334 domaines définis dans le fichier source
- 333 domaines créés en base (1 doublon résolu par update)
- 5 catégories couvertes : SOCIAL, TRAVEL, PROMOTIONS, JOURNAL, OFFICE
7.3 Exemples de domaines seedés
| Catégorie | Exemples |
|---|---|
| SOCIAL | linkedin.com, facebook.com, twitter.com, instagram.com |
| TRAVEL | booking.com, airbnb.com, expedia.com, aircanada.com |
| PROMOTIONS | amazon.com, shopify.com, paypal.com |
| JOURNAL | medium.com, substack.com, wordpress.com |
| OFFICE | docusign.com, hellosign.com, calendly.com |
7.4 Impact sur la classification
Avec 333 domaines en base, la couche 4 (confiance 0.90) peut maintenant classifier la majorité des emails provenant de services connus sans recourir au LLM (couche 10), améliorant :
- La vitesse de classification (pas d'appel API LLM)
- La précision (correspondance exacte de domaine > analyse LLM)
- Les coûts (moins d'appels LLM facturés)
7.5 Verdict
<a id="etat-db"></a>
SECTION 8 : ÉTAT DE LA BASE DE DONNÉES
8.1 Snapshot du 16 juin 2026
| Métrique | Valeur |
|---|---|
| Threads email | 884 |
| Messages email | 1 284 |
| Threads archivés | 184 |
| Contacts | 1 045 |
| Logs de classification | 59 |
| Entrées registre domaines | 333 |
| Projets de migration | 9 |
8.2 Distribution des catégories
| Catégorie | Threads | % |
|---|---|---|
| NONE | 781 | 88,3% |
| JOURNAL | 42 | 4,8% |
| IMPORTANT | 32 | 3,6% |
| OFFICE | 17 | 1,9% |
| URGENT | 8 | 0,9% |
| PROMOTIONS | 4 | 0,5% |
| TRAVEL | 0 | 0% |
| SOCIAL | 0 | 0% |
Note : 781 threads (88,3%) sont catégorisés
NONEcar la classification V10 n'a pas encore été exécutée sur les threads existants. Après le lancement de la classification batch, cette distribution devrait se rapprocher de la distribution cible documentée dans le Guide V10.
8.3 Nettoyage des anciennes migrations
Les deux migrations test ([email protected] et alainbessette.com/iwant@) ont été intégralement supprimées :
- 0 résidu trouvé dans les projets de migration
- 0 données orphelines liées à ces comptes
- Les tokens Google (refresh tokens) pour ces comptes sont encore présents et seront renouvelés automatiquement lors de la reconnexion
8.4 Messages avec adresses bounce
30 messages ont encore des adresses bounce ([email protected]) comme fromEmail. Ces messages antérieurs au correctif ne sont pas affectés rétroactivement. Un script de correction peut être exécuté sur demande.
<a id="verdict"></a>
SECTION 9 : VERDICT FINAL & RECOMMANDATIONS
9.1 Résumé de la vérification
| Composant | Vérifié | Statut | Action requise |
|---|---|---|---|
| Google Pull (rate limits, retry, batching) | ✅ | SOLIDE | Aucune |
| Import (self-chaining, stall detection) | ✅ | SOLIDE | Aucune |
| Classification V10 (cascade 12 couches) | ✅ | SOLIDE | Aucune |
| Auto-Archive (cron, batch 2000, catégories protégées) | ✅ | SOLIDE | Aucune |
| Feature Flags (7/7 activés) | ✅ | ACTIFS | Aucune |
| Webhook inbound (bounce address) | ✅ | CORRIGÉ | Aucune |
| Registre de domaines (333 entrées) | ✅ | SEEDÉ | Aucune |
| Anciennes migrations (nettoyées) | ✅ | PROPRE | Aucune |
| CRON_SECRET | ✅ | CONFIGURÉ | Aucune |
| Google OAuth credentials | ✅ | CONFIGURÉS | Aucune |
9.2 Recommandations post-déploiement
- Lancer la classification V10 sur les 781 threads existants catégorisés
NONEvia l'admin/admin/weba/migration - Lancer l'auto-archive pour archiver les threads >90 jours des catégories éligibles
- Vérifier les premiers emails entrants après le correctif bounce pour confirmer que les adresses sont correctes
- Considérer un script de correction rétroactive pour les 30 messages avec adresses bounce
- Considérer l'ajout d'un champ
replyToau modèleEmailMessagepour une meilleure gestion des réponses (amélioration future)
9.3 Conclusion
🟢 LE PIPELINE DE MIGRATION EST PRÊT. Toutes les vérifications sont passées. Les correctifs critiques ont été appliqués. Le registre de domaines a été populé. Le système est prêt à traiter de nouvelles migrations en toute confiance.
<a id="fichiers"></a>
SECTION 10 : FICHIERS MODIFIÉS — INVENTAIRE COMPLET
10.1 Phase E (Email Forward/Reply)
| Fichier | Modification |
|---|---|
app/(app)/inbox/compose-modal.tsx | Prop initialAttachments + chargement presigned URL → base64 + fix overwrite account |
app/(app)/inbox/webabox-client.tsx | replyComposeState type + forward attachments + wiring JSX |
app/(app)/inbox/ongoing/[threadId]/ongoing-client.tsx | composeState type + forward attachments |
10.2 Phase A (ARCHIVED tab + grille)
| Fichier | Modification |
|---|---|
app/(app)/inbox/webabox-client.tsx | Onglet Archived, suppression carte ARCHIVED, totaux |
app/api/inbox/snapshot/route.ts | Compteur archived dans les totaux |
10.3 Correctif Bounce
| Fichier | Modification |
|---|---|
app/api/webhooks/sendgrid-inbound/route.ts | Séparation mimeFrom vs envelopeFrom dans handleRawMode() |
10.4 Registre de domaines
| Fichier | Modification |
|---|---|
lib/weba/domain-registry-seed-data.ts | Source : 334 domaines (existant, non modifié) |
| Base de données | 333 entrées créées via script de seed |
<a id="checkpoints"></a>
SECTION 11 : CHRONOLOGIE DES CHECKPOINTS
| Date | Checkpoint | Description |
|---|---|---|
| 15 juin 2026 | Phase E | Forward attachments + From default fix |
| 15 juin 2026 | Phase A | Archived tab + 15-card grid |
| 16 juin 2026 | Bounce Fix | Fix bounce address in fromEmail for inbound emails |
Fin de l'Addendum 07 — Triple Vérification Migration