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