Table des matières

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


É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


É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

DokuWiki Appliance - Powered by TurnKey Linux