GoWeBaKnowledge Center

LA BIBLE DE LA PLATEFORME UNIFIÉE — ADDENDUM 06

Migration × Contacts × WebaBox — Gestionnaire Multi-Contacts

Version: 1.0
Date: 6 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 réinitialisation forcée · ZÉRO interruption d'envoi/réception de courriels


⚠️ AVIS CRITIQUE
Cet addendum possède la MÊME autorité que la Partie 1, la Partie 2 et tous les addendums précédents de la Bible.
Tous les changements décrits ici sont déployés en production et sauvegardés par points de contrôle.
Aucune modification incompatible avec le schéma n'a été effectuée. Toutes les modifications sont rétrocompatibles.

📋 TABLE DES MATIÈRES

  1. Phase A — Correction de catégorie WebaBox
  2. Phase B.1 — Bouton de suppression de migration
  3. Phase B.2 — Déconnexion du compte Google
  4. Phase B.3 — Enrichissement automatique lors de la migration
  5. Phase B.4 — Moteur de classification WebaCategory + Archivage 90 jours
  6. Phase C.1 — Onglet Chronologie du contact
  7. Phase C.2 — Onglet Pièces jointes (code couleur + aperçu + plein écran)
  8. Phase C.3 — Onglet Journal de fusion
  9. Phase C.4 — Onglet Analyse IA
  10. Phase D — Enrichissement par lot et vérification post-migration
  11. Phase E — Gestionnaire Multi-Contacts (Enrichissement relationnel + Sécurité de fusion)
  12. Corrections de bogues
  13. Fichiers modifiés — Inventaire complet
  14. Chronologie des points de contrôle

<a id="phase-a"></a>

SECTION 1 : PHASE A — CORRECTION DE CATÉGORIE WEBABOX

1.1 Énoncé du problème

L'API PATCH de WebaBox (/api/inbox/threads/[id]) définissait webaCategory: 'CONVERSATIONS' lorsqu'un utilisateur répondait à un fil URGENT. Or, CONVERSATIONS n'est pas une valeur valide dans l'énumération WebaCategory.

Valeurs valides de l'énumération : URGENT, IMPORTANT, JOURNAL, OFFICE, NONE.

1.2 Cause racine

Dans webabox-client.tsx, le gestionnaire de réponse codait en dur webaCategory: 'CONVERSATIONS' au lieu de la valeur correcte webaCategory: 'NONE'.

1.3 Correction appliquée

Fichier : app/(app)/webabox/webabox-client.tsx
Modification : webaCategory: 'CONVERSATIONS' → webaCategory: 'NONE'

1.4 Comportement après correction

ActionAvantAprès
Répondre à un fil URGENTLe fil passe dans « Conversations » avec une catégorie invalideLe fil passe dans le filtre Conversations (NONE + messageCount > 1)
Compteurs des cartes WebaBoxPouvaient afficher des compteurs fantômesCompteurs exacts pour l'ensemble des 12 cartes

1.5 Clarification clé — Architecture des 12 cartes WebaBox

Les 12 cartes WebaBox utilisent 5 valeurs en base de données + 7 filtres intelligents :

CarteSource
UrgentwebaCategory = URGENT
ImportantwebaCategory = IMPORTANT
JournalwebaCategory = JOURNAL
BureauwebaCategory = OFFICE
AucunewebaCategory = NONE ET messageCount = 1
ConversationswebaCategory = NONE ET messageCount > 1
Répondre plus tardisReplyLater = true
Mis de côtéisSetAside = true
SuivisisStarred = true
IndésirablesisSpam = true
CorbeilledeletedAt IS NOT NULL
Tous les courrielsTous les fils non supprimés

<a id="phase-b1"></a>

SECTION 2 : PHASE B.1 — BOUTON DE SUPPRESSION DE MIGRATION

2.1 Énoncé du problème

Le bouton Supprimer sur les cartes de projets de migration n'était visible que pour les statuts CREATED, COMPLETED, FAILED et CANCELLED. Les projets avec les statuts IMPORTING, SCANNING ou PLANNING n'affichaient aucun bouton Supprimer — laissant les utilisateurs dans l'impossibilité d'annuler une migration bloquée.

