====== Sprint 3 — Gestion des Clients ====== ===== Objectif ===== Implémenter le premier domaine métier CRM complet de la plateforme. Le domaine : Customer deviendra le pivot central de : Réservations Facturation CRM Marketing Communication Programme de fidélité Revenue Management ---- ====== Périmètre du Sprint 3 ====== ===== Entités ===== Customer CustomerAddress CustomerDocument CustomerTag CustomerNote CustomerCommunication CustomerPreference ---- ===== Fonctionnalités ===== CRUD Clients Profil Client Adresses Documents Tags CRM Notes internes Historique communications Préférences client Segmentation Fidélisation ---- ====== Architecture cible ====== Customer ├── Addresses ├── Documents ├── Tags ├── Notes ├── Communications ├── Preferences ├── Reservations ├── Invoices └── CRM Activities ---- ====== Découpage du Sprint ====== ===== Sprint 3-A ===== Modèle CRM Prisma Customer CustomerAddress CustomerPreference ---- ===== Sprint 3-B ===== CRUD Clients CustomerModule CustomerController CustomerService ---- ===== Sprint 3-C ===== Adresses Client CustomerAddressModule ---- ===== Sprint 3-D ===== Documents Client CustomerDocument Upload Stockage ---- ===== Sprint 3-E ===== Tags CRM CustomerTag Segmentation ---- ===== Sprint 3-F ===== Notes CRM CustomerNote ---- ===== Sprint 3-G ===== Communications CustomerCommunication ---- ===== Sprint 3-H ===== Préférences Client CustomerPreference ---- ===== Sprint 3-I ===== Recherche CRM Avancée Filtres Segmentation Recherche globale ---- ===== Sprint 3-J ===== Vue CRM Enterprise Dashboard Client Vue 360° Historique complet ---- ====== Sprint 3-A.1 — Implémentation Prisma CRM Core ====== ===== Objectif ===== Créer le socle CRM principal de la plateforme. Ces modèles deviendront les fondations de : Reservations CRM Marketing Facturation Communication Fidélisation Revenue Management ---- ====== Architecture CRM ====== Customer ├── CustomerAddress ├── CustomerPreference ├── Reservations ├── Invoices ├── Notes ├── Tags ├── Documents └── Communications ---- ====== Étape 1 — Création Customer ====== ===== Ajouter dans schema.prisma ===== model Customer { id String @id @default(uuid()) tenantId String customerNumber String? externalReference String? type String @default("INDIVIDUAL") status String @default("ACTIVE") firstName String lastName String companyName String? email String? phone String? mobilePhone String? dateOfBirth DateTime? nationality String? language String? source String? acquisitionChannel String? notes String? vip Boolean @default(false) blacklisted Boolean @default(false) marketingConsent Boolean @default(false) emailVerified Boolean @default(false) phoneVerified Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? tenant Tenant @relation( fields:[tenantId], references:[id] ) addresses CustomerAddress[] preferences CustomerPreference? @@index([tenantId]) @@index([status]) @@index([email]) @@index([phone]) @@index([vip]) @@index([createdAt]) @@unique([ tenantId, customerNumber ]) } ---- ====== Étape 2 — Création CustomerAddress ====== ===== Ajouter ===== model CustomerAddress { id String @id @default(uuid()) customerId String label String addressLine1 String addressLine2 String? postalCode String city String state String? country String latitude Decimal? @db.Decimal(10,7) longitude Decimal? @db.Decimal(10,7) formattedAddress String? placeId String? isDefault Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt customer Customer @relation( fields:[customerId], references:[id], onDelete:Cascade ) @@index([customerId]) @@index([country]) @@index([city]) @@index([isDefault]) } ---- ====== Étape 3 — Création CustomerPreference ====== ===== Ajouter ===== model CustomerPreference { id String @id @default(uuid()) customerId String @unique preferredLanguage String? preferredCurrency String? preferredChannel String? prefersEmail Boolean @default(true) prefersSms Boolean @default(false) prefersPhone Boolean @default(false) acceptsMarketing Boolean @default(false) acceptsNewsletter Boolean @default(false) acceptsPromotions Boolean @default(false) acceptsSurveys Boolean @default(false) loyaltyEligible Boolean @default(true) vipProgramEligible Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt customer Customer @relation( fields:[customerId], references:[id], onDelete:Cascade ) @@index([preferredLanguage]) @@index([preferredCurrency]) @@index([acceptsMarketing]) } ---- ====== Étape 4 — Relation Tenant ====== ===== Ajouter dans Tenant ===== customers Customer[] ---- ====== Étape 5 — Préparation Reservations ====== ===== Ajouter dans Customer ===== reservations Reservation[] ---- ===== Ajouter dans Reservation ===== customerId String? customer Customer? @relation( fields:[customerId], references:[id] ) ---- ====== Étape 6 — Préparation CRM ====== ===== Ajouter dans Customer ===== Relations futures : notes CustomerNote[] documents CustomerDocument[] communications CustomerCommunication[] tags CustomerTag[] ---- ===== Ne pas créer encore ===== Ces modèles arriveront dans : Sprint 3-D Sprint 3-E Sprint 3-F Sprint 3-G ---- ====== Étape 7 — Préparation Marketing ====== ===== Champs CRM ===== Déjà présents : source acquisitionChannel marketingConsent ---- ===== Exemples ===== Website Booking Airbnb Google Ads Facebook Referral Direct ---- ====== Étape 8 — Préparation Fidélité ====== ===== Champs ===== vip loyaltyEligible vipProgramEligible ---- ===== Utilisation future ===== Loyalty Program Reward Engine Customer Segmentation ---- ====== Étape 9 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name crm_customer_core ---- ===== Générer ===== npx prisma generate ---- ====== Étape 10 — Validation ====== ===== Exécuter ===== npx prisma validate ---- ===== Résultat attendu ===== The schema at prisma/schema.prisma is valid ---- ====== Étape 11 — Vérification SQL ====== ===== PostgreSQL ===== \d "Customer" \d "CustomerAddress" \d "CustomerPreference" ---- ====== Modèle CRM obtenu ====== Customer │ ├── Profil CRM │ ├── Préférences │ ├── Adresses │ ├── Réservations │ ├── Marketing │ └── Fidélité ---- ====== Définition de terminé ====== Le Sprint 3-A.1 est terminé lorsque : ✓ Customer créé ✓ CustomerAddress créée ✓ CustomerPreference créée ✓ Tenant relation ajoutée ✓ Reservation relation préparée ✓ Migration exécutée ✓ Prisma Client généré ✓ Validation Prisma verte ---- ====== Livrables ====== Customer CustomerAddress CustomerPreference Migration crm_customer_core Prisma Client mis à jour ---- ====== Sprint 3-A.2 — Amélioration Enterprise du modèle Customer ====== ===== Objectif ===== Faire évoluer le modèle CRM Core vers un modèle Enterprise capable de supporter : CRM avancé Segmentation Marketing Automation Fidélisation Analyse comportementale Revenue Management RGPD Conformité ---- ====== Architecture cible ====== Customer ├── Profile ├── Preferences ├── Addresses ├── Segmentation ├── Scoring ├── Risk ├── Lifetime Value ├── GDPR ├── Communications ├── Reservations └── CRM History ---- ====== Sprint 3-A.2-A ====== ===== CustomerStatus ===== ---- ====== Étape 1 — Création Enum ====== ===== Ajouter ===== enum CustomerStatus { LEAD ACTIVE VIP INACTIVE BLOCKED BLACKLISTED } ---- ====== Étape 2 — Utilisation ====== ===== Remplacer ===== Dans : model Customer ---- ===== Ancien ===== status String ---- ===== Nouveau ===== status CustomerStatus @default(ACTIVE) ---- ====== Sprint 3-A.2-B ====== ===== CustomerSource ===== ---- ====== Étape 3 — Enum Source ====== ===== Ajouter ===== enum CustomerSource { WEBSITE DIRECT AIRBNB BOOKING EXPEDIA VRBO GOOGLE FACEBOOK INSTAGRAM REFERRAL PARTNER IMPORT OTHER } ---- ====== Étape 4 — Utilisation ====== ===== Remplacer ===== source String? ---- ===== Par ===== source CustomerSource? ---- ====== Sprint 3-A.2-C ====== ===== Customer Score ===== ---- ====== Étape 5 — Ajouter ===== Dans : model Customer ---- ===== Champs ===== customerScore Int @default(0) engagementScore Int @default(0) satisfactionScore Int @default(0) loyaltyScore Int @default(0) ---- ===== Utilisation ===== Segmentation CRM Marketing Fidélisation ---- ====== Sprint 3-A.2-D ====== ===== Customer Lifetime Value ===== ---- ====== Étape 6 — Ajouter ===== lifetimeValue Decimal? @db.Decimal(14,2) totalReservations Int @default(0) totalRevenue Decimal? @db.Decimal(14,2) averageBasket Decimal? @db.Decimal(14,2) lastReservationAt DateTime? ---- ===== Préparation ===== Pour : Revenue Management Business Intelligence Customer Analytics ---- ====== Sprint 3-A.2-E ====== ===== Customer Risk ===== ---- ====== Étape 7 — Enum ====== enum CustomerRiskLevel { LOW MEDIUM HIGH CRITICAL } ---- ====== Étape 8 — Ajouter ===== Dans Customer : riskLevel CustomerRiskLevel @default(LOW) riskScore Int @default(0) fraudFlag Boolean @default(false) ---- ===== Utilisation ===== Fraude Paiements Réservations Sécurité ---- ====== Sprint 3-A.2-F ====== ===== Segmentation ===== ---- ====== Étape 9 — Enum ====== enum CustomerSegment { STANDARD FREQUENT VIP CORPORATE OWNER PARTNER BLACKLISTED } ---- ====== Étape 10 — Ajouter ===== segment CustomerSegment @default(STANDARD) ---- ===== Utilisation ===== Campagnes CRM Automatisation Fidélisation ---- ====== Sprint 3-A.2-G ====== ===== RGPD ===== ---- ====== Étape 11 — Ajouter ===== Dans Customer : gdprConsentGiven Boolean @default(false) gdprConsentAt DateTime? marketingConsentAt DateTime? privacyPolicyAccepted Boolean @default(false) privacyPolicyAcceptedAt DateTime? dataRetentionUntil DateTime? ---- ===== Préparation ===== Pour : Consent ComplianceAudit RetentionPolicy ---- ====== Sprint 3-A.2-H ====== ===== Historisation CRM ===== ---- ====== Étape 12 — Création CustomerHistory ====== ===== Ajouter ===== model CustomerHistory { id String @id @default(uuid()) customerId String changedField String oldValue String? newValue String? changedBy String? changedAt DateTime @default(now()) customer Customer @relation( fields:[customerId], references:[id], onDelete:Cascade ) @@index([customerId]) @@index([changedAt]) } ---- ====== Étape 13 — Relation ====== ===== Ajouter ===== Dans : model Customer history CustomerHistory[] ---- ====== Sprint 3-A.2-I ====== ===== Scoring Automatique ===== ---- ====== Étape 14 — Préparer ===== Ajouter dans Customer : firstReservationAt DateTime? lastCommunicationAt DateTime? lastActivityAt DateTime? ---- ===== Calcul futur ===== Customer Score Engagement Score Loyalty Score Risk Score seront alimentés par : Reservations Invoices CRM Activities Communications ---- ====== Sprint 3-A.2-J ====== ===== Préparation Marketing ===== ---- ====== Étape 15 — Ajouter ===== preferredPropertyType String? preferredStayDuration Int? preferredDestination String? preferredTravelSeason String? ---- ===== Utilisation ===== Marketing IA Recommandations Segmentation Campagnes ---- ====== Étape 16 — Index CRM ====== ===== Ajouter ===== Dans Customer : @@index([segment]) @@index([customerScore]) @@index([riskLevel]) @@index([source]) @@index([lifetimeValue]) @@index([lastReservationAt]) @@index([gdprConsentGiven]) ---- ====== Étape 17 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name customer_enterprise ---- ===== Générer ===== npx prisma generate ---- ====== Étape 18 — Validation ====== ===== Exécuter ===== npx prisma validate ---- ===== Résultat attendu ===== The schema at prisma/schema.prisma is valid ---- ====== Modèle CRM Enterprise obtenu ====== Customer ├── Profil ├── Adresses ├── Préférences ├── Segmentation ├── Score ├── Lifetime Value ├── Risque ├── RGPD ├── Historique ├── Marketing └── Fidélisation ---- ====== Définition de terminé ====== Le Sprint 3-A.2 est terminé lorsque : ✓ CustomerStatus ✓ CustomerSource ✓ CustomerScore ✓ CustomerLifetimeValue ✓ CustomerRisk ✓ CustomerSegment ✓ RGPD ✓ CustomerHistory ✓ Index CRM ✓ Migration exécutée ---- ====== Livrables ====== Customer Enterprise CustomerHistory CustomerStatus CustomerSource CustomerSegment CustomerRiskLevel Migration customer_enterprise ---- ====== Sprint 3-B.1 — Création du CustomerModule ====== ===== Objectif ===== Implémenter le premier module CRM métier complet basé sur : Customer avec : CRUD Clients Recherche CRM Pagination Tri Filtres Multi-Tenant Security Swagger ---- ====== Architecture ====== ===== Créer ===== src/modules/customers ---- ===== Structure ===== customers ├── application │ │ └── dto │ │ ├── create-customer.dto.ts │ ├── update-customer.dto.ts │ ├── customer-query.dto.ts │ └── customer-response.dto.ts │ ├── domain │ │ └── services │ │ └── customer.service.ts │ ├── presentation │ │ └── controllers │ │ └── customer.controller.ts │ └── customer.module.ts ---- ====== Sprint 3-B.1-A ====== ===== DTOs ===== ---- ====== Étape 1 — CreateCustomerDto ====== ===== Créer ===== create-customer.dto.ts ---- ===== Implémentation ===== export class CreateCustomerDto { firstName: string; lastName: string; email?: string; phone?: string; mobilePhone?: string; companyName?: string; language?: string; source?: string; marketingConsent?: boolean; } ---- ====== Étape 2 — UpdateCustomerDto ====== ===== Créer ===== update-customer.dto.ts ---- ===== Implémentation ===== export class UpdateCustomerDto extends PartialType( CreateCustomerDto ) {} ---- ====== Étape 3 — CustomerQueryDto ====== ===== Créer ===== customer-query.dto.ts ---- ===== Ajouter ===== export class CustomerQueryDto { page?: number = 1; limit?: number = 25; search?: string; status?: string; segment?: string; source?: string; vip?: boolean; sortBy?: string = 'createdAt'; sortOrder?: 'asc' | 'desc' = 'desc'; } ---- ====== Étape 4 — CustomerResponseDto ====== ===== Créer ===== customer-response.dto.ts ---- ===== Ajouter ===== export class CustomerResponseDto { id: string; firstName: string; lastName: string; email?: string; phone?: string; status: string; segment: string; customerScore: number; lifetimeValue?: number; vip: boolean; createdAt: Date; } ---- ====== Sprint 3-B.1-B ====== ===== CustomerService ===== ---- ====== Étape 5 — Création ====== ===== Créer ===== customer.service.ts ---- ===== Injection ===== @Injectable() export class CustomerService { constructor( private readonly prisma: PrismaService ) {} } ---- ====== Étape 6 — Méthodes ====== ===== Ajouter ===== findAll() findOne() create() update() remove() ---- ====== Étape 7 — Multi-Tenant Security ====== ===== Principe ===== Aucune requête CRM ne doit sortir du tenant. ---- ===== Exemple ===== where: { tenantId: currentTenantId } ---- ===== Obligatoire ===== Dans : Toutes les requêtes ---- ====== Étape 8 — Recherche CRM ====== ===== Recherche globale ===== OR: [ { firstName: { contains: search, mode: 'insensitive' } }, { lastName: { contains: search, mode: 'insensitive' } }, { email: { contains: search, mode: 'insensitive' } }, { companyName: { contains: search, mode: 'insensitive' } } ] ---- ====== Étape 9 — Filtres ====== ===== Ajouter ===== status segment source vip ---- ===== Exemple ===== if (query.vip !== undefined) { where.vip = query.vip; } ---- ====== Étape 10 — Pagination ====== ===== Calcul ===== const skip = (page - 1) * limit; ---- ===== Prisma ===== skip, take: limit ---- ====== Étape 11 — Tri ====== ===== Ajouter ===== orderBy: { [query.sortBy]: query.sortOrder } ---- ====== Étape 12 — findAll ====== ===== Implémentation ===== async findAll( tenantId: string, query: CustomerQueryDto ) ---- ===== Retour ===== return { data: customers, meta: { page, limit, total } }; ---- ====== Étape 13 — findOne ====== ===== Implémentation ===== async findOne( tenantId: string, id: string ) ---- ===== Sécurité ===== where: { id, tenantId } ---- ===== Sinon ===== throw new NotFoundException( 'Customer not found' ); ---- ====== Étape 14 — create ====== ===== Génération CRM ===== customerNumber = `CUS-${Date.now()}` ---- ===== Création ===== await prisma.customer.create({ data: { tenantId, customerNumber, ...dto } }); ---- ====== Étape 15 — CustomerPreference ====== ===== Création automatique ===== await prisma.customerPreference.create({ data: { customerId: customer.id } }); ---- ====== Étape 16 — update ====== ===== Vérifier ===== Customer existe + Même tenant ---- ===== Mise à jour ===== await prisma.customer.update(...) ---- ====== Étape 17 — remove ====== ===== Soft Delete ===== Ne jamais supprimer réellement. ---- ===== Ajouter ===== deletedAt: new Date() ---- ===== Mise à jour ===== await prisma.customer.update({ where: { id }, data: { deletedAt: new Date(), status: 'INACTIVE' } }); ---- ====== Sprint 3-B.1-C ====== ===== CustomerController ===== ---- ====== Étape 18 — Création ====== ===== Créer ===== customer.controller.ts ---- ===== Déclaration ===== @ApiTags('Customers') @Controller('customers') @UseGuards( JwtAuthGuard ) @ApiBearerAuth() ---- ====== Étape 19 — GET /customers ====== ===== Route ===== @Get() ---- ===== Paramètres ===== Recherche Pagination Filtres ---- ====== Étape 20 — GET /customers/{id} ====== ===== Route ===== @Get(':id') ---- ====== Étape 21 — POST /customers ====== ===== Route ===== @Post() ---- ====== Étape 22 — PUT /customers/{id} ====== ===== Route ===== @Put(':id') ---- ====== Étape 23 — DELETE /customers/{id} ====== ===== Route ===== @Delete(':id') ---- ====== Sprint 3-B.1-D ====== ===== CustomerModule ===== ---- ====== Étape 24 — Création ====== ===== Créer ===== customer.module.ts ---- ===== Implémentation ===== @Module({ imports: [ PrismaModule, AuthModule ], controllers: [ CustomerController ], providers: [ CustomerService ], exports: [ CustomerService ] }) export class CustomerModule {} ---- ====== Étape 25 — AppModule ====== ===== Ajouter ===== imports: [ ... CustomerModule ] ---- ====== Sprint 3-B.1-E ====== ===== Swagger ===== ---- ====== Étape 26 — Vérification ====== ===== Endpoints ===== GET /customers GET /customers/{id} POST /customers PUT /customers/{id} DELETE /customers/{id} ---- ====== Étape 27 — Exemple GET ====== ===== Requête ===== GET /customers?page=1&limit=25 ---- ===== Réponse ===== { "data": [ { "id": "xxx", "firstName": "Jean", "lastName": "Dupont", "segment": "VIP" } ], "meta": { "page": 1, "limit": 25, "total": 132 } } ---- ====== Étape 28 — Exemple POST ====== ===== Body ===== { "firstName": "Jean", "lastName": "Dupont", "email": "jean@demo.fr", "marketingConsent": true } ---- ===== Résultat ===== Customer créé CustomerPreference créée Numéro CRM généré ---- ====== Préparation Sprint 3-C ====== Ce module servira directement à : CustomerAddress CustomerDocument CustomerTag CustomerNote CustomerCommunication ---- ====== Définition de terminé ====== Le Sprint 3-B.1 est terminé lorsque : ✓ CustomerModule créé ✓ CustomerController créé ✓ CustomerService créé ✓ CRUD Clients opérationnel ✓ Recherche CRM ✓ Pagination ✓ Filtres ✓ Multi-Tenant Security ✓ Swagger documenté ✓ Soft Delete ---- ====== Livrables ====== CustomerModule CustomerController CustomerService CreateCustomerDto UpdateCustomerDto CustomerQueryDto CustomerResponseDto ---- ====== Sprint 3-B.2 — CRM Enterprise Search & Segmentation ====== ===== Objectif ===== Transformer le CRUD Clients en véritable CRM Enterprise. À l'issue de cette étape : ✓ Recherche avancée ✓ Segmentation dynamique ✓ Smart Segments ✓ Scores CRM ✓ Filtres combinés ✓ Export CSV ✓ Vues enregistrées ✓ CRM Analytics Ready ---- ====== Architecture cible ====== Customer ↓ CRM Search Engine ↓ Dynamic Filters ↓ Segmentation Engine ↓ Smart Segments ↓ Export / Campaigns / Analytics ---- ====== Sprint 3-B.2-A ====== ===== Segments CRM ===== ---- ====== Étape 1 — Création SavedCustomerView ====== ===== Ajouter dans schema.prisma ===== model SavedCustomerView { id String @id @default(uuid()) tenantId String userId String name String description String? filters Json isDefault Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tenant Tenant @relation( fields:[tenantId], references:[id] ) user User @relation( fields:[userId], references:[id] ) @@index([tenantId]) @@index([userId]) } ---- ====== Étape 2 — Création CustomerSegmentRule ====== ===== Ajouter ===== model CustomerSegmentRule { id String @id @default(uuid()) tenantId String name String code String @unique description String? conditions Json active Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tenant Tenant @relation( fields:[tenantId], references:[id] ) @@index([tenantId]) @@index([active]) } ---- ====== Étape 3 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name crm_segmentation ---- ===== Générer ===== npx prisma generate ---- ====== Sprint 3-B.2-B ====== ===== Recherche CRM Avancée ===== ---- ====== Étape 4 — Extension CustomerQueryDto ====== ===== Ajouter ===== customerScoreMin?: number; customerScoreMax?: number; lifetimeValueMin?: number; lifetimeValueMax?: number; riskLevel?: string; country?: string; language?: string; createdFrom?: Date; createdTo?: Date; lastReservationFrom?: Date; lastReservationTo?: Date; marketingConsent?: boolean; segment?: string; vip?: boolean; ---- ====== Étape 5 — Recherche multi-critères ====== ===== Exemple ===== AND: [ status, segment, vip, marketingConsent, riskLevel ] ---- ===== Recherche texte ===== OR: [ firstName, lastName, email, companyName, customerNumber ] ---- ====== Étape 6 — Recherche CRM complète ====== ===== Exemple ===== VIP ET Score > 80 ET LifetimeValue > 5000€ ET MarketingConsent = true ---- ===== Résultat ===== Liste filtrée ---- ====== Sprint 3-B.2-C ====== ===== CRM Score Engine ===== ---- ====== Étape 7 — Création ====== crm-score.service.ts ---- ===== Méthodes ===== calculateCustomerScore() calculateEngagementScore() calculateLoyaltyScore() ---- ====== Étape 8 — Exemple Score ====== Réservations +30 Paiements +20 Avis positifs +15 Ancienneté +20 Marketing +15 ---- ===== Total ===== 100 ---- ====== Étape 9 — Classification ====== 0-25 LOW 26-50 NORMAL 51-75 GOOD 76-100 EXCELLENT ---- ====== Sprint 3-B.2-D ====== ===== Smart Segments ===== ---- ====== Étape 10 — Segments automatiques ====== ===== Créer ===== crm-segmentation.service.ts ---- ===== Segments ===== VIP Frequent Travelers Corporate High Revenue Inactive High Risk Marketing Qualified ---- ====== Étape 11 — Segment VIP ====== ===== Règle ===== LifetimeValue > 10000 ET Score > 80 ---- ====== Étape 12 — Segment Inactif ====== ===== Règle ===== Dernière réservation > 365 jours ---- ====== Étape 13 — Segment Corporate ====== ===== Règle ===== CompanyName != null ---- ====== Sprint 3-B.2-E ====== ===== Vues enregistrées ===== ---- ====== Étape 14 — DTO ====== ===== Créer ===== create-saved-view.dto.ts ---- ===== Structure ===== export class CreateSavedViewDto { name: string; description?: string; filters: Record< string, unknown >; } ---- ====== Étape 15 — API ====== ===== Ajouter ===== GET /customers/views POST /customers/views DELETE /customers/views/{id} ---- ===== Exemple ===== Mes VIP Clients inactifs Corporate France Top Revenue ---- ====== Sprint 3-B.2-F ====== ===== Export CSV ===== ---- ====== Étape 16 — Service ====== ===== Créer ===== crm-export.service.ts ---- ===== Méthodes ===== exportCsv() exportExcel() ---- ====== Étape 17 — Colonnes ====== CustomerNumber FirstName LastName Email Segment Score LifetimeValue Status ---- ====== Étape 18 — Endpoint ====== ===== Ajouter ===== GET /customers/export ---- ===== Paramètres ===== Même filtres CRM ---- ====== Sprint 3-B.2-G ====== ===== API CRM Enterprise ===== ---- ====== Étape 19 — Nouveaux endpoints ====== GET /customers/search GET /customers/export GET /customers/views POST /customers/views DELETE /customers/views/{id} GET /customers/segments POST /customers/segments/recalculate ---- ====== Étape 20 — Exemple recherche ====== ===== Requête ===== GET /customers/search ---- ===== Paramètres ===== segment=VIP scoreMin=80 marketingConsent=true country=FR ---- ===== Résultat ===== Liste CRM filtrée ---- ====== Sprint 3-B.2-H ====== ===== Multi-Tenant Security ===== ---- ====== Étape 21 — Obligatoire ===== Toutes les requêtes : tenantId doivent être injectées automatiquement. ---- ===== Vérification ===== SavedCustomerView CustomerSegmentRule Customer Export ---- ====== Étape 22 — Audit ====== ===== Journaliser ===== CRM_SEARCH CRM_EXPORT CRM_SEGMENT_UPDATE CRM_VIEW_CREATE dans : AuditLog ---- ====== Sprint 3-B.2-I ====== ===== Préparation Marketing ===== ---- ===== Compatible ===== Campaign CampaignRecipient MarketingSegment AutomationRule Recommendation ---- ===== Préparation IA ===== Compatible avec : Customer Scoring Recommendations Lead Scoring Predictive Segmentation ---- ====== Définition de terminé ====== Le Sprint 3-B.2 est terminé lorsque : ✓ Recherche avancée ✓ Segmentation dynamique ✓ Smart Segments ✓ CRM Score Engine ✓ Export CSV ✓ Vues enregistrées ✓ Audit CRM ✓ Swagger documenté ---- ====== Livrables ====== SavedCustomerView CustomerSegmentRule CrmScoreService CrmSegmentationService CrmExportService CRM Search API CRM Segments API CRM Views API ---- ====== Sprint 3-C.1 — Gestion des Adresses Client ====== ===== Objectif ===== Implémenter la gestion complète des adresses CRM client basée sur : CustomerAddress avec : CRUD Adresses Adresse principale Géolocalisation Validation avancée Multi-Tenant Security Historisation CRM ---- ====== Architecture ====== ===== Créer ===== src/modules/customer-addresses ---- ===== Structure ===== customer-addresses ├── application │ │ └── dto │ │ ├── create-customer-address.dto.ts │ ├── update-customer-address.dto.ts │ └── customer-address-response.dto.ts │ ├── domain │ │ └── services │ │ └── customer-address.service.ts │ ├── presentation │ │ └── controllers │ │ └── customer-address.controller.ts │ └── customer-address.module.ts ---- ====== Sprint 3-C.1-A ====== ===== DTOs ===== ---- ====== Étape 1 — CreateCustomerAddressDto ====== ===== Créer ===== create-customer-address.dto.ts ---- ===== Implémentation ===== export class CreateCustomerAddressDto { label: string; addressLine1: string; addressLine2?: string; postalCode: string; city: string; state?: string; country: string; isDefault?: boolean; } ---- ====== Étape 2 — UpdateCustomerAddressDto ====== ===== Créer ===== update-customer-address.dto.ts ---- ===== Implémentation ===== export class UpdateCustomerAddressDto extends PartialType( CreateCustomerAddressDto ) {} ---- ====== Étape 3 — CustomerAddressResponseDto ====== ===== Créer ===== customer-address-response.dto.ts ---- ===== Ajouter ===== export class CustomerAddressResponseDto { id: string; label: string; addressLine1: string; postalCode: string; city: string; country: string; latitude?: number; longitude?: number; formattedAddress?: string; isDefault: boolean; createdAt: Date; } ---- ====== Sprint 3-C.1-B ====== ===== CustomerAddressService ===== ---- ====== Étape 4 — Création ====== ===== Créer ===== customer-address.service.ts ---- ===== Injection ===== @Injectable() export class CustomerAddressService { constructor( private readonly prisma: PrismaService, private readonly geocodingService: GeocodingService ) {} } ---- ====== Étape 5 — Méthodes ====== ===== Ajouter ===== findAll() create() update() remove() setDefault() ---- ====== Étape 6 — Vérification CRM ====== ===== Vérifier ===== Le client appartient au tenant. ---- ===== Requête ===== const customer = await prisma.customer.findFirst({ where: { id: customerId, tenantId } }); ---- ===== Sinon ===== throw new NotFoundException( 'Customer not found' ); ---- ====== Étape 7 — Recherche adresses ====== ===== Implémentation ===== async findAll( tenantId: string, customerId: string ) ---- ===== Requête ===== return prisma.customerAddress.findMany({ where: { customerId }, orderBy: [ { isDefault: 'desc' }, { createdAt: 'desc' } ] }); ---- ====== Sprint 3-C.1-C ====== ===== Adresse principale ===== ---- ====== Étape 8 — Reset adresse principale ====== ===== Ajouter ===== private async resetDefaultAddress( customerId: string ) ---- ===== Implémentation ===== await prisma.customerAddress.updateMany({ where: { customerId }, data: { isDefault: false } }); ---- ====== Étape 9 — Création ====== ===== Si ===== dto.isDefault === true ---- ===== Exécuter ===== await resetDefaultAddress( customerId ); ---- ====== Étape 10 — Première adresse ====== ===== Si aucune adresse ===== count === 0 ---- ===== Alors ===== isDefault = true ---- ====== Sprint 3-C.1-D ====== ===== Géolocalisation ===== ---- ====== Étape 11 — Construction adresse ====== ===== Ajouter ===== const fullAddress = `${dto.addressLine1} ${dto.postalCode} ${dto.city} ${dto.country}`; ---- ====== Étape 12 — Géocoder ====== ===== Utiliser ===== await geocodingService.geocode( fullAddress ); ---- ===== Retour ===== latitude longitude formattedAddress placeId ---- ====== Étape 13 — Gestion erreur ====== ===== Fallback ===== Si : OpenStreetMap indisponible ---- ===== Alors ===== Créer quand même l'adresse. ---- ===== Valeurs ===== latitude = null longitude = null ---- ====== Sprint 3-C.1-E ====== ===== Validation avancée ===== ---- ====== Étape 14 — Validation pays ====== ===== Réutiliser ===== SUPPORTED_COUNTRIES ---- ====== Étape 15 — Validation code postal ====== ===== Réutiliser ===== PostalCodeValidator ---- ====== Étape 16 — Validation géographique ====== ===== Vérifier ===== Ville Code postal Pays sont cohérents avec : GeocodingResult ---- ===== Sinon ===== throw new BadRequestException( 'Address validation failed' ); ---- ====== Sprint 3-C.1-F ====== ===== Historisation CRM ===== ---- ====== Étape 17 — CustomerHistory ====== ===== Ajouter ===== Lors de : CREATE UPDATE DELETE ---- ===== Exemple ===== await prisma.customerHistory.create({ data: { customerId, changedField: 'address', oldValue: oldAddress, newValue: newAddress } }); ---- ====== Étape 18 — AuditLog ====== ===== Journaliser ===== CUSTOMER_ADDRESS_CREATED CUSTOMER_ADDRESS_UPDATED CUSTOMER_ADDRESS_DELETED CUSTOMER_ADDRESS_DEFAULT_CHANGED ---- ====== Sprint 3-C.1-G ====== ===== Update ===== ---- ====== Étape 19 — Contrôle tenant ====== ===== Vérifier ===== Customer Adresse Tenant avant toute modification. ---- ====== Étape 20 — Mise à jour ====== ===== Si ===== dto.isDefault = true ---- ===== Alors ===== resetDefaultAddress() ---- ===== Puis ===== update() ---- ====== Étape 21 — Delete ====== ===== Soft Delete recommandé ===== Ajouter dans Prisma : deletedAt DateTime? à : CustomerAddress ---- ===== Suppression ===== deletedAt: new Date() ---- ====== Sprint 3-C.1-H ====== ===== CustomerAddressController ===== ---- ====== Étape 22 — Création ====== ===== Créer ===== customer-address.controller.ts ---- ===== Déclaration ===== @ApiTags('Customer Addresses') @Controller( 'customers/:id/addresses' ) @UseGuards( JwtAuthGuard ) @ApiBearerAuth() ---- ====== Étape 23 — GET ====== ===== Route ===== GET /customers/{id}/addresses ---- ====== Étape 24 — POST ====== ===== Route ===== POST /customers/{id}/addresses ---- ====== Étape 25 — PUT ====== ===== Route ===== PUT /customers/{id}/addresses/{addressId} ---- ====== Étape 26 — DELETE ====== ===== Route ===== DELETE /customers/{id}/addresses/{addressId} ---- ====== Sprint 3-C.1-I ====== ===== CustomerAddressModule ===== ---- ====== Étape 27 — Création ====== ===== Créer ===== customer-address.module.ts ---- ===== Implémentation ===== @Module({ imports: [ PrismaModule, AuthModule, GeocodingModule ], controllers: [ CustomerAddressController ], providers: [ CustomerAddressService ], exports: [ CustomerAddressService ] }) export class CustomerAddressModule {} ---- ====== Étape 28 — Swagger ====== ===== Vérifier ===== GET /customers/{id}/addresses POST /customers/{id}/addresses PUT /customers/{id}/addresses/{addressId} DELETE /customers/{id}/addresses/{addressId} ---- ====== Étape 29 — Exemple POST ====== ===== Body ===== { "label": "Residence", "addressLine1": "10 Rue Victor Hugo", "postalCode": "75001", "city": "Paris", "country": "FR", "isDefault": true } ---- ===== Résultat ===== Adresse créée Adresse principale définie Coordonnées GPS calculées Historique CRM enregistré ---- ====== Préparation Sprint 3-D ====== Les adresses client seront utilisées par : Reservations Invoices Documents Marketing CRM Analytics ---- ====== Définition de terminé ====== Le Sprint 3-C.1 est terminé lorsque : ✓ CustomerAddressModule créé ✓ CustomerAddressController créé ✓ CustomerAddressService créé ✓ CRUD adresses opérationnel ✓ Adresse principale opérationnelle ✓ Géolocalisation opérationnelle ✓ Validation avancée ✓ Historisation CRM ✓ AuditLog intégré ✓ Swagger documenté ---- ====== Livrables ====== CustomerAddressModule CustomerAddressController CustomerAddressService CreateCustomerAddressDto UpdateCustomerAddressDto CustomerAddressResponseDto ---- ====== Sprint 3-C.2 — Adresses Enterprise & Cartographie CRM ====== ===== Objectif ===== Transformer le système d'adresses CRM en moteur géospatial Enterprise. À l'issue de cette étape : ✓ Multi-adresses ✓ Zones géographiques ✓ Distance client ✓ Recherche par rayon ✓ Clustering géographique ✓ Cartographie CRM ✓ Heatmaps ✓ Géo-segmentation ---- ====== Architecture cible ====== Customer ↓ CustomerAddress ↓ Geo Engine ↓ Spatial Queries ↓ Maps ↓ CRM Analytics ---- ====== Sprint 3-C.2-A ====== ===== Extension Prisma ===== ---- ====== Étape 1 — Création GeoZone ====== ===== Ajouter ===== model GeoZone { id String @id @default(uuid()) tenantId String code String name String description String? zoneType GeoZoneType country String? region String? city String? polygon Json? centerLatitude Decimal? @db.Decimal(10,7) centerLongitude Decimal? @db.Decimal(10,7) radiusKm Decimal? @db.Decimal(10,2) active Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tenant Tenant @relation( fields:[tenantId], references:[id] ) @@index([tenantId]) @@index([zoneType]) @@index([active]) } ---- ====== Étape 2 — Enum GeoZoneType ====== ===== Ajouter ===== enum GeoZoneType { COUNTRY REGION CITY CUSTOM SALES MARKETING DELIVERY } ---- ====== Étape 3 — Extension CustomerAddress ====== ===== Ajouter ===== geoHash String? geoValidated Boolean @default(false) geoValidatedAt DateTime? timezone String? district String? ---- ====== Étape 4 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name crm_geospatial ---- ===== Générer ===== npx prisma generate ---- ====== Sprint 3-C.2-B ====== ===== GeoSpatial Module ===== ---- ====== Étape 5 — Création ====== src/modules/geospatial ---- ===== Structure ===== geospatial ├── domain │ │ └── services │ │ ├── geo-distance.service.ts │ │ ├── geo-search.service.ts │ │ ├── geo-clustering.service.ts │ │ └── geo-zone.service.ts │ └── geospatial.module.ts ---- ====== Étape 6 — Dépendances ====== ===== Installer ===== npm install geolib npm install ngeohash ---- ====== Sprint 3-C.2-C ====== ===== Distance Client ===== ---- ====== Étape 7 — GeoDistanceService ====== ===== Créer ===== geo-distance.service.ts ---- ===== Méthodes ===== calculateDistance() calculateTravelRadius() findNearestCustomers() ---- ====== Étape 8 — Calcul ====== ===== Exemple ===== getDistance( { latitude: lat1, longitude: lng1 }, { latitude: lat2, longitude: lng2 } ) ---- ===== Retour ===== Distance en kilomètres ---- ====== Étape 9 — Cas d'usage ====== Client ↔ Propriété Client ↔ Agence Client ↔ Région Client ↔ Zone commerciale ---- ====== Sprint 3-C.2-D ====== ===== Recherche par rayon ===== ---- ====== Étape 10 — Endpoint ====== ===== Ajouter ===== GET /customers/search/radius ---- ===== Paramètres ===== latitude longitude radiusKm ---- ====== Étape 11 — Service ====== ===== Ajouter ===== findCustomersInRadius( tenantId, lat, lng, radiusKm ) ---- ===== Retour ===== Tous les clients dans le rayon demandé ---- ====== Étape 12 — Exemple ====== ===== Recherche ===== Paris 50 km ---- ===== Retour ===== Clients Paris Clients Versailles Clients Saint-Denis ---- ====== Sprint 3-C.2-E ====== ===== Clustering CRM ===== ---- ====== Étape 13 — GeoClusteringService ====== ===== Créer ===== geo-clustering.service.ts ---- ===== Méthodes ===== clusterCustomers() clusterByCity() clusterByRegion() ---- ====== Étape 14 — Types ====== Ville Région Pays Distance Segment CRM ---- ====== Étape 15 — Exemple ====== ===== Résultat ===== { "cluster":"Paris", "customers":421 } ---- ====== Sprint 3-C.2-F ====== ===== Cartographie CRM ===== ---- ====== Étape 16 — DTO ====== ===== Créer ===== customer-map-point.dto.ts ---- ===== Structure ===== export class CustomerMapPointDto { customerId: string; customerNumber: string; latitude: number; longitude: number; city: string; segment: string; customerScore: number; } ---- ====== Étape 17 — Endpoint ====== ===== Ajouter ===== GET /customers/map ---- ===== Retour ===== Points cartographiques CRM ---- ====== Étape 18 — Préparation Front ====== Compatible : Leaflet Mapbox Google Maps OpenLayers ---- ====== Sprint 3-C.2-G ====== ===== Heatmaps CRM ===== ---- ====== Étape 19 — Endpoint ====== ===== Ajouter ===== GET /customers/heatmap ---- ===== Retour ===== Densité clients par zone géographique ---- ====== Étape 20 — Agrégation ====== ===== Calcul ===== Nombre clients par géohash ou par ville ---- ===== Exemple ===== [ { "city":"Paris", "count":421 }, { "city":"Lyon", "count":187 } ] ---- ====== Sprint 3-C.2-H ====== ===== Zones Marketing ===== ---- ====== Étape 21 — Gestion GeoZone ====== ===== Endpoints ===== GET /geo-zones POST /geo-zones PUT /geo-zones/{id} DELETE /geo-zones/{id} ---- ====== Étape 22 — Segmentation ====== ===== Exemple ===== Zone Paris ↓ Clients VIP ↓ Campagne Marketing ---- ====== Étape 23 — Attribution automatique ====== ===== Workflow ===== Adresse Client ↓ GeoZone Matching ↓ Segment Géographique ↓ Marketing ---- ====== Sprint 3-C.2-I ====== ===== CRM Analytics ===== ---- ====== Étape 24 — Dashboard ====== ===== Ajouter ===== GET /customers/geographic-statistics ---- ===== Retour ===== { "countries":12, "regions":38, "cities":142, "topCity":"Paris" } ---- ====== Étape 25 — Métriques ====== Top villes Top régions Répartition pays Répartition segments Lifetime Value géographique ---- ====== Sprint 3-C.2-J ====== ===== Audit & Sécurité ===== ---- ====== Étape 26 — Journaliser ====== Dans : AuditLog ---- ===== Événements ===== CRM_GEO_SEARCH CRM_MAP_VIEW CRM_HEATMAP_VIEW CRM_ZONE_CREATED CRM_ZONE_UPDATED ---- ====== Étape 27 — Multi-Tenant ====== ===== Obligatoire ===== Toutes les requêtes : tenantId doivent filtrer : GeoZone Customer CustomerAddress ---- ====== Préparation Sprint 9 ====== Compatible avec : Campaign MarketingSegment CampaignRecipient ---- ====== Préparation Sprint 13 ====== Compatible avec : Recommendation AutomationScenario AI Segmentation ---- ====== Définition de terminé ====== Le Sprint 3-C.2 est terminé lorsque : ✓ GeoZone créée ✓ Distance Client ✓ Recherche par rayon ✓ Clustering CRM ✓ Cartographie CRM ✓ Heatmaps ✓ Dashboard géographique ✓ Multi-Tenant Security ✓ Swagger documenté ---- ====== Livrables ====== GeoZone GeoDistanceService GeoSearchService GeoClusteringService GeoZoneService CRM Map API CRM Heatmap API CRM Geographic Analytics ---- ====== Sprint 3-D.1 — Gestion des Documents Client ====== ===== Objectif ===== Implémenter la gestion documentaire CRM complète basée sur : CustomerDocument avec : Upload Stockage MinIO/S3 Catégorisation Validation documentaire Historisation Audit RGPD ---- ====== Architecture cible ====== Customer ↓ CustomerDocument ↓ StorageService ↓ MinIO / S3 ↓ CRM / Reservations / Compliance ---- ====== Sprint 3-D.1-A ====== ===== Modèle Prisma ===== ---- ====== Étape 1 — Création CustomerDocument ====== ===== Ajouter dans schema.prisma ===== model CustomerDocument { id String @id @default(uuid()) tenantId String customerId String documentType CustomerDocumentType category String? name String originalFilename String storagePath String mimeType String fileSize Int checksum String? version Int @default(1) status DocumentStatus @default(PENDING) expiresAt DateTime? verifiedAt DateTime? verifiedBy String? uploadedBy String? metadata Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? tenant Tenant @relation( fields:[tenantId], references:[id] ) customer Customer @relation( fields:[customerId], references:[id], onDelete:Cascade ) @@index([tenantId]) @@index([customerId]) @@index([documentType]) @@index([status]) @@index([expiresAt]) } ---- ====== Étape 2 — Enum DocumentType ====== ===== Ajouter ===== enum CustomerDocumentType { IDENTITY_CARD PASSPORT DRIVING_LICENSE VISA RESIDENCE_PERMIT CONTRACT INVOICE PROOF_OF_ADDRESS INSURANCE TAX_DOCUMENT OTHER } ---- ====== Étape 3 — Enum DocumentStatus ====== ===== Ajouter ===== enum DocumentStatus { PENDING VERIFIED REJECTED EXPIRED ARCHIVED } ---- ====== Étape 4 — Relation Customer ====== ===== Ajouter ===== Dans : model Customer documents CustomerDocument[] ---- ====== Étape 5 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name customer_documents ---- ===== Générer ===== npx prisma generate ---- ====== Sprint 3-D.1-B ====== ===== Module ====== ---- ====== Étape 6 — Création ====== src/modules/customer-documents ├── application │ │ └── dto │ │ ├── upload-customer-document.dto.ts │ └── customer-document-response.dto.ts │ ├── domain │ │ └── services │ │ └── customer-document.service.ts │ ├── presentation │ │ └── controllers │ │ └── customer-document.controller.ts │ └── customer-document.module.ts ---- ====== Sprint 3-D.1-C ====== ===== DTOs ===== ---- ====== Étape 7 — Upload DTO ====== ===== Créer ===== upload-customer-document.dto.ts ---- ===== Ajouter ===== export class UploadCustomerDocumentDto { documentType: CustomerDocumentType; category?: string; expiresAt?: Date; } ---- ====== Étape 8 — Response DTO ====== ===== Créer ===== customer-document-response.dto.ts ---- ===== Ajouter ===== export class CustomerDocumentResponseDto { id: string; name: string; documentType: string; status: string; mimeType: string; fileSize: number; createdAt: Date; } ---- ====== Sprint 3-D.1-D ====== ===== Validation documentaire ===== ---- ====== Étape 9 — Types autorisés ====== ===== Créer ===== shared/constants document-mime-types.ts ---- ===== Ajouter ===== export const ALLOWED_DOCUMENT_TYPES = [ 'application/pdf', 'image/jpeg', 'image/png', 'image/webp' ]; ---- ====== Étape 10 — Taille maximale ====== ===== Ajouter ===== export const MAX_DOCUMENT_SIZE = 20 * 1024 * 1024; ---- ====== Étape 11 — Validation ====== ===== Vérifier ===== mimetype size ---- ===== Rejeter ===== EXE ZIP JS BAT SH ---- ====== Sprint 3-D.1-E ====== ===== CustomerDocumentService ===== ---- ====== Étape 12 — Création ====== ===== Créer ===== customer-document.service.ts ---- ===== Injection ===== @Injectable() export class CustomerDocumentService { constructor( private readonly prisma: PrismaService, private readonly storageService: StorageService ) {} } ---- ====== Étape 13 — Méthodes ====== ===== Ajouter ===== findAll() upload() remove() verify() generateDownloadUrl() ---- ====== Étape 14 — Upload ====== ===== Chemin ===== customers/ {customerId}/ documents/ {uuid} ---- ===== Upload MinIO ===== const storagePath = await storageService .uploadDocument( file, customerId ); ---- ====== Étape 15 — Enregistrement ====== ===== Créer ===== await prisma.customerDocument.create({ data: { tenantId, customerId, documentType, storagePath, mimeType: file.mimetype, fileSize: file.size, status: 'PENDING' } }); ---- ====== Étape 16 — URL sécurisée ====== ===== Générer ===== generateDownloadUrl() ---- ===== Utiliser ===== Presigned URL Expiration 1h ---- ====== Sprint 3-D.1-F ====== ===== Historisation CRM ===== ---- ====== Étape 17 — CustomerHistory ====== ===== Ajouter ===== DOCUMENT_UPLOADED DOCUMENT_VERIFIED DOCUMENT_DELETED ---- ===== Exemple ===== changedField: 'document' ---- ====== Étape 18 — Audit ====== ===== Ajouter ===== Dans : AuditLog ---- ===== Événements ===== CUSTOMER_DOCUMENT_UPLOAD CUSTOMER_DOCUMENT_VERIFY CUSTOMER_DOCUMENT_DELETE ---- ====== Sprint 3-D.1-G ====== ===== Contrôleur ===== ---- ====== Étape 19 — Création ====== ===== Créer ===== customer-document.controller.ts ---- ===== Déclaration ===== @ApiTags( 'Customer Documents' ) @Controller( 'customers/:id/documents' ) @UseGuards( JwtAuthGuard ) @ApiBearerAuth() ---- ====== Étape 20 — GET ====== ===== Route ===== GET /customers/{id}/documents ---- ====== Étape 21 — POST ====== ===== Route ===== POST /customers/{id}/documents ---- ===== Upload ===== @UseInterceptors( FileInterceptor( 'file' ) ) ---- ====== Étape 22 — DELETE ====== ===== Route ===== DELETE /customers/{id}/documents/{documentId} ---- ====== Étape 23 — Download ====== ===== Ajouter ===== GET /customers/{id}/documents/{documentId}/download ---- ====== Sprint 3-D.1-H ====== ===== Vérification documentaire ===== ---- ====== Étape 24 — Endpoint ====== ===== Ajouter ===== PUT /customers/{id}/documents/{documentId}/verify ---- ===== Action ===== Status ↓ VERIFIED ---- ===== Métadonnées ===== verifiedAt verifiedBy ---- ====== Étape 25 — Expiration ====== ===== Vérifier ===== Passport Visa Insurance ---- ===== Automatisation future ===== Créer alertes : 30 jours avant expiration ---- ====== Sprint 3-D.1-I ====== ===== Module ===== ---- ====== Étape 26 — Création ====== ===== Créer ===== customer-document.module.ts ---- ===== Implémentation ===== @Module({ imports: [ PrismaModule, AuthModule, StorageModule ], controllers: [ CustomerDocumentController ], providers: [ CustomerDocumentService ], exports: [ CustomerDocumentService ] }) export class CustomerDocumentModule {} ---- ====== Étape 27 — Swagger ====== ===== Vérifier ===== GET /customers/{id}/documents POST /customers/{id}/documents DELETE /customers/{id}/documents/{documentId} GET /customers/{id}/documents/{documentId}/download PUT /customers/{id}/documents/{documentId}/verify ---- ====== Étape 28 — Exemple ====== ===== Upload ===== Passeport.pdf ---- ===== Résultat ===== Document stocké MinIO Status=PENDING Historique CRM créé Audit créé ---- ====== Préparation Sprint 19 ====== Compatible avec : Consent ComplianceAudit RetentionPolicy DataClassification ---- ====== Préparation Sprint 13 ====== Compatible avec : OCR Document AI Extraction automatique Classification automatique ---- ====== Définition de terminé ====== Le Sprint 3-D.1 est terminé lorsque : ✓ CustomerDocument créé ✓ Upload opérationnel ✓ MinIO/S3 intégré ✓ Validation documentaire ✓ Vérification documentaire ✓ AuditLog intégré ✓ Historisation CRM ✓ URLs sécurisées ✓ Swagger documenté ---- ====== Livrables ====== CustomerDocument CustomerDocumentModule CustomerDocumentController CustomerDocumentService Document Validation MinIO Integration Secure Download URLs ---- ====== Sprint 3-D.2 — Gestion Documentaire Enterprise ====== ===== Objectif ===== Faire évoluer le système documentaire CRM vers une GED Enterprise complète. À l'issue de cette étape : ✓ Versioning ✓ OCR ✓ Classification automatique ✓ Extraction de données ✓ Expiration automatique ✓ Workflow de validation ✓ Signature électronique ✓ Conformité RGPD ✓ Préparation ISO27001 ---- ====== Architecture cible ====== Document Upload ↓ OCR Engine ↓ Classification Engine ↓ Extraction Engine ↓ Validation Workflow ↓ Storage ↓ Compliance ---- ====== Sprint 3-D.2-A ====== ===== Extension Prisma ===== ---- ====== Étape 1 — Versioning documentaire ====== ===== Ajouter dans CustomerDocument ===== parentDocumentId String? documentVersion Int @default(1) isLatestVersion Boolean @default(true) supersededAt DateTime? ---- ====== Étape 2 — Relation Version ====== ===== Ajouter ===== parentDocument CustomerDocument? @relation( "DocumentVersions", fields:[parentDocumentId], references:[id] ) versions CustomerDocument[] @relation( "DocumentVersions" ) ---- ====== Étape 3 — OCR ====== ===== Ajouter ===== ocrStatus OcrStatus @default(PENDING) ocrText String? ocrExecutedAt DateTime? ---- ====== Étape 4 — Classification ====== ===== Ajouter ===== classificationScore Float? classificationSource String? detectedDocumentType String? ---- ====== Étape 5 — Extraction ====== ===== Ajouter ===== extractedData Json? extractionStatus String? ---- ====== Étape 6 — Signature ====== ===== Ajouter ===== signatureRequired Boolean @default(false) signedAt DateTime? signatureProvider String? signatureReference String? ---- ====== Étape 7 — Enum OCR ====== ===== Ajouter ===== enum OcrStatus { PENDING PROCESSING COMPLETED FAILED } ---- ====== Étape 8 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name customer_documents_enterprise ---- ===== Générer ===== npx prisma generate ---- ====== Sprint 3-D.2-B ====== ===== GED Workflow ===== ---- ====== Étape 9 — Création DocumentWorkflow ====== ===== Ajouter ===== model DocumentWorkflow { id String @id @default(uuid()) tenantId String name String documentType String active Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tenant Tenant @relation( fields:[tenantId], references:[id] ) steps DocumentWorkflowStep[] } ---- ====== Étape 10 — Workflow Steps ====== ===== Ajouter ===== model DocumentWorkflowStep { id String @id @default(uuid()) workflowId String name String stepOrder Int validatorRole String? required Boolean @default(true) workflow DocumentWorkflow @relation( fields:[workflowId], references:[id], onDelete:Cascade ) @@index([workflowId]) @@index([stepOrder]) } ---- ====== Étape 11 — Workflow Instance ====== ===== Ajouter ===== model CustomerDocumentWorkflow { id String @id @default(uuid()) documentId String currentStep Int @default(1) status WorkflowStatus @default(PENDING) startedAt DateTime @default(now()) completedAt DateTime? document CustomerDocument @relation( fields:[documentId], references:[id] ) } ---- ====== Étape 12 — Enum Workflow ====== ===== Ajouter ===== enum WorkflowStatus { PENDING IN_PROGRESS APPROVED REJECTED CANCELLED } ---- ====== Sprint 3-D.2-C ====== ===== OCR Module ===== ---- ====== Étape 13 — Création ====== src/modules/document-ai ---- ===== Structure ===== document-ai ├── domain │ │ └── services │ │ ├── ocr.service.ts │ │ ├── document-classifier.service.ts │ │ ├── extraction.service.ts │ │ └── expiration-monitor.service.ts │ └── document-ai.module.ts ---- ====== Étape 14 — OCR Service ====== ===== Méthodes ===== processDocument() extractText() detectLanguage() ---- ===== Prévoir ===== Connecteurs futurs : Tesseract AWS Textract Google Vision Azure Form Recognizer ---- ====== Étape 15 — OCR Workflow ====== Upload ↓ OCR ↓ Classification ↓ Extraction ↓ Validation ↓ Archive ---- ====== Sprint 3-D.2-D ====== ===== Classification Automatique ===== ---- ====== Étape 16 — DocumentClassifier ====== ===== Méthodes ===== classify() detectPassport() detectInvoice() detectContract() ---- ====== Étape 17 — Classification ====== ===== Exemple ===== Passeport ↓ IDENTITY_DOCUMENT ---- ===== Résultat ===== classificationScore: 0.98 ---- ====== Étape 18 — Mise à jour ====== ===== Ajouter ===== detectedDocumentType classificationScore classificationSource ---- ====== Sprint 3-D.2-E ====== ===== Extraction de données ===== ---- ====== Étape 19 — ExtractionService ====== ===== Méthodes ===== extractIdentityData() extractInvoiceData() extractContractData() ---- ====== Étape 20 — Exemple ====== ===== Passeport ===== Nom Prénom Nationalité Date expiration Numéro ---- ===== Sauvegarder ===== extractedData Json ---- ====== Étape 21 — Exemple ====== ===== Facture ===== Numéro facture Montant Date TVA ---- ====== Sprint 3-D.2-F ====== ===== Expiration Automatique ===== ---- ====== Étape 22 — ExpirationMonitor ====== ===== Méthodes ===== checkExpiringDocuments() markExpiredDocuments() ---- ====== Étape 23 — Workflow ====== Tous les jours ↓ Expiration < 30 jours ↓ Notification ↓ Alert ---- ====== Étape 24 — Statut ====== ===== Mise à jour ===== EXPIRED automatiquement. ---- ====== Sprint 3-D.2-G ====== ===== Signature Électronique ===== ---- ====== Étape 25 — Préparation ====== ===== Ajouter ===== SignatureProvider ---- ===== Fournisseurs ===== DocuSign Yousign Adobe Sign ---- ====== Étape 26 — Workflow ====== Document ↓ Signature Request ↓ Signed ↓ Archive ---- ====== Étape 27 — Endpoints ====== ===== Ajouter ===== POST /customers/{id}/documents/{documentId}/sign GET /customers/{id}/documents/{documentId}/signature ---- ====== Sprint 3-D.2-H ====== ===== API GED ===== ---- ====== Étape 28 — Endpoints ====== ===== Ajouter ===== POST /documents/{id}/ocr POST /documents/{id}/classify POST /documents/{id}/extract GET /documents/{id}/workflow PUT /documents/{id}/approve PUT /documents/{id}/reject ---- ====== Étape 29 — Permissions ====== ===== RBAC ===== documents.read documents.write documents.verify documents.approve documents.sign ---- ====== Sprint 3-D.2-I ====== ===== Audit & Conformité ===== ---- ====== Étape 30 — AuditLog ====== ===== Journaliser ===== DOCUMENT_OCR DOCUMENT_CLASSIFIED DOCUMENT_EXTRACTED DOCUMENT_APPROVED DOCUMENT_REJECTED DOCUMENT_SIGNED DOCUMENT_EXPIRED ---- ====== Étape 31 — DataClassification ====== ===== Préparer ===== Compatible avec : PII IDENTITY FINANCIAL LEGAL CONFIDENTIAL ---- ====== Étape 32 — Retention ====== ===== Préparer ===== Compatible avec : RetentionPolicy ComplianceAudit GDPR ---- ====== Sprint 3-D.2-J ====== ===== Dashboard GED ===== ---- ====== Étape 33 — Statistiques ====== ===== Ajouter ===== GET /documents/statistics ---- ===== Retour ===== { "totalDocuments": 5234, "verifiedDocuments": 4987, "expiredDocuments": 74, "pendingValidation": 32, "pendingSignatures": 11 } ---- ====== Étape 34 — Recherche GED ====== ===== Ajouter ===== GET /documents/search ---- ===== Filtres ===== Type Statut Date expiration Client OCR Workflow ---- ====== Préparation Sprint 13 ====== Compatible avec : KnowledgeDocument Recommendation AI Assistant Document AI ---- ====== Préparation Sprint 19 ====== Compatible avec : ComplianceAudit DataClassification RetentionPolicy SecurityIncident ---- ====== Définition de terminé ====== Le Sprint 3-D.2 est terminé lorsque : ✓ Versioning ✓ OCR ✓ Classification automatique ✓ Extraction de données ✓ Expiration automatique ✓ Workflow validation ✓ Signature électronique ✓ Audit GED ✓ Conformité préparée ---- ====== Livrables ====== DocumentWorkflow DocumentWorkflowStep CustomerDocumentWorkflow OcrService DocumentClassifierService ExtractionService ExpirationMonitorService Enterprise GED API ---- ====== Sprint 3-E.1 — Gestion des Tags CRM ====== ===== Objectif ===== Implémenter un moteur de tags CRM permettant : Segmentation Classification Automatisation Marketing CRM Analytics Personnalisation basé sur : CustomerTag CustomerTagAssignment ---- ====== Architecture cible ====== Customer ↓ CustomerTagAssignment ↓ CustomerTag ↓ CRM Segmentation ↓ Campaigns ↓ Automation ---- ====== Sprint 3-E.1-A ====== ===== Modèle Prisma ===== ---- ====== Étape 1 — Création CustomerTag ====== ===== Ajouter dans schema.prisma ===== model CustomerTag { id String @id @default(uuid()) tenantId String name String code String description String? color String? icon String? category String? tagType CustomerTagType @default(MANUAL) active Boolean @default(true) usageCount Int @default(0) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tenant Tenant @relation( fields:[tenantId], references:[id] ) assignments CustomerTagAssignment[] @@unique([ tenantId, code ]) @@index([tenantId]) @@index([tagType]) @@index([active]) } ---- ====== Étape 2 — Création CustomerTagAssignment ====== ===== Ajouter ===== model CustomerTagAssignment { id String @id @default(uuid()) customerId String tagId String assignedBy String? assignedAt DateTime @default(now()) source String? @default("MANUAL") expiresAt DateTime? metadata Json? customer Customer @relation( fields:[customerId], references:[id], onDelete:Cascade ) tag CustomerTag @relation( fields:[tagId], references:[id], onDelete:Cascade ) @@unique([ customerId, tagId ]) @@index([customerId]) @@index([tagId]) @@index([assignedAt]) } ---- ====== Étape 3 — Enum TagType ====== ===== Ajouter ===== enum CustomerTagType { MANUAL DYNAMIC SYSTEM MARKETING LOYALTY RISK } ---- ====== Étape 4 — Relations ====== ===== Ajouter dans Customer ===== tags CustomerTagAssignment[] ---- ====== Étape 5 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name customer_tags ---- ===== Générer ===== npx prisma generate ---- ====== Sprint 3-E.1-B ====== ===== Module ===== ---- ====== Étape 6 — Création ====== src/modules/customer-tags ├── application │ │ └── dto │ │ ├── create-customer-tag.dto.ts │ │ ├── assign-customer-tag.dto.ts │ │ └── customer-tag-response.dto.ts │ ├── domain │ │ └── services │ │ └── customer-tag.service.ts │ ├── presentation │ │ └── controllers │ │ └── customer-tag.controller.ts │ └── customer-tag.module.ts ---- ====== Sprint 3-E.1-C ====== ===== DTOs ===== ---- ====== Étape 7 — CreateCustomerTagDto ====== ===== Créer ===== create-customer-tag.dto.ts ---- ===== Implémentation ===== export class CreateCustomerTagDto { name: string; code: string; description?: string; color?: string; icon?: string; category?: string; tagType?: string; } ---- ====== Étape 8 — AssignCustomerTagDto ====== ===== Créer ===== assign-customer-tag.dto.ts ---- ===== Implémentation ===== export class AssignCustomerTagDto { tagId: string; expiresAt?: Date; } ---- ====== Sprint 3-E.1-D ====== ===== CustomerTagService ===== ---- ====== Étape 9 — Méthodes ====== ===== Ajouter ===== findTags() createTag() assignTag() removeTag() getCustomerTags() recalculateUsage() ---- ====== Étape 10 — Création Tag ====== ===== Vérifier ===== Code unique par tenant ---- ===== Création ===== await prisma.customerTag.create({ data: { tenantId, ...dto } }); ---- ====== Étape 11 — Affectation ====== ===== Vérifier ===== Customer Tag Même tenant ---- ===== Affecter ===== await prisma.customerTagAssignment.create({ data: { customerId, tagId, assignedBy: userId } }); ---- ====== Étape 12 — Usage Count ====== ===== Mettre à jour ===== await prisma.customerTag.update({ where: { id: tagId }, data: { usageCount: { increment: 1 } } }); ---- ====== Étape 13 — Suppression ====== ===== Supprimer ===== CustomerTagAssignment ---- ===== Décrémenter ===== usageCount ---- ====== Sprint 3-E.1-E ====== ===== Tags Dynamiques ===== ---- ====== Étape 14 — Extension CustomerTag ====== ===== Ajouter ===== dynamicRule Json? ---- ====== Étape 15 — Exemple ====== ===== VIP ===== { "customerScore": { "gte": 80 } } ---- ===== High Revenue ===== { "lifetimeValue": { "gte": 10000 } } ---- ====== Étape 16 — Recalcul ====== ===== Méthode ===== evaluateDynamicTags() ---- ===== Déclencheurs ===== Customer Updated Reservation Created Score Updated ---- ====== Sprint 3-E.1-F ====== ===== Tags Système ===== ---- ====== Étape 17 — Tags par défaut ====== ===== Seed ===== VIP FREQUENT CORPORATE HIGH_VALUE INACTIVE BLACKLISTED HIGH_RISK NEWSLETTER LOYALTY ---- ====== Étape 18 — Attribution automatique ====== ===== Exemple ===== Segment = VIP ↓ Tag VIP ---- ===== Exemple ===== Risk = HIGH ↓ Tag HIGH_RISK ---- ====== Sprint 3-E.1-G ====== ===== Contrôleur ===== ---- ====== Étape 19 — Création ====== ===== Créer ===== customer-tag.controller.ts ---- ===== Déclaration ===== @ApiTags('Customer Tags') @Controller('customers') ---- ====== Étape 20 — Liste tags ====== ===== Route ===== GET /customers/tags ---- ====== Étape 21 — Création tag ====== ===== Route ===== POST /customers/tags ---- ====== Étape 22 — Affectation ====== ===== Route ===== POST /customers/{id}/tags ---- ====== Étape 23 — Suppression ====== ===== Route ===== DELETE /customers/{id}/tags/{tagId} ---- ====== Étape 24 — Consultation ====== ===== Ajouter ===== GET /customers/{id}/tags ---- ====== Sprint 3-E.1-H ====== ===== Recherche CRM ===== ---- ====== Étape 25 — Filtre Tags ====== ===== Ajouter dans ===== CustomerQueryDto ---- ===== Champ ===== tags?: string[]; ---- ====== Étape 26 — Recherche ====== ===== Exemple ===== VIP + NEWSLETTER ---- ===== Résultat ===== Clients correspondants ---- ====== Étape 27 — Segmentation ====== ===== Exemple ===== GET /customers/search tag=VIP ---- ===== Utilisation ===== Marketing Campagnes Automatisation ---- ====== Sprint 3-E.1-I ====== ===== Audit & Historisation ===== ---- ====== Étape 28 — CustomerHistory ====== ===== Journaliser ===== TAG_ASSIGNED TAG_REMOVED ---- ====== Étape 29 — AuditLog ====== ===== Ajouter ===== CUSTOMER_TAG_CREATED CUSTOMER_TAG_ASSIGNED CUSTOMER_TAG_REMOVED CUSTOMER_DYNAMIC_TAG_UPDATED ---- ====== Sprint 3-E.1-J ====== ===== Préparation Sprint 9 ===== ---- ===== Compatible ===== Campaign CampaignRecipient MarketingSegment MarketingEvent ---- ====== Préparation Sprint 13 ====== Compatible avec : AutomationRule Recommendation AiConversation AutomationScenario ---- ====== Préparation Sprint 20 ====== Compatible avec : Customer Analytics Predictive Segmentation Lead Scoring AI Recommendations ---- ====== Définition de terminé ====== Le Sprint 3-E.1 est terminé lorsque : ✓ CustomerTag créé ✓ CustomerTagAssignment créé ✓ Tags manuels ✓ Tags dynamiques ✓ Segmentation CRM ✓ Recherche par tags ✓ AuditLog intégré ✓ Historisation CRM ✓ Swagger documenté ---- ====== Livrables ====== CustomerTag CustomerTagAssignment CustomerTagModule CustomerTagController CustomerTagService Dynamic Tag Engine ---- ====== Sprint 3-E.2 — Segmentation CRM Avancée & Smart Tags ====== ===== Objectif ===== Transformer le moteur de tags CRM en moteur intelligent de segmentation Enterprise. À l'issue de cette étape : ✓ Tag Rules Engine ✓ Smart Tags IA ✓ Segmentation comportementale ✓ Scoring automatique ✓ Segments prédictifs ✓ Marketing Intelligence ✓ CRM Intelligence Engine ---- ====== Architecture cible ====== Customer Data ↓ Behavior Analysis ↓ Scoring Engine ↓ Tag Rules Engine ↓ Smart Segments ↓ Marketing Intelligence ↓ Automation ---- ====== Sprint 3-E.2-A ====== ===== Extension Prisma ===== ---- ====== Étape 1 — Création SmartSegment ====== ===== Ajouter dans schema.prisma ===== model SmartSegment { id String @id @default(uuid()) tenantId String name String code String description String? segmentType SmartSegmentType active Boolean @default(true) ruleDefinition Json estimatedCustomers Int @default(0) lastCalculatedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tenant Tenant @relation( fields:[tenantId], references:[id] ) @@unique([ tenantId, code ]) @@index([tenantId]) @@index([segmentType]) @@index([active]) } ---- ====== Étape 2 — Création CustomerScore ====== ===== Ajouter ===== model CustomerScore { id String @id @default(uuid()) customerId String @unique engagementScore Int @default(0) loyaltyScore Int @default(0) revenueScore Int @default(0) marketingScore Int @default(0) riskScore Int @default(0) predictiveScore Int @default(0) overallScore Int @default(0) calculatedAt DateTime @default(now()) customer Customer @relation( fields:[customerId], references:[id], onDelete:Cascade ) } ---- ====== Étape 3 — Enum SegmentType ====== ===== Ajouter ===== enum SmartSegmentType { BEHAVIORAL REVENUE LOYALTY MARKETING PREDICTIVE RISK AI_GENERATED } ---- ====== Étape 4 — Relations ====== ===== Ajouter dans Customer ===== score CustomerScore? ---- ====== Étape 5 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name crm_smart_segments ---- ===== Générer ===== npx prisma generate ---- ====== Sprint 3-E.2-B ====== ===== Tag Rules Engine ===== ---- ====== Étape 6 — Création ====== crm-tag-rules.service.ts ---- ===== Méthodes ===== evaluateRules() executeRule() assignTags() removeTags() ---- ====== Étape 7 — Structure Rule ====== ===== Exemple ===== { "conditions": [ { "field": "lifetimeValue", "operator": "gte", "value": 10000 } ], "action": { "tag": "HIGH_VALUE" } } ---- ====== Étape 8 — Opérateurs ====== eq neq gt gte lt lte contains in notIn ---- ====== Sprint 3-E.2-C ====== ===== Scoring Automatique ===== ---- ====== Étape 9 — Création ====== customer-scoring.service.ts ---- ===== Méthodes ===== calculateOverallScore() calculateEngagement() calculateLoyalty() calculateRevenue() calculateRisk() ---- ====== Étape 10 — Engagement ====== ===== Critères ===== Communications Ouvertures emails Réponses Activité CRM ---- ===== Score ===== 0 → 100 ---- ====== Étape 11 — Loyalty ====== ===== Critères ===== Ancienneté Réservations Lifetime Value VIP ---- ====== Étape 12 — Revenue ====== ===== Critères ===== Total Revenue Average Basket Frequency ---- ====== Sprint 3-E.2-D ====== ===== Smart Tags IA ===== ---- ====== Étape 13 — Création ====== smart-tag.service.ts ---- ===== Méthodes ===== generateSmartTags() predictCustomerCategory() recommendTags() ---- ====== Étape 14 — Smart Tags ====== ===== Exemples ===== HIGH_VALUE FUTURE_VIP AT_RISK LOYAL_CUSTOMER UPSELL_TARGET CHURN_RISK ---- ====== Étape 15 — Attribution ====== ===== Exemple ===== Lifetime Value élevé + Croissance forte ↓ FUTURE_VIP ---- ====== Sprint 3-E.2-E ====== ===== Segmentation Comportementale ===== ---- ====== Étape 16 — BehaviorSegmentService ====== ===== Créer ===== behavior-segmentation.service.ts ---- ===== Segments ===== Frequent Traveler Weekend Traveler Luxury Traveler Business Traveler Seasonal Traveler Family Traveler ---- ====== Étape 17 — Analyse ====== ===== Sources ===== Reservations Invoices Communications Preferences ---- ====== Étape 18 — Exemple ====== 80% réservations Vendredi → Dimanche ↓ Weekend Traveler ---- ====== Sprint 3-E.2-F ====== ===== Segments Prédictifs ===== ---- ====== Étape 19 — PredictiveSegmentation ====== ===== Créer ===== predictive-segmentation.service.ts ---- ===== Segments ===== Future VIP Future Churn Future Corporate Future High Revenue Future Ambassador ---- ====== Étape 20 — Prévision ====== ===== Critères ===== Croissance dépenses Fréquence réservations Engagement Satisfaction ---- ====== Étape 21 — Exemple ====== Croissance 30% ↓ Future VIP ---- ====== Sprint 3-E.2-G ====== ===== Marketing Intelligence ===== ---- ====== Étape 22 — Création ====== marketing-intelligence.service.ts ---- ===== Méthodes ===== findCampaignTargets() findUpsellTargets() findRetentionTargets() findReferralCandidates() ---- ====== Étape 23 — Exemples ====== ===== Upsell ===== VIP + Revenue > 5000 ↓ Campagne Premium ---- ===== Rétention ===== CHURN_RISK ↓ Campagne Réactivation ---- ====== Sprint 3-E.2-H ====== ===== API CRM Intelligence ===== ---- ====== Étape 24 — Endpoints ====== ===== Ajouter ===== GET /customers/segments/smart GET /customers/tags/smart GET /customers/scoring POST /customers/scoring/recalculate POST /customers/segments/recalculate ---- ====== Étape 25 — Exemple ====== ===== Réponse ===== { "customerId":"123", "overallScore":87, "smartTags":[ "VIP", "LOYAL_CUSTOMER", "UPSELL_TARGET" ] } ---- ====== Sprint 3-E.2-I ====== ===== Dashboard CRM Intelligence ===== ---- ====== Étape 26 — KPI ====== ===== Ajouter ===== GET /customers/intelligence/dashboard ---- ===== Retour ===== { "futureVip":54, "churnRisk":23, "upsellTargets":118, "loyalCustomers":401 } ---- ====== Étape 27 — Visualisation ====== ===== Répartition ===== Segments Scores Tags Prévisions ---- ====== Sprint 3-E.2-J ====== ===== Audit & Automatisation ===== ---- ====== Étape 28 — AuditLog ====== ===== Journaliser ===== SMART_TAG_ASSIGNED SEGMENT_RECALCULATED CUSTOMER_SCORE_UPDATED PREDICTIVE_SEGMENT_ASSIGNED ---- ====== Étape 29 — Automatisation ====== ===== Déclencheurs ===== Reservation Created Invoice Paid Customer Updated Campaign Opened ---- ===== Actions ===== Recalculate Scores Recalculate Tags Recalculate Segments ---- ====== Préparation Sprint 9 ====== Compatible avec : Campaign CampaignRecipient MarketingSegment MarketingEvent ---- ====== Préparation Sprint 13 ====== Compatible avec : Recommendation AutomationRule AutomationScenario AiConversation ---- ====== Préparation Sprint 20 ====== Compatible avec : Enterprise Analytics Customer Intelligence Predictive CRM AI Recommendations ---- ====== Définition de terminé ====== Le Sprint 3-E.2 est terminé lorsque : ✓ SmartSegment créé ✓ CustomerScore créé ✓ Tag Rules Engine ✓ Smart Tags ✓ Segmentation comportementale ✓ Segments prédictifs ✓ Marketing Intelligence ✓ Dashboard CRM Intelligence ✓ Audit intégré ---- ====== Livrables ====== SmartSegment CustomerScore CustomerScoringService SmartTagService BehaviorSegmentationService PredictiveSegmentationService MarketingIntelligenceService CRM Intelligence API ---- ====== Sprint 3-F.1 — Gestion des Notes CRM ====== ===== Objectif ===== Implémenter le système de notes CRM permettant aux équipes : Commerciales Support Réservations Finance Marketing Administration de collaborer autour d'un client. À l'issue de cette étape : ✓ Notes privées ✓ Notes publiques ✓ Historique CRM ✓ Mentions utilisateurs ✓ Audit ✓ Recherche ✓ Timeline CRM ---- ====== Architecture cible ====== Customer ↓ CustomerNote ↓ Mentions ↓ Timeline CRM ↓ Audit ↓ Collaboration ---- ====== Sprint 3-F.1-A ====== ===== Modèle Prisma ===== ---- ====== Étape 1 — Création CustomerNote ====== ===== Ajouter dans schema.prisma ===== model CustomerNote { id String @id @default(uuid()) tenantId String customerId String authorId String title String? content String visibility NoteVisibility @default(PRIVATE) noteType CustomerNoteType @default(GENERAL) pinned Boolean @default(false) edited Boolean @default(false) editedAt DateTime? metadata Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? tenant Tenant @relation( fields:[tenantId], references:[id] ) customer Customer @relation( fields:[customerId], references:[id], onDelete:Cascade ) author User @relation( fields:[authorId], references:[id] ) mentions CustomerNoteMention[] @@index([tenantId]) @@index([customerId]) @@index([authorId]) @@index([visibility]) @@index([createdAt]) } ---- ====== Étape 2 — Création CustomerNoteMention ====== ===== Ajouter ===== model CustomerNoteMention { id String @id @default(uuid()) noteId String userId String readAt DateTime? createdAt DateTime @default(now()) note CustomerNote @relation( fields:[noteId], references:[id], onDelete:Cascade ) user User @relation( fields:[userId], references:[id] ) @@unique([ noteId, userId ]) @@index([userId]) @@index([noteId]) } ---- ====== Étape 3 — Enum Visibility ====== ===== Ajouter ===== enum NoteVisibility { PRIVATE INTERNAL PUBLIC } ---- ====== Étape 4 — Enum Type ====== ===== Ajouter ===== enum CustomerNoteType { GENERAL SALES SUPPORT FINANCE MARKETING RESERVATION VIP RISK } ---- ====== Étape 5 — Relation Customer ====== ===== Ajouter ===== Dans : model Customer notes CustomerNote[] ---- ====== Étape 6 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name customer_notes ---- ===== Générer ===== npx prisma generate ---- ====== Sprint 3-F.1-B ====== ===== Module ===== ---- ====== Étape 7 — Création ====== src/modules/customer-notes ├── application │ │ └── dto │ │ ├── create-customer-note.dto.ts │ │ ├── update-customer-note.dto.ts │ │ └── customer-note-response.dto.ts │ ├── domain │ │ └── services │ │ └── customer-note.service.ts │ ├── presentation │ │ └── controllers │ │ └── customer-note.controller.ts │ └── customer-note.module.ts ---- ====== Sprint 3-F.1-C ====== ===== DTOs ===== ---- ====== Étape 8 — CreateCustomerNoteDto ====== ===== Créer ===== create-customer-note.dto.ts ---- ===== Implémentation ===== export class CreateCustomerNoteDto { title?: string; content: string; visibility?: string; noteType?: string; pinned?: boolean; mentions?: string[]; } ---- ====== Étape 9 — UpdateCustomerNoteDto ====== ===== Créer ===== update-customer-note.dto.ts ---- ===== Implémentation ===== export class UpdateCustomerNoteDto extends PartialType( CreateCustomerNoteDto ) {} ---- ====== Sprint 3-F.1-D ====== ===== CustomerNoteService ===== ---- ====== Étape 10 — Méthodes ====== ===== Ajouter ===== findAll() findOne() create() update() remove() createMentions() ---- ====== Étape 11 — Liste ====== ===== Trier ===== Pinned ↓ Date création DESC ---- ===== Prisma ===== orderBy: [ { pinned: 'desc' }, { createdAt: 'desc' } ] ---- ====== Étape 12 — Création ====== ===== Vérifier ===== Customer Tenant ---- ===== Créer ===== const note = await prisma.customerNote.create({ data: { tenantId, customerId, authorId, ...dto } }); ---- ====== Étape 13 — Mentions ====== ===== Exemple ===== @john @support @manager ---- ===== Créer ===== await prisma.customerNoteMention.createMany({ data: [...] }); ---- ====== Étape 14 — Notifications ====== ===== Déclencher ===== IN_APP EMAIL pour les utilisateurs mentionnés. ---- ====== Sprint 3-F.1-E ====== ===== Notes privées ===== ---- ====== Étape 15 — Visibilité ====== ===== PRIVATE ===== Auteur uniquement ---- ===== INTERNAL ===== Employés du tenant ---- ===== PUBLIC ===== Visible dans CRM global ---- ====== Étape 16 — Filtrage ====== ===== Vérifier ===== Avant lecture : Visibility Tenant Permissions ---- ====== Sprint 3-F.1-F ====== ===== Modification ===== ---- ====== Étape 17 — Update ====== ===== Ajouter ===== edited = true editedAt = new Date() ---- ====== Étape 18 — Historique ====== ===== Journaliser ===== Dans : CustomerHistory ---- ===== Événements ===== NOTE_CREATED NOTE_UPDATED NOTE_DELETED ---- ====== Étape 19 — Soft Delete ====== ===== Supprimer ===== deletedAt: new Date() ---- ====== Sprint 3-F.1-G ====== ===== Recherche CRM ===== ---- ====== Étape 20 — Recherche ====== ===== Ajouter ===== GET /customers/{id}/notes ---- ===== Paramètres ===== noteType visibility author search ---- ====== Étape 21 — Recherche texte ====== ===== Champs ===== title content ---- ===== Prisma ===== contains: search ---- ====== Sprint 3-F.1-H ====== ===== Contrôleur ===== ---- ====== Étape 22 — Création ====== ===== Créer ===== customer-note.controller.ts ---- ===== Déclaration ===== @ApiTags( 'Customer Notes' ) @Controller( 'customers/:id/notes' ) @UseGuards( JwtAuthGuard ) @ApiBearerAuth() ---- ====== Étape 23 — Endpoints ====== ===== Ajouter ===== GET /customers/{id}/notes POST /customers/{id}/notes PUT /customers/{id}/notes/{noteId} DELETE /customers/{id}/notes/{noteId} ---- ====== Étape 24 — Mentions ====== ===== Ajouter ===== GET /notes/mentions ---- ===== Retour ===== Mes mentions ---- ====== Sprint 3-F.1-I ====== ===== Timeline CRM ===== ---- ====== Étape 25 — Préparation ====== Les notes alimentent : Customer Timeline future. ---- ===== Événements ===== Notes Documents Tags Communications Réservations ---- ====== Étape 26 — Notes épinglées ====== ===== Utilisation ===== VIP Risques Informations critiques ---- ====== Sprint 3-F.1-J ====== ===== Audit & Sécurité ===== ---- ====== Étape 27 — AuditLog ====== ===== Journaliser ===== CUSTOMER_NOTE_CREATED CUSTOMER_NOTE_UPDATED CUSTOMER_NOTE_DELETED CUSTOMER_NOTE_PINNED CUSTOMER_MENTION_CREATED ---- ====== Étape 28 — Permissions ====== ===== Ajouter ===== customer.notes.read customer.notes.write customer.notes.delete customer.notes.manage ---- ====== Préparation Sprint 9 ====== Compatible avec : CustomerCommunication Campaign MarketingEvent ---- ====== Préparation Sprint 13 ====== Compatible avec : AiConversation Recommendation KnowledgeDocument ---- ====== Définition de terminé ====== Le Sprint 3-F.1 est terminé lorsque : ✓ CustomerNote créé ✓ CustomerNoteMention créé ✓ Notes privées ✓ Notes publiques ✓ Mentions utilisateurs ✓ Historisation CRM ✓ AuditLog intégré ✓ Recherche notes ✓ Swagger documenté ---- ====== Livrables ====== CustomerNote CustomerNoteMention CustomerNoteModule CustomerNoteController CustomerNoteService CRM Notes API ---- ====== Sprint 3-F.2 — Collaboration CRM Enterprise ====== ===== Objectif ===== Transformer le système de notes CRM en véritable plateforme collaborative Enterprise. À l'issue de cette étape : ✓ Threads ✓ Réponses aux notes ✓ Réactions ✓ Tâches liées ✓ Assignation ✓ Notifications temps réel ✓ Timeline CRM unifiée ✓ Collaboration multi-équipes ---- ====== Architecture cible ====== Customer ↓ CRM Timeline ↓ Notes ↓ Threads ↓ Tasks ↓ Mentions ↓ Notifications ↓ Collaboration Hub ---- ====== Sprint 3-F.2-A ====== ===== Extension Prisma ===== ---- ====== Étape 1 — Support des Threads ====== ===== Ajouter dans CustomerNote ===== parentNoteId String? threadRootId String? replyCount Int @default(0) ---- ====== Étape 2 — Relations ====== ===== Ajouter ===== parentNote CustomerNote? @relation( "CustomerNoteThread", fields:[parentNoteId], references:[id] ) replies CustomerNote[] @relation( "CustomerNoteThread" ) ---- ====== Étape 3 — Réactions ====== ===== Créer ===== model CustomerNoteReaction { id String @id @default(uuid()) noteId String userId String reaction String createdAt DateTime @default(now()) note CustomerNote @relation( fields:[noteId], references:[id], onDelete:Cascade ) user User @relation( fields:[userId], references:[id] ) @@unique([ noteId, userId, reaction ]) @@index([noteId]) @@index([userId]) } ---- ====== Étape 4 — Tâches CRM ====== ===== Créer ===== model CustomerTask { id String @id @default(uuid()) tenantId String customerId String noteId String? assignedToId String? createdById String title String description String? priority TaskPriority status TaskStatus dueDate DateTime? completedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt customer Customer @relation( fields:[customerId], references:[id] ) @@index([tenantId]) @@index([customerId]) @@index([assignedToId]) @@index([status]) } ---- ====== Étape 5 — Enums ====== ===== Ajouter ===== enum TaskPriority { LOW MEDIUM HIGH CRITICAL } enum TaskStatus { OPEN IN_PROGRESS COMPLETED CANCELLED } ---- ====== Étape 6 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name crm_collaboration ---- ===== Générer ===== npx prisma generate ---- ====== Sprint 3-F.2-B ====== ===== Threads CRM ===== ---- ====== Étape 7 — Réponses ====== ===== Ajouter ===== Dans : CustomerNoteService ---- ===== Méthode ===== replyToNote() ---- ===== Workflow ===== Note ↓ Réponse ↓ Thread ↓ Timeline ---- ====== Étape 8 — Exemple ====== Client VIP ↓ Note commerciale ↓ Réponse finance ↓ Réponse support ---- ===== Résultat ===== Conversation CRM unifiée ---- ====== Étape 9 — Lecture Thread ====== ===== Endpoint ===== GET /customers/{id}/notes/{noteId}/thread ---- ===== Retour ===== Arborescence complète ---- ====== Sprint 3-F.2-C ====== ===== Réactions ===== ---- ====== Étape 10 — Réactions supportées ====== LIKE IMPORTANT FOLLOW_UP DONE WARNING ---- ====== Étape 11 — Service ====== ===== Ajouter ===== addReaction() removeReaction() listReactions() ---- ====== Étape 12 — Endpoint ====== ===== Ajouter ===== POST /notes/{noteId}/reactions DELETE /notes/{noteId}/reactions ---- ====== Sprint 3-F.2-D ====== ===== Assignation CRM ===== ---- ====== Étape 13 — Assignation ====== ===== Ajouter dans CustomerNote ===== assignedToId String? ---- ===== Relation ===== assignedTo User? ---- ====== Étape 14 — Endpoint ====== ===== Ajouter ===== PUT /notes/{noteId}/assign ---- ===== Exemple ===== Client réclame facture ↓ Assigné Finance ---- ====== Étape 15 — Notification ====== ===== Déclencher ===== Notification Email In-App ---- ====== Sprint 3-F.2-E ====== ===== Tâches CRM ===== ---- ====== Étape 16 — CustomerTaskService ====== ===== Créer ===== customer-task.service.ts ---- ===== Méthodes ===== createTask() assignTask() completeTask() cancelTask() ---- ====== Étape 17 — Endpoints ====== ===== Ajouter ===== GET /customers/{id}/tasks POST /customers/{id}/tasks PUT /customers/{id}/tasks/{taskId} DELETE /customers/{id}/tasks/{taskId} ---- ====== Étape 18 — Exemple ====== Rappeler client ↓ Assigner commercial ↓ Date limite ---- ====== Sprint 3-F.2-F ====== ===== Notifications Temps Réel ===== ---- ====== Étape 19 — WebSocket ====== ===== Réutiliser ===== Infrastructure : Notification Gateway prévue en Sprint 9. ---- ====== Étape 20 — Événements ====== NOTE_CREATED NOTE_REPLY NOTE_MENTION NOTE_ASSIGNED TASK_CREATED TASK_COMPLETED ---- ====== Étape 21 — Canal ====== tenant:{tenantId} crm:{customerId} ---- ====== Sprint 3-F.2-G ====== ===== Timeline CRM Unifiée ===== ---- ====== Étape 22 — Création ====== crm-timeline.service.ts ---- ===== Sources ===== CustomerNote CustomerDocument CustomerTag CustomerTask Reservation Invoice Communication ---- ====== Étape 23 — Timeline ====== ===== Endpoint ===== GET /customers/{id}/timeline ---- ===== Exemple ===== [ { "type":"NOTE", "date":"2026-01-01" }, { "type":"TASK", "date":"2026-01-03" }, { "type":"DOCUMENT", "date":"2026-01-05" } ] ---- ====== Étape 24 — Filtres ====== Notes Documents Tâches Tags Réservations Factures ---- ====== Sprint 3-F.2-H ====== ===== Collaboration Dashboard ===== ---- ====== Étape 25 — Endpoint ====== ===== Ajouter ===== GET /crm/collaboration/dashboard ---- ===== KPI ===== Notes ouvertes Tâches ouvertes Mentions non lues Assignations Threads actifs ---- ====== Étape 26 — Exemple ====== { "openTasks":42, "activeThreads":17, "unreadMentions":9 } ---- ====== Sprint 3-F.2-I ====== ===== Audit & Historisation ===== ---- ====== Étape 27 — CustomerHistory ====== ===== Journaliser ===== NOTE_REPLIED NOTE_ASSIGNED TASK_CREATED TASK_COMPLETED ---- ====== Étape 28 — AuditLog ====== ===== Ajouter ===== CRM_THREAD_CREATED CRM_NOTE_REACTION CRM_TASK_CREATED CRM_TASK_ASSIGNED CRM_TASK_COMPLETED ---- ====== Sprint 3-F.2-J ====== ===== Préparation Sprint 9 ===== ---- ===== Compatible ===== Campaign MarketingEvent NotificationCenter Realtime Communication ---- ====== Préparation Sprint 13 ====== Compatible avec : AiConversation Recommendation AutomationScenario KnowledgeDocument ---- ====== Préparation Sprint 20 ====== Compatible avec : Enterprise CRM Collaboration Analytics Customer Intelligence Unified Timeline ---- ====== Définition de terminé ====== Le Sprint 3-F.2 est terminé lorsque : ✓ Threads CRM ✓ Réponses aux notes ✓ Réactions ✓ Assignation ✓ Tâches CRM ✓ Notifications temps réel ✓ Timeline unifiée ✓ Dashboard collaboration ✓ Audit intégré ---- ====== Livrables ====== CustomerNoteReaction CustomerTask CustomerTaskService CrmTimelineService CRM Collaboration API Unified CRM Timeline Realtime CRM Events ---- ====== Sprint 3-G.1 — Gestion des Communications Client ====== ===== Objectif ===== Implémenter la couche CRM Communication centralisée permettant de tracer toutes les interactions client. À l'issue de cette étape : ✓ Emails ✓ SMS ✓ Appels ✓ Historique communications ✓ Timeline CRM ✓ Audit ✓ Statistiques ✓ Préparation Marketing ---- ====== Architecture cible ====== Customer ↓ CustomerCommunication ↓ Email SMS Calls ↓ Timeline CRM ↓ Analytics ↓ Marketing ---- ====== Sprint 3-G.1-A ====== ===== Modèle Prisma ===== ---- ====== Étape 1 — Création CustomerCommunication ====== ===== Ajouter dans schema.prisma ===== model CustomerCommunication { id String @id @default(uuid()) tenantId String customerId String userId String? communicationType CommunicationType direction CommunicationDirection status CommunicationStatus subject String? content String? externalReference String? provider String? sender String? recipient String? durationSeconds Int? scheduledAt DateTime? sentAt DateTime? deliveredAt DateTime? openedAt DateTime? repliedAt DateTime? metadata Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? tenant Tenant @relation( fields:[tenantId], references:[id] ) customer Customer @relation( fields:[customerId], references:[id], onDelete:Cascade ) user User? @relation( fields:[userId], references:[id] ) @@index([tenantId]) @@index([customerId]) @@index([communicationType]) @@index([status]) @@index([createdAt]) } ---- ====== Étape 2 — CommunicationType ====== ===== Ajouter ===== enum CommunicationType { EMAIL SMS PHONE_CALL WHATSAPP PUSH_NOTIFICATION LETTER INTERNAL_NOTE } ---- ====== Étape 3 — Direction ====== ===== Ajouter ===== enum CommunicationDirection { INBOUND OUTBOUND } ---- ====== Étape 4 — Status ====== ===== Ajouter ===== enum CommunicationStatus { DRAFT SCHEDULED SENT DELIVERED OPENED REPLIED FAILED CANCELLED } ---- ====== Étape 5 — Relation Customer ====== ===== Ajouter ===== Dans : model Customer communications CustomerCommunication[] ---- ====== Étape 6 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name customer_communications ---- ===== Générer ===== npx prisma generate ---- ====== Sprint 3-G.1-B ====== ===== Module ===== ---- ====== Étape 7 — Création ====== src/modules/customer-communications ├── application │ │ └── dto │ │ ├── create-customer-communication.dto.ts │ │ ├── communication-query.dto.ts │ │ └── communication-response.dto.ts │ ├── domain │ │ └── services │ │ └── customer-communication.service.ts │ ├── presentation │ │ └── controllers │ │ └── customer-communication.controller.ts │ └── customer-communication.module.ts ---- ====== Sprint 3-G.1-C ====== ===== DTOs ===== ---- ====== Étape 8 — Create DTO ====== ===== Créer ===== create-customer-communication.dto.ts ---- ===== Implémentation ===== export class CreateCustomerCommunicationDto { communicationType: string; direction: string; subject?: string; content?: string; recipient?: string; sender?: string; scheduledAt?: Date; } ---- ====== Étape 9 — Query DTO ====== ===== Ajouter ===== export class CommunicationQueryDto { communicationType?: string; status?: string; direction?: string; page?: number = 1; limit?: number = 25; } ---- ====== Sprint 3-G.1-D ====== ===== CustomerCommunicationService ===== ---- ====== Étape 10 — Création ====== ===== Créer ===== customer-communication.service.ts ---- ===== Méthodes ===== findAll() findTimeline() create() markDelivered() markOpened() markReplied() ---- ====== Étape 11 — Création ====== ===== Exemple ===== await prisma.customerCommunication.create({ data: { tenantId, customerId, userId, ...dto } }); ---- ====== Étape 12 — Historisation ====== ===== Ajouter ===== Dans : CustomerHistory ---- ===== Événements ===== COMMUNICATION_CREATED EMAIL_SENT SMS_SENT CALL_LOGGED ---- ====== Sprint 3-G.1-E ====== ===== Emails ===== ---- ====== Étape 13 — Intégration ====== ===== Préparer ===== EmailService ---- ===== Fournisseurs ===== SMTP SendGrid Mailgun AWS SES ---- ====== Étape 14 — Workflow ====== CRM ↓ Email ↓ Send ↓ Tracking ↓ Timeline ---- ====== Étape 15 — Tracking ====== ===== Stocker ===== sentAt deliveredAt openedAt repliedAt ---- ====== Sprint 3-G.1-F ====== ===== SMS ===== ---- ====== Étape 16 — Intégration ====== ===== Préparer ===== SmsService ---- ===== Fournisseurs ===== Twilio OVH SMS MessageBird ---- ====== Étape 17 — Tracking ====== ===== Stocker ===== Sent Delivered Failed ---- ====== Sprint 3-G.1-G ====== ===== Appels ===== ---- ====== Étape 18 — Journalisation ====== ===== Ajouter ===== PHONE_CALL ---- ===== Métadonnées ===== Duration Agent Outcome Recording ---- ====== Étape 19 — Exemple ====== { "communicationType":"PHONE_CALL", "durationSeconds":420 } ---- ====== Sprint 3-G.1-H ====== ===== Timeline CRM ===== ---- ====== Étape 20 — Endpoint ====== ===== Ajouter ===== GET /customers/{id}/communications/timeline ---- ===== Retour ===== Communications + Notes + Documents + Tags ---- ====== Étape 21 — Vue unifiée ====== ===== Exemple ===== [ { "type":"EMAIL", "date":"2026-01-01" }, { "type":"SMS", "date":"2026-01-02" }, { "type":"CALL", "date":"2026-01-03" } ] ---- ====== Sprint 3-G.1-I ====== ===== Contrôleur ===== ---- ====== Étape 22 — Création ====== ===== Créer ===== customer-communication.controller.ts ---- ===== Déclaration ===== @ApiTags( 'Customer Communications' ) @Controller( 'customers/:id/communications' ) @UseGuards( JwtAuthGuard ) ---- ====== Étape 23 — Endpoints ====== ===== Ajouter ===== GET /customers/{id}/communications POST /customers/{id}/communications GET /customers/{id}/communications/timeline ---- ====== Étape 24 — Recherche ====== ===== Ajouter ===== Filtres : Type Statut Direction Période ---- ====== Sprint 3-G.1-J ====== ===== Audit & Analytics ===== ---- ====== Étape 25 — AuditLog ====== ===== Journaliser ===== COMMUNICATION_CREATED EMAIL_DELIVERED EMAIL_OPENED SMS_DELIVERED CALL_CREATED ---- ====== Étape 26 — KPI ====== ===== Endpoint ===== GET /customers/{id}/communications/statistics ---- ===== Retour ===== { "emails":124, "sms":31, "calls":14, "openRate":67, "replyRate":19 } ---- ====== Étape 27 — Permissions ====== ===== Ajouter ===== communications.read communications.write communications.send communications.manage ---- ====== Préparation Sprint 9 ====== Compatible avec : Campaign EmailCampaign SmsCampaign NotificationCenter RealtimeMessaging ---- ====== Préparation Sprint 13 ====== Compatible avec : AiConversation Recommendation AutomationScenario KnowledgeBase ---- ====== Préparation Sprint 20 ====== Compatible avec : Customer Intelligence Communication Analytics Engagement Scoring Predictive CRM ---- ====== Définition de terminé ====== Le Sprint 3-G.1 est terminé lorsque : ✓ CustomerCommunication créé ✓ Emails tracés ✓ SMS tracés ✓ Appels tracés ✓ Historique complet ✓ Timeline CRM ✓ AuditLog intégré ✓ Statistiques CRM ✓ Swagger documenté ---- ====== Livrables ====== CustomerCommunication CustomerCommunicationModule CustomerCommunicationController CustomerCommunicationService Communication Timeline Communication Analytics ---- ====== Étape suivante ====== ====== Sprint 3-G.2 — Communication Intelligence & Omnicanal ====== ===== Objectif ===== Faire évoluer le module CRM Communication vers une plateforme omnicanale Enterprise. À l'issue de cette étape : ✓ WhatsApp ✓ Messagerie instantanée ✓ Templates ✓ Campagnes ✓ Analyse de sentiment ✓ IA conversationnelle ✓ Centre omnicanal ✓ Communication Intelligence ---- ====== Architecture cible ====== Customer ↓ Omnichannel Hub ├── Email ├── SMS ├── WhatsApp ├── Chat ├── Push ├── Voice │ ↓ AI Intelligence ↓ Campaigns ↓ Analytics ---- ====== Sprint 3-G.2-A ====== ===== Extension Prisma ===== ---- ====== Étape 1 — CommunicationTemplate ====== ===== Ajouter dans schema.prisma ===== model CommunicationTemplate { id String @id @default(uuid()) tenantId String name String code String channel CommunicationChannel subject String? content String variables Json? active Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tenant Tenant @relation( fields:[tenantId], references:[id] ) @@unique([ tenantId, code ]) @@index([tenantId]) @@index([channel]) } ---- ====== Étape 2 — OmnichannelConversation ====== ===== Ajouter ===== model OmnichannelConversation { id String @id @default(uuid()) tenantId String customerId String channel CommunicationChannel status ConversationStatus subject String? startedAt DateTime @default(now()) lastMessageAt DateTime? closedAt DateTime? assignedToId String? sentimentScore Float? aiSummary String? tenant Tenant @relation( fields:[tenantId], references:[id] ) customer Customer @relation( fields:[customerId], references:[id] ) @@index([tenantId]) @@index([customerId]) @@index([channel]) @@index([status]) } ---- ====== Étape 3 — ConversationMessage ====== ===== Ajouter ===== model ConversationMessage { id String @id @default(uuid()) conversationId String direction CommunicationDirection messageType String content String? externalReference String? sentAt DateTime @default(now()) metadata Json? conversation OmnichannelConversation @relation( fields:[conversationId], references:[id], onDelete:Cascade ) @@index([conversationId]) @@index([sentAt]) } ---- ====== Étape 4 — Enums ====== ===== Ajouter ===== enum CommunicationChannel { EMAIL SMS WHATSAPP CHAT PUSH VOICE } enum ConversationStatus { OPEN ASSIGNED WAITING_CUSTOMER CLOSED } ---- ====== Étape 5 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name omnichannel_communications ---- ====== Sprint 3-G.2-B ====== ===== Omnichannel Module ===== ---- ====== Étape 6 — Création ====== src/modules/omnichannel ---- ===== Structure ===== omnichannel ├── templates │ ├── conversations │ ├── whatsapp │ ├── chat │ ├── ai │ └── analytics ---- ====== Sprint 3-G.2-C ====== ===== WhatsApp Business ===== ---- ====== Étape 7 — WhatsApp Service ====== ===== Créer ===== whatsapp.service.ts ---- ===== Méthodes ===== sendMessage() sendTemplate() receiveWebhook() markDelivered() ---- ====== Étape 8 — Modèles WhatsApp ====== ===== Exemples ===== Booking Confirmation Payment Reminder Welcome Message Review Request Check-In Reminder ---- ====== Étape 9 — Endpoints ====== ===== Ajouter ===== POST /communications/whatsapp/send POST /communications/whatsapp/template POST /communications/whatsapp/webhook ---- ====== Sprint 3-G.2-D ====== ===== Messagerie Instantanée ===== ---- ====== Étape 10 — Chat Service ====== ===== Créer ===== chat.service.ts ---- ===== Méthodes ===== startConversation() sendMessage() closeConversation() assignConversation() ---- ====== Étape 11 — Temps réel ====== ===== Utiliser ===== WebSocket Gateway ---- ===== Événements ===== CHAT_MESSAGE CHAT_TYPING CHAT_ASSIGNED CHAT_CLOSED ---- ====== Étape 12 — Endpoints ====== GET /conversations GET /conversations/{id} POST /conversations/{id}/messages PUT /conversations/{id}/assign ---- ====== Sprint 3-G.2-E ====== ===== Templates Enterprise ===== ---- ====== Étape 13 — Template Service ====== ===== Créer ===== communication-template.service.ts ---- ===== Variables ===== {{customerName}} {{reservationNumber}} {{propertyName}} {{checkInDate}} {{amount}} ---- ====== Étape 14 — Rendu ====== ===== Méthode ===== renderTemplate() ---- ====== Étape 15 — Endpoints ====== GET /communication-templates POST /communication-templates PUT /communication-templates/{id} DELETE /communication-templates/{id} ---- ====== Sprint 3-G.2-F ====== ===== Campagnes CRM ===== ---- ====== Étape 16 — CampaignCommunication ====== ===== Ajouter ===== model CampaignCommunication { id String @id @default(uuid()) tenantId String name String channel CommunicationChannel templateId String? targetSegment String? status String scheduledAt DateTime? sentAt DateTime? recipientsCount Int @default(0) createdAt DateTime @default(now()) @@index([tenantId]) @@index([status]) } ---- ====== Étape 17 — Campagnes ====== ===== Types ===== Newsletter Promotion Loyalty Upsell Cross-sell Retention ---- ====== Étape 18 — Endpoints ====== GET /campaigns POST /campaigns POST /campaigns/{id}/send ---- ====== Sprint 3-G.2-G ====== ===== Analyse de Sentiment ===== ---- ====== Étape 19 — Extension Conversation ====== ===== Utiliser ===== sentimentScore Float? aiSummary String? ---- ====== Étape 20 — Sentiment ====== ===== Service ===== sentiment-analysis.service.ts ---- ===== Résultat ===== NEGATIVE NEUTRAL POSITIVE ---- ====== Étape 21 — Exemple ====== "Très satisfait" ↓ POSITIVE ↓ 0.92 ---- ====== Sprint 3-G.2-H ====== ===== IA Conversationnelle ===== ---- ====== Étape 22 — AI Conversation Service ====== ===== Créer ===== conversation-ai.service.ts ---- ===== Capacités ===== Résumé automatique Détection intention Suggestions réponses Priorisation ---- ====== Étape 23 — Suggestions ====== ===== Exemple ===== Client demande remboursement ↓ Intent: REFUND_REQUEST ↓ Réponse suggérée ---- ====== Étape 24 — Résumé ====== ===== Générer ===== aiSummary à la fermeture d'une conversation. ---- ====== Sprint 3-G.2-I ====== ===== Centre Omnicanal ===== ---- ====== Étape 25 — Dashboard ====== ===== Endpoint ===== GET /omnichannel/dashboard ---- ===== KPI ===== Conversations ouvertes Temps réponse moyen Messages aujourd'hui Sentiment moyen Campagnes actives ---- ====== Étape 26 — Vue Agent ====== ===== Endpoint ===== GET /omnichannel/inbox ---- ===== Regroupe ===== Email SMS WhatsApp Chat ---- ====== Sprint 3-G.2-J ====== ===== Audit & Intelligence ===== ---- ====== Étape 27 — AuditLog ====== ===== Ajouter ===== WHATSAPP_SENT CHAT_STARTED CHAT_ASSIGNED CAMPAIGN_CREATED CAMPAIGN_SENT SENTIMENT_ANALYZED AI_RESPONSE_GENERATED ---- ====== Étape 28 — Permissions ====== ===== Ajouter ===== communications.campaigns communications.templates communications.omnichannel communications.ai ---- ====== Préparation Sprint 9 ====== Compatible avec : NotificationCenter RealtimeMessaging CampaignEngine CommunicationHub ---- ====== Préparation Sprint 13 ====== Compatible avec : AiConversation AiMessage Recommendation AutomationScenario ---- ====== Préparation Sprint 20 ====== Compatible avec : Enterprise Analytics Communication Intelligence Customer Intelligence Revenue Intelligence ---- ====== Définition de terminé ====== Le Sprint 3-G.2 est terminé lorsque : ✓ WhatsApp intégré ✓ Messagerie instantanée ✓ Templates ✓ Campagnes CRM ✓ Analyse de sentiment ✓ IA conversationnelle ✓ Centre omnicanal ✓ Dashboard omnicanal ✓ Audit intégré ---- ====== Livrables ====== CommunicationTemplate OmnichannelConversation ConversationMessage WhatsAppService ChatService ConversationAIService SentimentAnalysisService Omnichannel Dashboard ---- ====== Sprint 3-H.1 — Gestion des Préférences Client ====== ===== Objectif ===== Implémenter la gestion centralisée des préférences client permettant : Personnalisation Marketing Communication Fidélisation Consentements Expérience client À l'issue de cette étape : ✓ Préférences marketing ✓ Canaux préférés ✓ Consentements ✓ Préférences linguistiques ✓ Préférences monétaires ✓ Personnalisation CRM ✓ Conformité RGPD ---- ====== Architecture cible ====== Customer ↓ CustomerPreference ├── Marketing ├── Communication ├── Language ├── Currency ├── Timezone ├── Loyalty └── GDPR ↓ CRM ↓ Marketing Automation ---- ====== Sprint 3-H.1-A ====== ===== Extension Prisma ===== ---- ====== Étape 1 — Enrichissement CustomerPreference ====== ===== Ajouter ===== model CustomerPreference { id String @id @default(uuid()) customerId String @unique preferredLanguage String? preferredCurrency String? preferredTimezone String? preferredChannel PreferredChannel? preferredContactTime String? prefersEmail Boolean @default(true) prefersSms Boolean @default(false) prefersPhone Boolean @default(false) prefersWhatsApp Boolean @default(false) acceptsMarketing Boolean @default(false) acceptsNewsletter Boolean @default(false) acceptsPromotions Boolean @default(false) acceptsSurveys Boolean @default(false) acceptsRecommendations Boolean @default(false) loyaltyEligible Boolean @default(true) vipProgramEligible Boolean @default(false) communicationFrequency CommunicationFrequency? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt customer Customer @relation( fields:[customerId], references:[id], onDelete:Cascade ) } ---- ====== Étape 2 — PreferredChannel ====== ===== Ajouter ===== enum PreferredChannel { EMAIL SMS PHONE WHATSAPP PUSH } ---- ====== Étape 3 — CommunicationFrequency ====== ===== Ajouter ===== enum CommunicationFrequency { IMMEDIATE DAILY WEEKLY MONTHLY NEVER } ---- ====== Étape 4 — Consentement RGPD ====== ===== Ajouter ===== marketingConsentAt DateTime? newsletterConsentAt DateTime? privacyAcceptedAt DateTime? consentVersion String? consentIpAddress String? ---- ====== Étape 5 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name customer_preferences_enterprise ---- ===== Générer ===== npx prisma generate ---- ====== Sprint 3-H.1-B ====== ===== Module ===== ---- ====== Étape 6 — Création ====== src/modules/customer-preferences ├── application │ │ └── dto │ │ ├── update-customer-preference.dto.ts │ │ └── customer-preference-response.dto.ts │ ├── domain │ │ └── services │ │ └── customer-preference.service.ts │ ├── presentation │ │ └── controllers │ │ └── customer-preference.controller.ts │ └── customer-preference.module.ts ---- ====== Sprint 3-H.1-C ====== ===== DTOs ===== ---- ====== Étape 7 — Update DTO ====== ===== Créer ===== update-customer-preference.dto.ts ---- ===== Implémentation ===== export class UpdateCustomerPreferenceDto { preferredLanguage?: string; preferredCurrency?: string; preferredTimezone?: string; preferredChannel?: string; preferredContactTime?: string; prefersEmail?: boolean; prefersSms?: boolean; prefersPhone?: boolean; prefersWhatsApp?: boolean; acceptsMarketing?: boolean; acceptsNewsletter?: boolean; acceptsPromotions?: boolean; acceptsSurveys?: boolean; acceptsRecommendations?: boolean; communicationFrequency?: string; } ---- ====== Étape 8 — Response DTO ====== ===== Créer ===== customer-preference-response.dto.ts ---- ===== Ajouter ===== export class CustomerPreferenceResponseDto { preferredLanguage: string; preferredCurrency: string; preferredChannel: string; acceptsMarketing: boolean; acceptsNewsletter: boolean; communicationFrequency: string; } ---- ====== Sprint 3-H.1-D ====== ===== CustomerPreferenceService ===== ---- ====== Étape 9 — Création ====== ===== Créer ===== customer-preference.service.ts ---- ===== Méthodes ===== findPreferences() updatePreferences() validatePreferences() recordConsent() ---- ====== Étape 10 — Lecture ====== ===== Vérifier ===== Customer Tenant avant toute lecture. ---- ===== Retour ===== CustomerPreference ---- ====== Étape 11 — Mise à jour ====== ===== Exemple ===== await prisma.customerPreference.update({ where: { customerId }, data: { ...dto } }); ---- ====== Étape 12 — Consentements ====== ===== Si ===== acceptsMarketing=true ---- ===== Ajouter ===== marketingConsentAt: new Date() ---- ===== Si ===== acceptsNewsletter=true ---- ===== Ajouter ===== newsletterConsentAt: new Date() ---- ====== Sprint 3-H.1-E ====== ===== Validation ===== ---- ====== Étape 13 — Langues ====== ===== Vérifier ===== Contre : SupportedLanguages ---- ====== Étape 14 — Devises ====== ===== Vérifier ===== Contre : SupportedCurrencies ---- ====== Étape 15 — Fuseaux horaires ====== ===== Vérifier ===== Contre : IANA Timezones ---- ====== Étape 16 — Cohérence ====== ===== Exemple ===== PreferredChannel=SMS ↓ Téléphone requis ---- ===== Sinon ===== throw new BadRequestException() ---- ====== Sprint 3-H.1-F ====== ===== Personnalisation CRM ===== ---- ====== Étape 17 — Utilisation ====== Les préférences alimentent : Marketing Communication Campagnes Recommandations Automatisation ---- ====== Étape 18 — Exemples ====== Langue = FR ↓ Templates FR ---- Canal = WhatsApp ↓ Communication WhatsApp ---- Fréquence = Weekly ↓ Digest hebdomadaire ---- ====== Sprint 3-H.1-G ====== ===== Contrôleur ===== ---- ====== Étape 19 — Création ====== ===== Créer ===== customer-preference.controller.ts ---- ===== Déclaration ===== @ApiTags( 'Customer Preferences' ) @Controller( 'customers/:id/preferences' ) @UseGuards( JwtAuthGuard ) @ApiBearerAuth() ---- ====== Étape 20 — GET ====== ===== Route ===== GET /customers/{id}/preferences ---- ====== Étape 21 — PUT ====== ===== Route ===== PUT /customers/{id}/preferences ---- ====== Sprint 3-H.1-H ====== ===== Historisation CRM ===== ---- ====== Étape 22 — CustomerHistory ====== ===== Journaliser ===== PREFERENCES_UPDATED MARKETING_CONSENT_UPDATED COMMUNICATION_CHANNEL_CHANGED ---- ====== Étape 23 — AuditLog ====== ===== Ajouter ===== CUSTOMER_PREFERENCES_UPDATED CUSTOMER_CONSENT_GRANTED CUSTOMER_CONSENT_REVOKED ---- ====== Sprint 3-H.1-I ====== ===== Analytics ===== ---- ====== Étape 24 — Statistiques ====== ===== Endpoint ===== GET /customers/preferences/statistics ---- ===== Retour ===== { "email":523, "sms":121, "whatsapp":84, "marketingOptIn":432 } ---- ====== Étape 25 — Segmentation ====== ===== Exemple ===== acceptsMarketing=true AND preferredChannel=EMAIL ---- ===== Utilisation ===== Campagnes CRM Marketing Automation ---- ====== Sprint 3-H.1-J ====== ===== Sécurité & RGPD ===== ---- ====== Étape 26 — Export ====== ===== Préparer ===== Compatible avec : GDPR Export Data Portability ---- ====== Étape 27 — Révocation ====== ===== Supporter ===== Retrait consentement Opt-out Désinscription ---- ====== Étape 28 — Permissions ====== ===== Ajouter ===== customer.preferences.read customer.preferences.write customer.consent.manage ---- ====== Préparation Sprint 9 ====== Compatible avec : Campaign MarketingSegment NotificationCenter CommunicationHub ---- ====== Préparation Sprint 13 ====== Compatible avec : Recommendation AiConversation AutomationScenario Customer Intelligence ---- ====== Préparation Sprint 19 ====== Compatible avec : Consent ComplianceAudit RetentionPolicy DataClassification ---- ====== Définition de terminé ====== Le Sprint 3-H.1 est terminé lorsque : ✓ CustomerPreference enrichi ✓ CustomerPreferenceModule créé ✓ CustomerPreferenceController créé ✓ CustomerPreferenceService créé ✓ Consentements RGPD ✓ Personnalisation CRM ✓ Historisation ✓ AuditLog intégré ✓ Swagger documenté ---- ====== Livrables ====== CustomerPreference Enterprise CustomerPreferenceModule CustomerPreferenceController CustomerPreferenceService Consent Management Preference Analytics ---- ====== Sprint 3-H.2 — Centre de Préférences Enterprise & Consent Management ====== ===== Objectif ===== Finaliser la couche CRM Enterprise de conformité et de gestion des consentements. À l'issue de cette étape : ✓ Consentements RGPD avancés ✓ Historique complet ✓ Double Opt-In ✓ Centre omnicanal ✓ Gestion abonnements ✓ Portabilité des données ✓ Droit à l'oubli ✓ Audit de conformité ---- ====== Architecture cible ====== Customer ↓ Consent Center ├── Marketing ├── Newsletter ├── SMS ├── WhatsApp ├── Push ├── Profilage ├── Analytics └── Partage données ↓ Compliance ↓ GDPR ---- ====== Sprint 3-H.2-A ====== ===== Modèle RGPD ===== ---- ====== Étape 1 — Création Consent ====== ===== Ajouter dans schema.prisma ===== model Consent { id String @id @default(uuid()) tenantId String customerId String consentType ConsentType status ConsentStatus source ConsentSource version String grantedAt DateTime? revokedAt DateTime? expiresAt DateTime? ipAddress String? userAgent String? proofReference String? metadata Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tenant Tenant @relation( fields:[tenantId], references:[id] ) customer Customer @relation( fields:[customerId], references:[id], onDelete:Cascade ) history ConsentHistory[] @@index([tenantId]) @@index([customerId]) @@index([consentType]) @@index([status]) } ---- ====== Étape 2 — Historique ====== ===== Ajouter ===== model ConsentHistory { id String @id @default(uuid()) consentId String oldStatus ConsentStatus? newStatus ConsentStatus changedAt DateTime @default(now()) changedBy String? reason String? metadata Json? consent Consent @relation( fields:[consentId], references:[id], onDelete:Cascade ) @@index([consentId]) @@index([changedAt]) } ---- ====== Étape 3 — Types ====== ===== Ajouter ===== enum ConsentType { MARKETING NEWSLETTER SMS WHATSAPP EMAIL PROFILING ANALYTICS THIRD_PARTY_SHARING PERSONALIZATION } ---- ====== Étape 4 — Status ====== ===== Ajouter ===== enum ConsentStatus { PENDING GRANTED REVOKED EXPIRED } ---- ====== Étape 5 — Source ====== ===== Ajouter ===== enum ConsentSource { WEBSITE CRM API IMPORT MOBILE_APP CUSTOMER_PORTAL } ---- ====== Étape 6 — Relation Customer ====== ===== Ajouter ===== consents Consent[] dans : model Customer ---- ====== Étape 7 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name consent_management ---- ====== Sprint 3-H.2-B ====== ===== Double Opt-In ===== ---- ====== Étape 8 — Extension Consent ====== ===== Ajouter ===== doubleOptInRequired Boolean @default(false) doubleOptInToken String? doubleOptInSentAt DateTime? doubleOptInConfirmedAt DateTime? ---- ====== Étape 9 — Workflow ====== Inscription ↓ Consentement ↓ Email confirmation ↓ Lien sécurisé ↓ Consentement actif ---- ====== Étape 10 — Service ====== ===== Créer ===== double-optin.service.ts ---- ===== Méthodes ===== generateToken() sendConfirmation() confirmConsent() ---- ====== Sprint 3-H.2-C ====== ===== Centre Omnicanal ===== ---- ====== Étape 11 — Subscription ====== ===== Ajouter ===== model CustomerSubscription { id String @id @default(uuid()) customerId String code String name String channel PreferredChannel subscribed Boolean @default(true) subscribedAt DateTime? unsubscribedAt DateTime? customer Customer @relation( fields:[customerId], references:[id], onDelete:Cascade ) @@index([customerId]) @@index([channel]) } ---- ====== Étape 12 — Types ====== ===== Exemples ===== Newsletter Promotions Loyalty Product Updates Reservation Alerts Security Alerts ---- ====== Étape 13 — Endpoint ====== ===== Ajouter ===== GET /customers/{id}/subscriptions PUT /customers/{id}/subscriptions ---- ====== Sprint 3-H.2-D ====== ===== Consent Management Service ===== ---- ====== Étape 14 — Création ====== consent-management.service.ts ---- ===== Méthodes ===== grantConsent() revokeConsent() expireConsent() recordProof() getConsentHistory() ---- ====== Étape 15 — Historisation ====== ===== Obligatoire ===== Toute modification crée : ConsentHistory ---- ====== Étape 16 — Vérification ====== ===== Avant envoi ===== Email SMS WhatsApp Campagne ---- ===== Vérifier ===== Consent actif ---- ====== Sprint 3-H.2-E ====== ===== Portabilité des données ===== ---- ====== Étape 17 — Export GDPR ====== ===== Créer ===== gdpr-export.service.ts ---- ===== Agréger ===== Customer Preferences Consents Communications Documents Notes Tags Reservations ---- ====== Étape 18 — Endpoint ====== ===== Ajouter ===== POST /customers/{id}/gdpr/export ---- ===== Formats ===== JSON ZIP PDF ---- ====== Sprint 3-H.2-F ====== ===== Droit à l'oubli ===== ---- ====== Étape 19 — GDPR Erasure ====== ===== Créer ===== gdpr-erasure.service.ts ---- ===== Méthodes ===== anonymizeCustomer() deletePersonalData() generateErasureReport() ---- ====== Étape 20 — Workflow ====== Demande ↓ Validation ↓ Anonymisation ↓ Rapport ↓ Audit ---- ====== Étape 21 — Endpoint ====== ===== Ajouter ===== POST /customers/{id}/gdpr/erase ---- ===== Anonymisation ===== Email Téléphone Adresse Documents Métadonnées personnelles ---- ====== Sprint 3-H.2-G ====== ===== Centre de Préférences ===== ---- ====== Étape 22 — Endpoint public ====== ===== Ajouter ===== GET /preferences-center/{token} PUT /preferences-center/{token} ---- ===== Permet ===== Modifier préférences Modifier abonnements Retirer consentements Télécharger données ---- ====== Étape 23 — Token sécurisé ====== ===== Ajouter ===== JWT signé Expiration configurable ---- ====== Sprint 3-H.2-H ====== ===== Compliance Dashboard ===== ---- ====== Étape 24 — Endpoint ====== ===== Ajouter ===== GET /compliance/consents/dashboard ---- ===== KPI ===== Total Consents Active Consents Revoked Consents Double Opt-In Pending Export Requests Erasure Requests ---- ====== Étape 25 — Exemple ====== { "activeConsents":8421, "revokedConsents":213, "pendingDoubleOptIn":54 } ---- ====== Sprint 3-H.2-I ====== ===== Audit & Conformité ===== ---- ====== Étape 26 — AuditLog ====== ===== Ajouter ===== CONSENT_GRANTED CONSENT_REVOKED DOUBLE_OPTIN_CONFIRMED GDPR_EXPORT_REQUESTED GDPR_ERASURE_REQUESTED GDPR_ERASURE_COMPLETED ---- ====== Étape 27 — ComplianceAudit ====== ===== Préparer ===== Compatible avec : Sprint 19 ISO27001 SOC2 GDPR Audit ---- ====== Étape 28 — RetentionPolicy ====== ===== Préparer ===== Compatible avec : RetentionPolicy DataClassification SecurityIncident ---- ====== Sprint 3-H.2-J ====== ===== Permissions ===== ---- ====== Étape 29 — Ajouter ===== consents.read consents.write consents.manage gdpr.export gdpr.erase ---- ====== Préparation Sprint 9 ====== Compatible avec : Campaign NotificationCenter CommunicationHub Marketing Automation ---- ====== Préparation Sprint 19 ====== Compatible avec : Consent ComplianceAudit RetentionPolicy DataClassification SecurityPolicy ---- ====== Préparation Sprint 20 ====== Compatible avec : Enterprise Governance Enterprise Compliance Privacy Center Customer Trust Dashboard ---- ====== Définition de terminé ====== Le Sprint 3-H.2 est terminé lorsque : ✓ Consent créé ✓ ConsentHistory créé ✓ Double Opt-In ✓ Centre omnicanal ✓ Gestion abonnements ✓ Portabilité données ✓ Droit à l'oubli ✓ Dashboard conformité ✓ Audit intégré ---- ====== Livrables ====== Consent ConsentHistory CustomerSubscription ConsentManagementService DoubleOptInService GdprExportService GdprErasureService Compliance Dashboard ---- ====== Sprint 3-I.1 — Recherche CRM Avancée ====== ===== Objectif ===== Mettre en place un moteur de recherche CRM Enterprise capable de rechercher instantanément dans l'ensemble du domaine Client. À l'issue de cette étape : ✓ Recherche globale ✓ Recherche plein texte ✓ Recherche multicritères ✓ Filtres avancés ✓ Facettes ✓ Recherches sauvegardées ✓ CRM Search Engine ---- ====== Architecture cible ====== CRM Search API ↓ Search Engine ├── Customers ├── Notes ├── Documents ├── Communications ├── Tags ├── Preferences └── Reservations ↓ Filters Engine ↓ Facets Engine ↓ Saved Searches ---- ====== Sprint 3-I.1-A ====== ===== Extension Prisma ===== ---- ====== Étape 1 — SavedSearch ====== ===== Ajouter dans schema.prisma ===== model SavedSearch { id String @id @default(uuid()) tenantId String userId String name String description String? entityType SearchEntityType query String? filters Json isDefault Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tenant Tenant @relation( fields:[tenantId], references:[id] ) user User @relation( fields:[userId], references:[id] ) @@index([tenantId]) @@index([userId]) } ---- ====== Étape 2 — Search History ====== ===== Ajouter ===== model SearchHistory { id String @id @default(uuid()) tenantId String userId String query String entityType SearchEntityType? resultCount Int @default(0) executedAt DateTime @default(now()) tenant Tenant @relation( fields:[tenantId], references:[id] ) user User @relation( fields:[userId], references:[id] ) @@index([tenantId]) @@index([userId]) @@index([executedAt]) } ---- ====== Étape 3 — Enum ====== ===== Ajouter ===== enum SearchEntityType { CUSTOMER NOTE DOCUMENT COMMUNICATION TAG RESERVATION GLOBAL } ---- ====== Étape 4 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name crm_search_engine ---- ====== Sprint 3-I.1-B ====== ===== CRM Search Module ===== ---- ====== Étape 5 — Création ====== src/modules/crm-search ├── application │ │ └── dto │ │ ├── crm-search.dto.ts │ │ ├── facet-filter.dto.ts │ │ └── saved-search.dto.ts │ ├── domain │ │ └── services │ │ ├── crm-search.service.ts │ │ ├── crm-facet.service.ts │ │ └── saved-search.service.ts │ ├── presentation │ │ └── controllers │ │ └── crm-search.controller.ts │ └── crm-search.module.ts ---- ====== Sprint 3-I.1-C ====== ===== DTOs ===== ---- ====== Étape 6 — Recherche ====== ===== Créer ===== crm-search.dto.ts ---- ===== Ajouter ===== export class CrmSearchDto { q?: string; entityType?: string; page?: number = 1; limit?: number = 25; sortBy?: string; sortOrder?: 'asc' | 'desc'; filters?: Record< string, unknown >; } ---- ====== Étape 7 — Filtres avancés ====== ===== Supporter ===== Status Segment Tags Score Revenue Risk Country Language Consent Date ---- ====== Sprint 3-I.1-D ====== ===== Recherche Globale ===== ---- ====== Étape 8 — CrmSearchService ====== ===== Créer ===== crm-search.service.ts ---- ===== Méthodes ===== globalSearch() searchCustomers() searchNotes() searchDocuments() searchCommunications() ---- ====== Étape 9 — Recherche Clients ====== ===== Champs ===== CustomerNumber FirstName LastName Email Phone CompanyName ---- ===== Prisma ===== OR: [ { firstName: { contains: q, mode: 'insensitive' } }, { lastName: { contains: q, mode: 'insensitive' } }, { email: { contains: q, mode: 'insensitive' } } ] ---- ====== Étape 10 — Recherche Globale ====== ===== Agréger ===== Customers Notes Documents Communications ---- ===== Retour ===== { "customers": [], "notes": [], "documents": [], "communications": [] } ---- ====== Sprint 3-I.1-E ====== ===== Recherche Plein Texte ===== ---- ====== Étape 11 — PostgreSQL ====== ===== Ajouter ===== Colonnes : title content subject ---- ===== Utiliser ===== tsvector tsquery ---- ====== Étape 12 — Index ====== ===== Exemple ===== CREATE INDEX idx_note_search ON "CustomerNote" USING GIN( to_tsvector( 'simple', content ) ); ---- ====== Étape 13 — Recherche ====== ===== Exemple ===== VIP facture ---- ===== Retour ===== Notes Documents Emails concernés. ---- ====== Sprint 3-I.1-F ====== ===== Recherche Multicritères ===== ---- ====== Étape 14 — Filtres combinés ====== ===== Exemple ===== VIP + France + Revenue > 5000 + Marketing = true ---- ===== Prisma ===== AND: [ ... ] ---- ====== Étape 15 — Support ====== Equals Contains In Range Date Boolean ---- ====== Sprint 3-I.1-G ====== ===== Facettes CRM ===== ---- ====== Étape 16 — CrmFacetService ====== ===== Créer ===== crm-facet.service.ts ---- ===== Méthodes ===== buildFacets() countSegments() countTags() countCountries() ---- ====== Étape 17 — Facettes ====== ===== Exemple ===== { "segments": { "VIP": 41, "STANDARD": 381 }, "countries": { "FR": 250, "ES": 71 } } ---- ====== Étape 18 — Endpoint ====== ===== Ajouter ===== GET /crm-search/facets ---- ====== Sprint 3-I.1-H ====== ===== Recherches Sauvegardées ===== ---- ====== Étape 19 — SavedSearchService ====== ===== Créer ===== saved-search.service.ts ---- ===== Méthodes ===== createSearch() listSearches() deleteSearch() executeSavedSearch() ---- ====== Étape 20 — Exemple ====== ===== Recherche ===== VIP France ---- ===== Sauvegarder ===== Mes VIP France ---- ====== Étape 21 — Endpoints ====== GET /crm-search/saved POST /crm-search/saved DELETE /crm-search/saved/{id} ---- ====== Sprint 3-I.1-I ====== ===== API Search ===== ---- ====== Étape 22 — Contrôleur ====== ===== Créer ===== crm-search.controller.ts ---- ====== Étape 23 — Endpoints ====== ===== Ajouter ===== GET /crm-search GET /crm-search/global GET /crm-search/facets GET /crm-search/saved POST /crm-search/saved DELETE /crm-search/saved/{id} ---- ====== Étape 24 — Exemple ====== ===== Requête ===== GET /crm-search/global?q=dupont ---- ===== Retour ===== { "customers": 3, "notes": 5, "communications": 2 } ---- ====== Sprint 3-I.1-J ====== ===== Audit & Analytics ===== ---- ====== Étape 25 — Historique ====== ===== Créer ===== SearchHistory automatiquement. ---- ====== Étape 26 — AuditLog ====== ===== Journaliser ===== CRM_SEARCH CRM_GLOBAL_SEARCH CRM_SAVED_SEARCH CRM_SEARCH_EXPORT ---- ====== Étape 27 — KPI ====== ===== Endpoint ===== GET /crm-search/statistics ---- ===== Retour ===== { "searchesToday":421, "savedSearches":82, "mostUsedFilter":"VIP" } ---- ====== Préparation Sprint 13 ====== Compatible avec : Recommendation KnowledgeDocument AiConversation AutomationScenario ---- ====== Préparation Sprint 17 ====== Compatible avec : RevenueForecast CustomerAnalytics Predictive Segmentation ---- ====== Préparation Sprint 20 ====== Compatible avec : Enterprise Search Global Search Data Intelligence Enterprise Analytics ---- ====== Définition de terminé ====== Le Sprint 3-I.1 est terminé lorsque : ✓ Recherche globale ✓ Recherche plein texte ✓ Recherche multicritères ✓ Facettes CRM ✓ Recherches sauvegardées ✓ Historique recherches ✓ Audit intégré ✓ Swagger documenté ---- ====== Livrables ====== SavedSearch SearchHistory CrmSearchService CrmFacetService SavedSearchService CRM Search API Enterprise Search Engine ---- ====== Sprint 3-I.2 — CRM Search Intelligence & Recommandations ====== ===== Objectif ===== Faire évoluer le moteur CRM Search vers une plateforme de recherche intelligente assistée par IA. À l'issue de cette étape : ✓ Recherche sémantique ✓ Suggestions intelligentes ✓ Recherche IA ✓ Résultats personnalisés ✓ Recherche prédictive ✓ Recommandations CRM ✓ Search Intelligence Engine ---- ====== Architecture cible ====== User Query ↓ Search Intelligence Layer ├── Full Text Search ├── Semantic Search ├── Predictive Search ├── Personalized Ranking └── AI Recommendations ↓ CRM Knowledge Graph ↓ Results Engine ↓ Recommendations ---- ====== Sprint 3-I.2-A ====== ===== Extension Prisma ===== ---- ====== Étape 1 — SearchSuggestion ====== ===== Ajouter dans schema.prisma ===== model SearchSuggestion { id String @id @default(uuid()) tenantId String query String frequency Int @default(1) lastUsedAt DateTime @default(now()) createdAt DateTime @default(now()) tenant Tenant @relation( fields:[tenantId], references:[id] ) @@unique([ tenantId, query ]) @@index([tenantId]) @@index([frequency]) @@index([lastUsedAt]) } ---- ====== Étape 2 — SearchRecommendation ====== ===== Ajouter ===== model SearchRecommendation { id String @id @default(uuid()) tenantId String userId String recommendationType RecommendationType entityType SearchEntityType entityId String score Float reason String? createdAt DateTime @default(now()) expiresAt DateTime? tenant Tenant @relation( fields:[tenantId], references:[id] ) user User @relation( fields:[userId], references:[id] ) @@index([tenantId]) @@index([userId]) @@index([score]) } ---- ====== Étape 3 — RecommendationType ====== ===== Ajouter ===== enum RecommendationType { RECENT FREQUENT RELATED PREDICTIVE AI_GENERATED BEHAVIOR_BASED } ---- ====== Étape 4 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name crm_search_ai ---- ====== Sprint 3-I.2-B ====== ===== Search Intelligence Module ===== ---- ====== Étape 5 — Création ====== src/modules/search-intelligence ├── semantic-search │ ├── suggestions │ ├── recommendations │ ├── predictive-search │ ├── ranking │ └── ai-search ---- ====== Sprint 3-I.2-C ====== ===== Recherche Sémantique ===== ---- ====== Étape 6 — SemanticSearchService ====== ===== Créer ===== semantic-search.service.ts ---- ===== Méthodes ===== semanticSearch() findRelatedTerms() expandQuery() ---- ====== Étape 7 — Synonymes CRM ====== ===== Exemples ===== VIP = Premium Client = Customer Facture = Invoice Réservation = Booking ---- ====== Étape 8 — Expansion ====== ===== Exemple ===== Recherche : "client premium" ---- ===== Recherche réelle ===== VIP Premium High Value Loyal Customer ---- ====== Sprint 3-I.2-D ====== ===== Suggestions Intelligentes ===== ---- ====== Étape 9 — SearchSuggestionService ====== ===== Créer ===== search-suggestion.service.ts ---- ===== Méthodes ===== generateSuggestions() recordSearch() getPopularQueries() ---- ====== Étape 10 — Suggestions ====== ===== Sources ===== Historique utilisateur Historique tenant Popularité Fréquence ---- ====== Étape 11 — Endpoint ====== ===== Ajouter ===== GET /crm-search/suggestions ---- ===== Exemple ===== vip vip france vip paris vip corporate ---- ====== Sprint 3-I.2-E ====== ===== Résultats Personnalisés ===== ---- ====== Étape 12 — PersonalizedRankingService ====== ===== Créer ===== personalized-ranking.service.ts ---- ===== Méthodes ===== rankResults() applyUserPreferences() boostFrequentlyUsedEntities() ---- ====== Étape 13 — Critères ====== Historique utilisateur Segments favoris Clients récents Résultats utilisés ---- ====== Étape 14 — Exemple ====== ===== Commercial ===== VIP Leads Réservations plus visibles. ---- ===== Finance ===== Factures Paiements Contrats plus visibles. ---- ====== Sprint 3-I.2-F ====== ===== Recherche Prédictive ===== ---- ====== Étape 15 — PredictiveSearchService ====== ===== Créer ===== predictive-search.service.ts ---- ===== Méthodes ===== predictNextQueries() predictCustomerInterest() predictRelatedSearches() ---- ====== Étape 16 — Exemples ====== ===== Recherche ===== VIP France ---- ===== Suggestions ===== VIP Paris VIP Revenue > 10000 VIP Loyalty ---- ====== Étape 17 — Analyse ====== ===== Basée sur ===== SearchHistory SavedSearch CustomerActivity ---- ====== Sprint 3-I.2-G ====== ===== Recommandations CRM ===== ---- ====== Étape 18 — SearchRecommendationService ====== ===== Créer ===== search-recommendation.service.ts ---- ===== Méthodes ===== generateRecommendations() recommendCustomers() recommendSegments() recommendActions() ---- ====== Étape 19 — Exemples ====== ===== Recommandation ===== 23 clients à risque non contactés ---- ===== Recommandation ===== 12 VIP sans campagne active ---- ====== Étape 20 — Endpoint ====== ===== Ajouter ===== GET /crm-search/recommendations ---- ====== Sprint 3-I.2-H ====== ===== Recherche IA ===== ---- ====== Étape 21 — AI Search Service ====== ===== Créer ===== ai-search.service.ts ---- ===== Méthodes ===== naturalLanguageSearch() explainResults() generateInsights() ---- ====== Étape 22 — Exemples ====== ===== Requête ===== Montre-moi les clients VIP qui n'ont pas été contactés depuis 90 jours. ---- ===== Traduction ===== Segment=VIP AND LastCommunication < 90 jours ---- ====== Étape 23 — Endpoint ====== ===== Ajouter ===== POST /crm-search/ai ---- ====== Sprint 3-I.2-I ====== ===== Dashboard Search Intelligence ===== ---- ====== Étape 24 — Endpoint ====== ===== Ajouter ===== GET /crm-search/intelligence/dashboard ---- ===== KPI ===== Top recherches Suggestions utilisées Recherche IA Taux de clic Recommandations générées ---- ====== Étape 25 — Exemple ====== { "topSearch":"VIP", "aiSearches":128, "recommendations":342 } ---- ====== Sprint 3-I.2-J ====== ===== Audit & Gouvernance ===== ---- ====== Étape 26 — AuditLog ====== ===== Journaliser ===== SEMANTIC_SEARCH AI_SEARCH SEARCH_RECOMMENDATION SEARCH_SUGGESTION_SELECTED PREDICTIVE_SEARCH ---- ====== Étape 27 — Permissions ====== ===== Ajouter ===== crm.search.ai crm.search.recommendations crm.search.analytics ---- ====== Préparation Sprint 13 ====== Compatible avec : AiConversation KnowledgeGraph RecommendationEngine AutomationScenario ---- ====== Préparation Sprint 17 ====== Compatible avec : RevenueForecast CustomerAnalytics PredictiveCRM BusinessIntelligence ---- ====== Préparation Sprint 20 ====== Compatible avec : Enterprise AI Search Intelligence Enterprise Knowledge Decision Support System ---- ====== Définition de terminé ====== Le Sprint 3-I.2 est terminé lorsque : ✓ Recherche sémantique ✓ Suggestions intelligentes ✓ Recherche IA ✓ Résultats personnalisés ✓ Recherche prédictive ✓ Recommandations CRM ✓ Dashboard Search Intelligence ✓ Audit intégré ---- ====== Livrables ====== SearchSuggestion SearchRecommendation SemanticSearchService PredictiveSearchService AISearchService SearchRecommendationService Search Intelligence Dashboard ---- ====== Sprint 3-J.1 — CRM Analytics & Tableau de Bord ====== ===== Objectif ===== Construire le premier cockpit CRM Enterprise centralisant l'ensemble des indicateurs stratégiques. À l'issue de cette étape : ✓ KPI CRM ✓ Customer Dashboard ✓ Segmentation Analytics ✓ Communication Analytics ✓ Conversion Analytics ✓ Revenue Analytics ✓ Executive Dashboard ---- ====== Architecture cible ====== CRM Analytics ↓ Analytics Engine ├── Customers ├── Segments ├── Communications ├── Revenue ├── Conversion └── Loyalty ↓ Dashboard API ↓ Frontend Cockpit ---- ====== Sprint 3-J.1-A ====== ===== Extension Prisma ===== ---- ====== Étape 1 — Dashboard Snapshot ====== ===== Ajouter dans schema.prisma ===== model DashboardSnapshot { id String @id @default(uuid()) tenantId String snapshotDate DateTime metrics Json createdAt DateTime @default(now()) tenant Tenant @relation( fields:[tenantId], references:[id] ) @@unique([ tenantId, snapshotDate ]) @@index([tenantId]) @@index([snapshotDate]) } ---- ====== Étape 2 — KPI Definition ====== ===== Ajouter ===== model KpiDefinition { id String @id @default(uuid()) tenantId String code String name String description String? category String active Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@unique([ tenantId, code ]) @@index([tenantId]) } ---- ====== Étape 3 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name crm_analytics_dashboard ---- ===== Générer ===== npx prisma generate ---- ====== Sprint 3-J.1-B ====== ===== CRM Analytics Module ===== ---- ====== Étape 4 — Création ====== src/modules/crm-analytics ├── application │ │ └── dto │ ├── domain │ │ └── services │ │ ├── crm-dashboard.service.ts │ │ ├── customer-analytics.service.ts │ │ ├── communication-analytics.service.ts │ │ ├── segmentation-analytics.service.ts │ │ ├── conversion-analytics.service.ts │ │ └── revenue-analytics.service.ts │ ├── presentation │ │ └── controllers │ │ └── crm-analytics.controller.ts │ └── crm-analytics.module.ts ---- ====== Sprint 3-J.1-C ====== ===== KPI CRM ===== ---- ====== Étape 5 — KPI Principaux ====== ===== Calculer ===== Nombre clients Clients actifs Clients inactifs VIP Nouveaux clients Clients à risque ---- ====== Étape 6 — Customer KPI ====== ===== Exemple ===== { "totalCustomers": 12584, "activeCustomers": 10874, "inactiveCustomers": 1710, "vipCustomers": 524 } ---- ====== Étape 7 — Service ====== ===== Créer ===== customer-analytics.service.ts ---- ===== Méthodes ===== getCustomerKpis() getGrowthRate() getCustomerHealth() ---- ====== Sprint 3-J.1-D ====== ===== Customer Dashboard ===== ---- ====== Étape 8 — Endpoint ====== ===== Ajouter ===== GET /crm-analytics/dashboard ---- ===== Retour ===== { "customers": {}, "communications": {}, "revenue": {}, "segments": {} } ---- ====== Étape 9 — Widgets ====== ===== Ajouter ===== Top clients Derniers clients Clients à risque Clients VIP Croissance ---- ====== Étape 10 — Exemple ====== { "topCustomers": [], "vipCustomers": [], "riskCustomers": [] } ---- ====== Sprint 3-J.1-E ====== ===== Segmentation Analytics ===== ---- ====== Étape 11 — Service ====== ===== Créer ===== segmentation-analytics.service.ts ---- ===== Méthodes ===== getSegmentDistribution() getSegmentGrowth() getSegmentRevenue() ---- ====== Étape 12 — KPI ====== ===== Répartition ===== VIP Corporate Loyal High Value Standard At Risk ---- ====== Étape 13 — Endpoint ====== ===== Ajouter ===== GET /crm-analytics/segments ---- ===== Retour ===== { "VIP": 412, "LOYAL": 1832, "CORPORATE": 94 } ---- ====== Sprint 3-J.1-F ====== ===== Communication Analytics ===== ---- ====== Étape 14 — Service ====== ===== Créer ===== communication-analytics.service.ts ---- ===== Méthodes ===== getCommunicationStats() getOpenRate() getReplyRate() getChannelPerformance() ---- ====== Étape 15 — KPI ====== ===== Calculer ===== Emails envoyés Emails ouverts SMS envoyés SMS délivrés WhatsApp envoyés Réponses ---- ====== Étape 16 — Endpoint ====== ===== Ajouter ===== GET /crm-analytics/communications ---- ===== Retour ===== { "emailOpenRate": 68.4, "replyRate": 17.2, "smsDeliveryRate": 95.8 } ---- ====== Sprint 3-J.1-G ====== ===== Conversion Analytics ===== ---- ====== Étape 17 — Service ====== ===== Créer ===== conversion-analytics.service.ts ---- ===== Méthodes ===== getConversionRate() getLeadConversion() getCampaignConversion() ---- ====== Étape 18 — KPI ====== ===== Exemple ===== Client créé ↓ Premier achat ↓ Client fidèle ---- ====== Étape 19 — Endpoint ====== ===== Ajouter ===== GET /crm-analytics/conversions ---- ===== Retour ===== { "leadConversion": 22.3, "repeatCustomerRate": 38.1 } ---- ====== Sprint 3-J.1-H ====== ===== Revenue Analytics ===== ---- ====== Étape 20 — Service ====== ===== Créer ===== revenue-analytics.service.ts ---- ===== Méthodes ===== getRevenueMetrics() getLifetimeValue() getAverageBasket() getRevenueBySegment() ---- ====== Étape 21 — KPI ====== ===== Calculer ===== Revenue total MRR CRM Lifetime Value Average Basket Revenue Segment ---- ====== Étape 22 — Endpoint ====== ===== Ajouter ===== GET /crm-analytics/revenue ---- ===== Retour ===== { "revenue": 1542870, "averageBasket": 382, "averageLtv": 4120 } ---- ====== Sprint 3-J.1-I ====== ===== Dashboard Exécutif ===== ---- ====== Étape 23 — Endpoint ====== ===== Ajouter ===== GET /crm-analytics/executive ---- ===== KPI Stratégiques ===== Croissance clients Croissance revenu VIP Attrition Satisfaction Engagement ---- ====== Étape 24 — Snapshot ====== ===== Générer ===== Tous les jours : DashboardSnapshot ---- ===== Utilisation ===== Historique Tendances Comparaisons ---- ====== Étape 25 — Comparaison ====== ===== Exemple ===== { "customersGrowth": 12.4, "revenueGrowth": 18.7 } ---- ====== Sprint 3-J.1-J ====== ===== Audit & Gouvernance ===== ---- ====== Étape 26 — AuditLog ====== ===== Journaliser ===== CRM_DASHBOARD_VIEW CRM_ANALYTICS_VIEW CRM_REVENUE_ANALYTICS CRM_SEGMENT_ANALYTICS CRM_EXPORT_ANALYTICS ---- ====== Étape 27 — Permissions ====== ===== Ajouter ===== crm.analytics.read crm.analytics.export crm.analytics.executive ---- ====== Étape 28 — Export ====== ===== Ajouter ===== GET /crm-analytics/export ---- ===== Formats ===== CSV XLSX PDF ---- ====== Préparation Sprint 13 ====== Compatible avec : RecommendationEngine AiInsights Forecasting Business Intelligence ---- ====== Préparation Sprint 17 ====== Compatible avec : Revenue Forecast Customer Forecast Predictive Analytics Financial Analytics ---- ====== Préparation Sprint 20 ====== Compatible avec : Executive Cockpit Enterprise BI Enterprise Analytics Data Warehouse ---- ====== Définition de terminé ====== Le Sprint 3-J.1 est terminé lorsque : ✓ KPI CRM ✓ Customer Dashboard ✓ Segmentation Analytics ✓ Communication Analytics ✓ Conversion Analytics ✓ Revenue Analytics ✓ Dashboard exécutif ✓ Export Analytics ✓ Audit intégré ---- ====== Livrables ====== DashboardSnapshot KpiDefinition CrmDashboardService CustomerAnalyticsService CommunicationAnalyticsService ConversionAnalyticsService RevenueAnalyticsService Executive Dashboard ---- ====== Sprint 3-J.2 — CRM Intelligence & Analytics Prédictifs ====== ===== Objectif ===== Finaliser le CRM Enterprise en ajoutant une couche complète d'intelligence prédictive. À l'issue de cette étape : ✓ Prévision revenus ✓ Prévision churn ✓ Prévision LTV ✓ Détection opportunités ✓ Détection anomalies ✓ Insights IA ✓ Score santé client ✓ CRM Intelligence Platform ---- ====== Architecture cible ====== CRM Data ↓ Analytics Engine ↓ Prediction Engine ├── Revenue Forecast ├── Churn Prediction ├── LTV Prediction ├── Opportunity Detection ├── Anomaly Detection └── Customer Health ↓ AI Insights ↓ Executive Dashboard ---- ====== Sprint 3-J.2-A ====== ===== Extension Prisma ===== ---- ====== Étape 1 — CustomerHealth ====== ===== Ajouter dans schema.prisma ===== model CustomerHealth { id String @id @default(uuid()) customerId String @unique overallScore Int @default(0) engagementScore Int @default(0) loyaltyScore Int @default(0) satisfactionScore Int @default(0) communicationScore Int @default(0) revenueScore Int @default(0) churnRiskScore Int @default(0) lastCalculatedAt DateTime @default(now()) customer Customer @relation( fields:[customerId], references:[id], onDelete:Cascade ) } ---- ====== Étape 2 — PredictionSnapshot ====== ===== Ajouter ===== model PredictionSnapshot { id String @id @default(uuid()) tenantId String predictionType PredictionType snapshotDate DateTime result Json createdAt DateTime @default(now()) tenant Tenant @relation( fields:[tenantId], references:[id] ) @@index([tenantId]) @@index([predictionType]) @@index([snapshotDate]) } ---- ====== Étape 3 — AI Insight ====== ===== Ajouter ===== model AiInsight { id String @id @default(uuid()) tenantId String category InsightCategory severity InsightSeverity title String description String recommendation String? entityType String? entityId String? active Boolean @default(true) createdAt DateTime @default(now()) expiresAt DateTime? @@index([tenantId]) @@index([category]) @@index([severity]) @@index([active]) } ---- ====== Étape 4 — Enums ====== ===== Ajouter ===== enum PredictionType { REVENUE CHURN LTV OPPORTUNITY CUSTOMER_HEALTH } enum InsightCategory { REVENUE CHURN CUSTOMER SEGMENT COMMUNICATION MARKETING } enum InsightSeverity { LOW MEDIUM HIGH CRITICAL } ---- ====== Étape 5 — Migration ====== ===== Générer ===== npx prisma migrate dev \ --name crm_predictive_intelligence ---- ====== Sprint 3-J.2-B ====== ===== CRM Intelligence Module ===== ---- ====== Étape 6 — Création ====== src/modules/crm-intelligence ├── revenue-forecast │ ├── churn-prediction │ ├── ltv-prediction │ ├── opportunity-detection │ ├── anomaly-detection │ ├── ai-insights │ ├── customer-health │ └── dashboard ---- ====== Sprint 3-J.2-C ====== ===== Prévision Revenus ===== ---- ====== Étape 7 — RevenueForecastService ====== ===== Créer ===== revenue-forecast.service.ts ---- ===== Méthodes ===== forecastRevenue() forecastSegmentRevenue() forecastCustomerRevenue() ---- ====== Étape 8 — Sources ====== Invoices Reservations Customer LTV Customer Score Segments ---- ====== Étape 9 — Endpoint ====== ===== Ajouter ===== GET /crm-intelligence/revenue-forecast ---- ===== Retour ===== { "nextMonth": 152000, "nextQuarter": 487000, "confidence": 0.84 } ---- ====== Sprint 3-J.2-D ====== ===== Prévision Churn ===== ---- ====== Étape 10 — ChurnPredictionService ====== ===== Créer ===== churn-prediction.service.ts ---- ===== Méthodes ===== calculateChurnRisk() predictChurn() detectInactiveCustomers() ---- ====== Étape 11 — Critères ====== Dernière activité Dernière communication Baisse dépenses Baisse engagement Réclamations ---- ====== Étape 12 — Classification ====== LOW MEDIUM HIGH CRITICAL ---- ====== Étape 13 — Endpoint ====== ===== Ajouter ===== GET /crm-intelligence/churn ---- ===== Exemple ===== { "highRiskCustomers": 42, "criticalCustomers": 8 } ---- ====== Sprint 3-J.2-E ====== ===== Prévision LTV ===== ---- ====== Étape 14 — LtvPredictionService ====== ===== Créer ===== ltv-prediction.service.ts ---- ===== Méthodes ===== predictLifetimeValue() predictVipCustomers() estimateFutureRevenue() ---- ====== Étape 15 — Facteurs ====== Historique achats Segments Fidélité Engagement Communication ---- ====== Étape 16 — Endpoint ====== ===== Ajouter ===== GET /crm-intelligence/ltv ---- ===== Retour ===== { "averagePredictedLtv": 5420, "futureVipCustomers": 73 } ---- ====== Sprint 3-J.2-F ====== ===== Détection Opportunités ===== ---- ====== Étape 17 — OpportunityDetectionService ====== ===== Créer ===== opportunity-detection.service.ts ---- ===== Méthodes ===== findUpsellOpportunities() findCrossSellOpportunities() findRetentionActions() ---- ====== Étape 18 — Exemples ====== VIP sans offre premium ↓ Upsell ---- Corporate sans programme fidélité ↓ Cross-sell ---- ====== Étape 19 — Endpoint ====== ===== Ajouter ===== GET /crm-intelligence/opportunities ---- ====== Sprint 3-J.2-G ====== ===== Détection d'Anomalies ===== ---- ====== Étape 20 — AnomalyDetectionService ====== ===== Créer ===== anomaly-detection.service.ts ---- ===== Méthodes ===== detectRevenueAnomalies() detectBehaviorAnomalies() detectCommunicationAnomalies() ---- ====== Étape 21 — Exemples ====== Baisse revenu -45% ↓ Anomalie ---- Ouvertures emails 0% ↓ Alerte ---- ====== Étape 22 — Endpoint ====== ===== Ajouter ===== GET /crm-intelligence/anomalies ---- ====== Sprint 3-J.2-H ====== ===== Score Santé Client ===== ---- ====== Étape 23 — CustomerHealthService ====== ===== Créer ===== customer-health.service.ts ---- ===== Méthodes ===== calculateHealthScore() updateHealthScores() getHealthDistribution() ---- ====== Étape 24 — Calcul ====== ===== Pondérations ===== Engagement 20% Communication 15% Loyalty 20% Revenue 20% Satisfaction 15% Churn Risk 10% ---- ====== Étape 25 — Classification ====== 90-100 Excellent 75-89 Healthy 50-74 Attention 0-49 Critical ---- ====== Étape 26 — Endpoint ====== ===== Ajouter ===== GET /crm-intelligence/health ---- ====== Sprint 3-J.2-I ====== ===== AI Insights ===== ---- ====== Étape 27 — AiInsightService ====== ===== Créer ===== ai-insight.service.ts ---- ===== Méthodes ===== generateInsights() generateRecommendations() prioritizeActions() ---- ====== Étape 28 — Exemples ====== ===== Insight ===== 23 VIP sans contact depuis 60 jours ---- ===== Recommandation ===== Créer campagne VIP ---- ===== Insight ===== Segment Corporate +18% revenu ce mois-ci ---- ====== Étape 29 — Endpoint ====== ===== Ajouter ===== GET /crm-intelligence/insights ---- ====== Sprint 3-J.2-J ====== ===== Cockpit CRM Intelligence ===== ---- ====== Étape 30 — Endpoint ====== ===== Ajouter ===== GET /crm-intelligence/dashboard ---- ===== Agrège ===== Forecast Revenue Churn LTV Health Opportunities Insights ---- ====== Étape 31 — Exemple ====== { "forecastRevenue": 487000, "highRiskCustomers": 42, "futureVipCustomers": 73, "opportunities": 118, "insights": 14 } ---- ====== Étape 32 — AuditLog ====== ===== Journaliser ===== CRM_FORECAST_GENERATED CRM_CHURN_ANALYSIS CRM_LTV_PREDICTION CRM_ANOMALY_DETECTED CRM_AI_INSIGHT_GENERATED ---- ====== Étape 33 — Permissions ====== ===== Ajouter ===== crm.intelligence.read crm.intelligence.forecast crm.intelligence.insights crm.intelligence.executive ---- ====== Préparation Sprint 17 ====== Compatible avec : Forecast Engine Revenue Planning Financial Intelligence Business Intelligence ---- ====== Préparation Sprint 20 ====== Compatible avec : Enterprise AI Executive Intelligence Decision Support Predictive Analytics Enterprise BI ---- ====== Définition de terminé ====== Le Sprint 3-J.2 est terminé lorsque : ✓ Revenue Forecast ✓ Churn Prediction ✓ LTV Prediction ✓ Opportunity Detection ✓ Anomaly Detection ✓ Customer Health Score ✓ AI Insights ✓ CRM Intelligence Dashboard ✓ Audit intégré ---- ====== Livrables ====== CustomerHealth PredictionSnapshot AiInsight RevenueForecastService ChurnPredictionService LtvPredictionService OpportunityDetectionService AnomalyDetectionService CustomerHealthService AiInsightService CRM Intelligence Dashboard ---- ====== Sprint 3 — Gestion des Clients TERMINÉ ====== ===== Domaines CRM Livrés ===== ✓ Customer ✓ CustomerAddress ✓ CustomerDocument ✓ CustomerTag ✓ CustomerNote ✓ CustomerCommunication ✓ CustomerPreference ✓ Consent Management ✓ CRM Search ✓ CRM Analytics ✓ CRM Intelligence ----