2.2 Modifications appliquées

Interface — app/(app)/migration/migration-client.tsx

// Avant
const canDelete = ['CREATED', 'COMPLETED', 'FAILED', 'CANCELLED'].includes(project.status);

// Après
const canDelete = ['CREATED', 'COMPLETED', 'FAILED', 'CANCELLED', 'IMPORTING', 'SCANNING', 'PLANNING'].includes(project.status);

Serveur — app/api/migration/projects/[id]/route.ts

// Avant
const deletableStatuses = ['CREATED', 'COMPLETED', 'FAILED', 'CANCELLED'];

// Après
const deletableStatuses = ['CREATED', 'COMPLETED', 'FAILED', 'CANCELLED', 'IMPORTING', 'SCANNING', 'PLANNING'];

2.3 Résultat

Les utilisateurs peuvent désormais supprimer des projets de migration dans n'importe quel statut, y compris les importations en cours.


<a id="phase-b2"></a>

SECTION 3 : PHASE B.2 — DÉCONNEXION DU COMPTE GOOGLE

Déjà présente dans la plateforme. Le bouton Déconnecter était fonctionnel sur la page Migration. Aucune modification requise.


<a id="phase-b3"></a>

SECTION 4 : PHASE B.3 — ENRICHISSEMENT AUTOMATIQUE LORS DE LA MIGRATION

4.1 Vue d'ensemble

Lorsque des contacts sont importés lors d'une migration Google Workspace, le système les enrichit automatiquement en :

  1. Créant/liant des enregistrements CompanyContact selon le nom de l'entreprise ou le domaine du courriel
  2. Créant des liens ContactCompanyRole entre Contact et CompanyContact
  3. Analysant les signatures de courriels via un LLM pour extraire des données supplémentaires

4.2 Nouvelles fonctions

Fichier : lib/migration/migration-actions.ts

enrichContactPostCreation(contactId, normalizedContact, organizationId, userId)

  • Déclencheur : Appelée en mode « fire-and-forget » après createContactEntity() dans le flux d'exécution de la migration
  • Logique :
    1. Si companyName est présent → trouver ou créer un CompanyContact (correspondance par nom insensible à la casse OU domaine de courriel)
    2. Extraire le domaine du courriel, ignorer les fournisseurs génériques (gmail, yahoo, hotmail, etc.)
    3. Créer un lien ContactCompanyRole avec le titre de poste comme rôle
  • Gestion des erreurs : Mode « fire-and-forget » — les échecs sont consignés mais ne bloquent jamais la migration

analyzeSignatureWithLLM(bodyHtml, bodyText)

  • Objectif : Extraire des données structurées à partir des signatures de courriels
  • Modèle : primary (gpt-4.1) via le wrapper LLM de WEBA
  • Champs extraits :
    • jobTitle
    • companyName
    • phone
    • website
    • address
    • bookingUrl ← NOUVEAU (Calendly, Cal.com, HubSpot meetings, Acuity, etc.)
  • Stratégie : Prend les 600 derniers caractères du corps du courriel comme bloc de signature
  • Sortie : Réponse JSON analysée, retourne null si aucune donnée utile n'est trouvée

4.3 Point d'intégration

Fichier : app/api/migration/projects/[id]/execute/route.ts

// Après createContactEntity()
enrichContactPostCreation(contact.id, normalized, organizationId, userId).catch(() => {});

<a id="phase-b4"></a>

SECTION 5 : PHASE B.4 — MOTEUR DE CLASSIFICATION WEBACATEGORY + ARCHIVAGE 90 JOURS

5.1 Moteur de classification

Fichier : lib/migration/weba-classify.ts

Classification basée sur des règles avec recours optionnel au LLM pour les fils ambigus.

Moteur de règles (sans coût LLM)

CatégorieExpressions régulières/Règles
JOURNALRapports DMARC, noreply@, no-reply@, reçus, notifications d'expédition, confirmations de livraison, alertes système, réponses automatiques, messages de rebond
OFFICEInfolettres, notifications de réseaux sociaux, courriels promotionnels, « unsubscribe », étiquettes de catégorie Gmail (CATEGORY_PROMOTIONS, CATEGORY_SOCIAL, CATEGORY_UPDATES, CATEGORY_FORUMS)
URGENTMessages Gmail suivis, étiquette IMPORTANT
IMPORTANTContacts connus dans l'organisation (courriel présent dans la table ContactEmail), fils avec 3+ messages (conversations actives)
NONEValeur par défaut

Recours au LLM (optionnel)

classifyAmbiguousWithLLM() — Classifie par lot les fils ayant obtenu NONE avec une faible confiance. Disponible pour une passe post-migration, mais non appelée lors de l'importation initiale afin de limiter les coûts.

5.2 Point d'intégration

Fichier : app/api/migration/projects/[id]/execute/route.ts

// Avant la création du fil
const webaCategory = classifyWebaCategory(threadData, gmailLabels, orgContactEmails);
// webaCategory transmise à EmailThread.create()

5.3 API d'archivage 90 jours

Fichier : app/api/migration/archive-old-threads/route.ts

  • Point de terminaison : POST /api/migration/archive-old-threads
  • Corps : { days?: number } (défaut : 90)
  • Action : Définit isArchived: true sur les fils plus anciens que N jours
  • Audit : Consigné sous migration.archive_old_threads

<a id="phase-c1"></a>

SECTION 6 : PHASE C.1 — ONGLET CHRONOLOGIE DU CONTACT

6.1 Nouvel onglet

Fichiers :

  • app/api/contacts/[id]/timeline/route.ts — Point de terminaison API
  • app/(app)/contacts/[id]/timeline-tab.tsx — Composant d'interface

6.2 Fonctionnalités

  • Liste chronologique de tous les échanges de courriels avec le contact
  • Agrège l'ensemble des adresses courriel du contact (principale + enregistrements ContactEmail)
  • Code couleur selon la direction :
    • ENTRANT ↓ — Indicateurs verts
    • SORTANT ↑ — Indicateurs bleus
  • Affichage de l'objet, de l'extrait, de la date et des adresses d'expédition/réception
  • Possibilité d'exportation en PDF

<a id="phase-c2"></a>

SECTION 7 : PHASE C.2 — ONGLET PIÈCES JOINTES (CODE COULEUR + APERÇU + PLEIN ÉCRAN)

7.1 Réécriture complète

Fichier : app/(app)/contacts/[id]/attachments-tab.tsx

7.2 Fonctionnalités

  • Liste toutes les pièces jointes des courriels provenant des fils du contact
  • Code couleur selon la direction : Badges verts pour ENTRANT, bleus pour SORTANT
  • Bouton Aperçu (👁) : Ouvre une boîte de dialogue avec aperçu intégré pour :
    • Images (tous formats)
    • PDF (via iframe)
    • Vidéo (lecteur HTML5)
    • Audio (lecteur HTML5)
    • Fichiers texte (affichage à espacement fixe)
  • Mode plein écran (⛶) : Bouton Agrandir dans la boîte de dialogue d'aperçu → superposition noire immersive
  • Bouton Télécharger : Disponible depuis la liste et la fenêtre modale d'aperçu
  • API d'aperçu : Utilise le point de terminaison existant /api/inbox/attachments/[id]?action=preview pour les URL présignées en ligne

<a id="phase-c3"></a>

SECTION 8 : PHASE C.3 — ONGLET JOURNAL DE FUSION

8.1 Nouvel onglet

Fichiers :

  • app/api/contacts/[id]/merge-log/route.ts — Point de terminaison API
  • app/(app)/contacts/[id]/merge-log-tab.tsx — Composant d'interface

8.2 Fonctionnalités

  • Affiche l'historique de toutes les opérations de fusion impliquant ce contact
  • Affiche : date de fusion, contacts sources, acteur (qui a effectué la fusion)
  • Données provenant des enregistrements AuditLog avec l'action contact.merge

<a id="phase-c4"></a>

SECTION 9 : PHASE C.4 — ONGLET ANALYSE IA

9.1 Architecture

API : app/api/contacts/[id]/ai-insights/route.ts
Interface : app/(app)/contacts/[id]/ai-insights-tab.tsx

9.2 Analyse LLM

  • Déclencheur : À la demande — l'utilisateur clique sur le bouton « Lancer l'analyse »
  • Données recueillies : Détails du contact, toutes les adresses courriel, téléphones, rôles en entreprise, interactions récentes (objet + corps), notes
  • Modèle : primary (gpt-4.1) via le wrapper LLM de WEBA
  • Invite : Invite structurée en français demandant :
    • Résumé de la relation
    • Points clés de communication
    • Statistiques d'interaction
    • Recommandations
    • Signaux de risque ou d'opportunité

9.3 Fonctionnalités de l'interface

  • Bouton « Lancer l'analyse » avec style dégradé
  • État de chargement avec indicateur animé
  • Sections Markdown analysées (en-têtes, puces)
  • Barre de statistiques : nombre de courriels, temps de réponse, jetons utilisés
  • Bouton « Réanalyser » pour actualiser
  • Couleur de l'onglet : Accent violet (cohérent avec les fonctionnalités IA)

<a id="phase-d"></a>

SECTION 10 : PHASE D — ENRICHISSEMENT PAR LOT ET VÉRIFICATION POST-MIGRATION

10.1 API d'enrichissement par lot

Fichier : app/api/migration/batch-enrich/route.ts

  • Point de terminaison : POST /api/migration/batch-enrich
  • Objectif : Enrichir les contacts sans jobTitle NI companyName en analysant leurs signatures de courriels
  • Flux :
    1. Trouver les contacts sans jobTitle/companyName (limite : 50-200 par lot)
    2. Pour chaque contact, trouver le dernier courriel ENTRANT (via lien de fil ou participantEmails)
    3. Appeler analyzeSignatureWithLLM() sur le corps du courriel
    4. Mettre à jour les champs du contact (jobTitle, companyName, website, calendarBookingUrl)
    5. Créer un enregistrement ContactPhone si un téléphone est extrait
    6. Créer CompanyContact + ContactCompanyRole si une entreprise est trouvée
  • Déduplication : Vérifie les enregistrements existants avant de créer
  • Audit : Consigné sous migration.batch_enrich

10.2 API de vérification post-migration

Fichier : app/api/migration/post-verify/route.ts

  • Point de terminaison : POST /api/migration/post-verify
  • Objectif : Effectuer une vérification complète de l'état post-migration
  • Retourne :
    • Analyse des doublons : Utilise le detectDuplicates() existant (correspondance par courriel, nom, téléphone)
    • Statistiques de complétude : Nombre de contacts sans jobTitle, companyName, téléphone, courriel
    • Liens d'entreprise : Nombre de contacts associés à des CompanyContact
    • Statistiques des fils : Total, archivés, distribution des WebaCategory
    • Statistiques du projet : Si projectId est fourni, retourne le statut du projet de migration
  • Audit : Consigné sous migration.post_verify

<a id="phase-e"></a>

SECTION 11 : PHASE E — GESTIONNAIRE MULTI-CONTACTS

11.1 Vision

Un seul contact peut avoir :

  • 4+ entreprises (via ContactCompanyRole → CompanyContact)
  • 4+ numéros de téléphone (via enregistrements ContactPhone)
  • 5-6 courriels (via enregistrements ContactEmail)
  • Plusieurs adresses (via enregistrements ContactAddress — bureaux, propriétés, international)
  • Plusieurs profils sociaux (via enregistrements ContactSocialMedia)
  • URL de réservation (champ calendarBookingUrl)

11.2 Problème identifié

L'Intelligence de signature extrayait correctement les données, mais les enregistrait uniquement dans des champs plats :

DonnéeEnregistrée dans (❌ Avant)L'onglet lit depuis
TéléphoneContact.primaryPhone (texte)ContactPhone (table relationnelle)
EntrepriseContact.companyName (texte)ContactCompanyRole → CompanyContact (relations)
Facebook/InstagramContact.socialLinks (JSON)ContactSocialMedia (table relationnelle)

Résultat : Les onglets affichaient (0) malgré les données extraites.

11.3 Correction — E.1 : Enrichissement relationnel

Fichier : app/api/email/extract-signature/route.ts

L'API Signature Intel crée désormais des enregistrements relationnels en plus des champs plats :

Création de ContactPhone

  • Crée un ContactPhone pour le phone extrait (étiquette : travail) et le mobilePhone (étiquette : mobile)
  • Définit isPrimary: true pour le premier téléphone si le contact n'en a aucun
  • Déduplication : vérifie les enregistrements ContactPhone existants avant de créer

CompanyContact + ContactCompanyRole

  • Trouve le CompanyContact existant par nom (insensible à la casse) ou domaine de courriel
  • Crée un nouveau CompanyContact si introuvable (avec domaine, site web)
  • Crée un lien ContactCompanyRole avec le titre de poste comme rôle/titre
  • Définit isPrimary: true pour le premier rôle en entreprise

ContactSocialMedia

  • Crée des enregistrements individuels pour chaque plateforme sociale trouvée :
    • LinkedIn → LINKEDIN
    • Twitter/X → TWITTER_X
    • Facebook → FACEBOOK
    • Instagram → INSTAGRAM
    • GitHub → GITHUB
    • YouTube → YOUTUBE
    • TikTok → TIKTOK
  • Identifiant extrait de l'URL (supprime le protocole/www)
  • Déduplication : vérifie la combinaison plateforme:identifiant

11.4 Correction — E.2 : Déduplication lors de la fusion (ContactCompanyRole)

Fichier : lib/contacts/contact-merge.ts

Avant : updateMany déplaçait TOUS les enregistrements ContactCompanyRole → PLANTAGE sur la contrainte d'unicité contactId_companyContactId si la cible et la source partagent la même entreprise.

Après : Vérification par enregistrement :

// Pour chaque rôle source :
if (targetRoleSet.has(role.companyContactId)) {
  // Même entreprise → supprimer le doublon de la source
  await prisma.contactCompanyRole.delete({ where: { id: role.id } });
} else {
  // Entreprise différente → déplacer vers la cible
  await prisma.contactCompanyRole.update({ where: { id: role.id }, data: { contactId: targetId } });
}

11.5 Correction — E.3 : Déduplication lors de la fusion (ContactSocialMedia)

Fichier : lib/contacts/contact-merge.ts

Même approche — vérifie la combinaison plateforme:identifiant avant de déplacer :

if (targetSocialSet.has(`${s.platform}:${s.handle.toLowerCase()}`)) {
  await prisma.contactSocialMedia.delete({ where: { id: s.id } });
} else {
  await prisma.contactSocialMedia.update({ where: { id: s.id }, data: { contactId: targetId } });
}

11.6 Correction — E.4 : La cible hérite des meilleurs champs après la fusion

Fichier : lib/contacts/contact-merge.ts

Après la fusion, le contact cible hérite des meilleures données disponibles des sources fusionnées :

for (const source of sources) {
  if (!target.jobTitle && source.jobTitle) updates.jobTitle = source.jobTitle;
  if (!target.companyName && source.companyName) updates.companyName = source.companyName;
  if (!target.website && source.website) updates.website = source.website;
  if (!target.calendarBookingUrl && source.calendarBookingUrl) updates.calendarBookingUrl = source.calendarBookingUrl;
  if (!target.socialLinks && source.socialLinks) updates.socialLinks = source.socialLinks;
}

11.7 Flux de fusion complet (16 étapes)

Lors de la fusion de N contacts en 1 cible :

#RelationStratégie
1ContactEmailDéplacer les non-doublons, supprimer les doublons
2ContactPhoneDéplacer les non-doublons, supprimer les doublons
3ContactInteractionTout déplacer
4ContactNoteTout déplacer
5ContactTagDéplacer les non-doublons, supprimer les doublons
6ContactAddressTout déplacer
7ContactSocialMediaDéplacer les non-doublons, supprimer les doublons (E.3)
8ContactCompanyRoleDéplacer les non-doublons, supprimer les doublons (E.2)
9ContactGroupMemberDéplacer les non-doublons, supprimer les doublons
10ContactObjectLinkDéplacer (ignorer les doublons via contrainte d'unicité)
11FileAssetRelier tous
12ClientInvoiceRelier tous
13EmailThreadRelier tous
14StudioFormSubmissionRelier tous
15ContractSignatoryRelier tous
16CalendarEventAttendeeRelier tous

Ensuite : définir mergedIntoId sur les sources, hériter des meilleurs champs sur la cible.


<a id="bugfixes"></a>

SECTION 12 : CORRECTIONS DE BOGUES

12.1 Onglet Chronologie — Boucle de chargement infinie

Cause racine : La fonction de traduction t de useT() était incluse dans les dépendances de useCallback. La référence de la fonction t change à chaque rendu, provoquant des boucles de récupération infinies.

Correction : Suppression de t du tableau de dépendances de useCallback dans timeline-tab.tsx.

12.2 Onglet Journal de fusion — Boucle de chargement infinie

Même cause racine et même correction que l'onglet Chronologie, dans merge-log-tab.tsx.

12.3 API de suppression — Statut IMPORTING bloqué

Problème : L'API du serveur refusait la suppression pour les projets avec les statuts IMPORTING/SCANNING/PLANNING.
Correction : Ajout de ces statuts au tableau deletableStatuses dans app/api/migration/projects/[id]/route.ts.

12.4 BookingUrl non extraite

Problème : analyzeSignatureWithLLM() n'extrayait pas les URL de réservation de calendrier.
Correction : Ajout de bookingUrl à l'invite LLM, à la signature de type, à la vérification hasData et à applyEnrichment(). Correspond à Contact.calendarBookingUrl.


<a id="files"></a>

SECTION 13 : FICHIERS MODIFIÉS — INVENTAIRE COMPLET

Nouveaux fichiers créés

FichierObjectif
lib/migration/weba-classify.tsMoteur de classification WebaCategory (règles + LLM)
app/api/migration/archive-old-threads/route.tsAPI d'archivage des fils de 90 jours
app/api/migration/batch-enrich/route.tsAPI d'enrichissement par lot post-migration
app/api/migration/post-verify/route.tsAPI de vérification post-migration
app/api/contacts/[id]/ai-insights/route.tsAPI d'analyse Analyse IA
app/(app)/contacts/[id]/ai-insights-tab.tsxComposant d'interface Analyse IA

Fichiers modifiés

FichierModifications
app/(app)/webabox/webabox-client.tsxCorrection CONVERSATIONS → NONE
app/(app)/migration/migration-client.tsxAjout de IMPORTING/SCANNING/PLANNING à canDelete
app/api/migration/projects/[id]/route.tsAjout de IMPORTING/SCANNING/PLANNING à deletableStatuses
app/api/migration/projects/[id]/execute/route.tsAjout des appels enrichContactPostCreation + classifyWebaCategory
lib/migration/migration-actions.tsAjout de enrichContactPostCreation() + analyzeSignatureWithLLM() + bookingUrl
app/(app)/contacts/[id]/timeline-tab.tsxCorrection de la boucle infinie (suppression de t des dépendances useCallback)
app/(app)/contacts/[id]/merge-log-tab.tsxCorrection de la boucle infinie (suppression de t des dépendances useCallback)
app/(app)/contacts/[id]/attachments-tab.tsxRéécriture complète : fenêtre modale d'aperçu + plein écran
app/(app)/contacts/[id]/contact-detail-client.tsxAjout de l'onglet Analyse IA
app/api/email/extract-signature/route.tsAjout de l'enrichissement relationnel (ContactPhone, CompanyContact, ContactSocialMedia)
lib/weba/signature-extraction.tsRéférence — buildContactEnrichmentData (inchangé)
lib/contacts/contact-merge.tsE.2/E.3 : déduplication ContactCompanyRole + ContactSocialMedia ; E.4 : héritage des meilleurs champs

<a id="checkpoints"></a>

SECTION 14 : CHRONOLOGIE DES POINTS DE CONTRÔLE

#Point de contrôleDescription
1Correction Phase AURGENT → NONE (et non CONVERSATIONS) dans webabox-client.tsx
2Phase B.1-B.2Bouton Supprimer visible + Déconnexion Google (préexistant)
3Phase C.1-C.3Onglets Chronologie, Pièces jointes (code couleur), Journal de fusion
4Correction suppression chronologie journalfusion aperçuSuppression IMPORTING + corrections boucles infinies + aperçu/plein écran Pièces jointes
5Onglet C.4 Analyse IA contactsOnglet d'analyse LLM à la demande
6B.3 enrichissement auto CompanyContact migrationEnrichissement automatique lors de l'exécution de la migration
7B.4 classification WebaCategory archivage 90jMoteur de classification + API d'archivage
8API D enrichissement-lot vérification-postPoints de terminaison d'enrichissement par lot + vérification
9Correction API suppression autoriser statut IMPORTINGCorrection de l'API du serveur pour la suppression IMPORTING
10Ajout extraction bookingUrl depuis signaturesBookingUrl ajoutée à l'extraction de signature LLM
11E enrichissement relationnel multi-contacts fusionEnrichissement relationnel + déduplication lors de la fusion

SECTION 15 : IMPACT SUR LE SCHÉMA

Zéro modification du schéma

Toutes les modifications utilisent des modèles et des champs Prisma existants :

  • Contact — jobTitle, companyName, website, calendarBookingUrl, socialLinks, primaryPhone, primaryEmail
  • ContactPhone — phone, label, isPrimary
  • ContactEmail — email, isPrimary
  • ContactCompanyRole — contactId, companyContactId, role, title, isPrimary
  • CompanyContact — name, domain, website, organizationId
  • ContactSocialMedia — platform (énumération SocialPlatform), handle, url, isPrimary
  • ContactAddress — champs d'adresse complets
  • EmailThread — webaCategory (énumération WebaCategory), isArchived
  • ContactInteraction — subject, body
  • ContactNote — content

Aucun prisma db push requis. Aucun --force-reset. Aucun --accept-data-loss.


SECTION 16 : POINTS DE TERMINAISON API CRÉÉS

MéthodePoint de terminaisonObjectif
POST/api/migration/batch-enrichEnrichissement par lot des contacts sans jobTitle/companyName via analyse LLM des signatures de courriels
POST/api/migration/post-verifyVérification post-migration (doublons + statistiques de complétude)
POST/api/migration/archive-old-threadsArchiver les fils plus anciens que N jours (défaut : 90)
POST/api/contacts/[id]/ai-insightsAnalyse LLM à la demande de la relation avec le contact

SECTION 17 : ONGLETS DU DÉTAIL DU CONTACT (LISTE COMPLÈTE)

Rangée 1

OngletSource de données
Vue d'ensembleContactForm (champs modifiables)
EntreprisesContactCompanyRole → CompanyContact
CourrielEnregistrements ContactEmail
TéléphoneEnregistrements ContactPhone
AdressesEnregistrements ContactAddress
Réseaux sociauxEnregistrements ContactSocialMedia

Rangée 2

OngletSource de données
ActivitéEnregistrements ContactInteraction
NotesEnregistrements ContactNote
ÉtiquettesContactTag → Tag
CalendrierCalendarEvent (via participants)
Signature IntelExtraction LLM depuis les courriels entrants
ChronologieAgrégation EmailMessage (NOUVEAU)
Journal de fusionAuditLog avec action=contact.merge (NOUVEAU)
Pièces jointesEmailAttachment avec aperçu/plein écran (RÉÉCRIT)
Analyse IAAnalyse LLM à la demande (NOUVEAU)
ContratsEnregistrements ContractSignatory

Fin de l'Addendum 06

« Une seule WEBA. Chaque canal. En temps réel, toujours. »


Document préparé par : Agent de développement WEBA
Validé par : Alain Bessette
Date : 6 juin 2026
Classification : Interne — Spécification technique

© 2024–2026 GOWEBA INC. — Make it Simple, Make it Possible, Make it Real.