Outils pour utilisateurs

Outils du site


ujusum:3-codage:1-repository:2-prisma-schema

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
ujusum:3-codage:1-repository:2-prisma-schema [2026/06/07 05:27] 91.170.108.99ujusum:3-codage:1-repository:2-prisma-schema [2026/06/07 19:04] (Version actuelle) 91.170.108.99
Ligne 2059: Ligne 2059:
 ---- ----
  
-====== Étape suivante ======+====== Phase 2-E — Contrats, Documents, Paiements & Facturation ======
  
-===== Phase 2-E =====+===== Objectif =====
  
-Domaines financiers et contractuels :+Construire le premier flux métier complet de la plateforme : 
 + 
 +<code> 
 +Client 
 + 
 +↓ 
 + 
 +Réservation 
 + 
 +↓ 
 + 
 +Contrat 
 + 
 +↓ 
 + 
 +Signature 
 + 
 +↓ 
 + 
 +Paiement 
 + 
 +↓ 
 + 
 +Facture 
 + 
 +↓ 
 + 
 +Comptabilité 
 +</code> 
 + 
 +Cette phase couvre : 
 + 
 +  * Sprint 5 — Contrats & Signature Électronique 
 +  * Sprint 6 — Paiements & Facturation 
 + 
 +---- 
 + 
 +====== Prérequis ====== 
 + 
 +Avant cette phase, le schéma doit déjà contenir : 
 + 
 +<code> 
 +Tenant 
 + 
 +User 
 + 
 +Role 
 + 
 +Permission 
 + 
 +Owner 
 + 
 +Property 
 + 
 +Reservation 
 +</code> 
 + 
 +---- 
 + 
 +====== Domaine Client ====== 
 + 
 +Avant les contrats et paiements, il faut définir le client. 
 + 
 +---- 
 + 
 +===== Customer ===== 
 + 
 +<code prisma> 
 +model Customer { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  tenantId              String 
 + 
 +  customerNumber        String @unique 
 + 
 +  firstName             String 
 + 
 +  lastName              String 
 + 
 +  email                 String 
 + 
 +  phone                 String? 
 + 
 +  mobile                String? 
 + 
 +  birthDate             DateTime? 
 + 
 +  nationality           String? 
 + 
 +  languageCode          String? 
 + 
 +  active                Boolean @default(true) 
 + 
 +  createdAt             DateTime @default(now()) 
 + 
 +  updatedAt             DateTime @updatedAt 
 + 
 +  deletedAt             DateTime? 
 + 
 +  tenant                Tenant @relation( 
 +                            fields:[tenantId], 
 +                            references:[id] 
 +                         ) 
 + 
 +  address               CustomerAddress? 
 + 
 +  documents             CustomerDocument[] 
 + 
 +  reservations          Reservation[] 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== CustomerAddress ===== 
 + 
 +<code prisma> 
 +model CustomerAddress { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  customerId            String @unique 
 + 
 +  addressLine1          String 
 + 
 +  addressLine2          String? 
 + 
 +  postalCode            String 
 + 
 +  city                  String 
 + 
 +  state                 String? 
 + 
 +  countryCode           String 
 + 
 +  customer              Customer @relation( 
 +                            fields:[customerId], 
 +                            references:[id] 
 +                         ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== CustomerDocument ===== 
 + 
 +<code prisma> 
 +model CustomerDocument { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  customerId            String 
 + 
 +  documentType          String 
 + 
 +  fileUrl               String 
 + 
 +  createdAt             DateTime @default(now()) 
 + 
 +  customer              Customer @relation( 
 +                            fields:[customerId], 
 +                            references:[id] 
 +                         ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Mise à jour Reservation ====== 
 + 
 +===== Ajouter ===== 
 + 
 +<code prisma> 
 +customerId String? 
 +</code> 
 + 
 +---- 
 + 
 +===== Relation ===== 
 + 
 +<code prisma> 
 +customer Customer? @relation( 
 +  fields:[customerId], 
 +  references:[id] 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Domaine Contrats ====== 
 + 
 +===== Architecture =====
  
 <code> <code>
Ligne 2069: Ligne 2261:
  
 ContractTemplate ContractTemplate
 +
 +ContractVersion
  
 ContractSignature ContractSignature
 +</code>
  
-Document+----
  
 +====== Contract ======
 +
 +<code prisma>
 +model Contract {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  reservationId         String
 +
 +  templateId            String
 +
 +  contractNumber        String @unique
 +
 +  status                ContractStatus
 +
 +  signedAt              DateTime?
 +
 +  generatedAt           DateTime?
 +
 +  pdfUrl                String?
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  reservation           Reservation @relation(
 +                            fields:[reservationId],
 +                            references:[id]
 +                         )
 +
 +  template              ContractTemplate @relation(
 +                            fields:[templateId],
 +                            references:[id]
 +                         )
 +
 +  signatures            ContractSignature[]
 +
 +  versions              ContractVersion[]
 +}
 +</code>
 +
 +----
 +
 +===== ContractStatus =====
 +
 +<code prisma>
 +enum ContractStatus {
 +
 +  DRAFT
 +
 +  GENERATED
 +
 +  SENT
 +
 +  VIEWED
 +
 +  SIGNED
 +
 +  CANCELLED
 +}
 +</code>
 +
 +----
 +
 +====== ContractTemplate ======
 +
 +<code prisma>
 +model ContractTemplate {
 +
 +  id                    String @id @default(uuid())
 +
 +  code                  String @unique
 +
 +  name                  String
 +
 +  content               String
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  contracts             Contract[]
 +}
 +</code>
 +
 +----
 +
 +====== ContractVersion ======
 +
 +<code prisma>
 +model ContractVersion {
 +
 +  id                    String @id @default(uuid())
 +
 +  contractId            String
 +
 +  versionNumber         Int
 +
 +  pdfUrl                String
 +
 +  createdAt             DateTime @default(now())
 +
 +  contract              Contract @relation(
 +                            fields:[contractId],
 +                            references:[id]
 +                         )
 +}
 +</code>
 +
 +----
 +
 +====== ContractSignature ======
 +
 +<code prisma>
 +model ContractSignature {
 +
 +  id                    String @id @default(uuid())
 +
 +  contractId            String
 +
 +  signerName            String
 +
 +  signerEmail           String
 +
 +  signedAt              DateTime?
 +
 +  providerReference     String?
 +
 +  status                String
 +
 +  contract              Contract @relation(
 +                            fields:[contractId],
 +                            references:[id]
 +                         )
 +}
 +</code>
 +
 +----
 +
 +====== Domaine Documents ======
 +
 +===== Document =====
 +
 +<code prisma>
 +model Document {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  documentType          String
 +
 +  fileName              String
 +
 +  fileUrl               String
 +
 +  mimeType              String
 +
 +  fileSize              Int
 +
 +  uploadedAt            DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +}
 +</code>
 +
 +----
 +
 +====== Domaine Paiements ======
 +
 +===== Architecture =====
 +
 +<code>
 Payment Payment
  
-Invoice+PaymentTransaction
  
 Refund Refund
  
-AccountingEntry+PaymentMethod
 </code> </code>
  
-Ces tables permettront d'implémenter intégralement :+----
  
-  * Sprint 5 — Contrats & Signature Électronique +====== Payment ======
-  * Sprint 6 — Paiements & Facturation+
  
-et de disposer du premier flux métier complet :+<code prisma> 
 +model Payment { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  tenantId              String 
 + 
 +  reservationId         String 
 + 
 +  paymentReference      String @unique 
 + 
 +  status                PaymentStatus 
 + 
 +  amount                Decimal @db.Decimal(10,2) 
 + 
 +  currencyCode          String 
 + 
 +  paidAt                DateTime? 
 + 
 +  createdAt             DateTime @default(now()) 
 + 
 +  tenant                Tenant @relation( 
 +                            fields:[tenantId], 
 +                            references:[id] 
 +                         ) 
 + 
 +  reservation           Reservation @relation( 
 +                            fields:[reservationId], 
 +                            references:[id] 
 +                         ) 
 + 
 +  transactions          PaymentTransaction[] 
 + 
 +  refunds               Refund[] 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== PaymentStatus ===== 
 + 
 +<code prisma> 
 +enum PaymentStatus { 
 + 
 +  PENDING 
 + 
 +  AUTHORIZED 
 + 
 +  PAID 
 + 
 +  FAILED 
 + 
 +  CANCELLED 
 + 
 +  REFUNDED 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== PaymentTransaction ====== 
 + 
 +<code prisma> 
 +model PaymentTransaction { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  paymentId             String 
 + 
 +  gateway               String 
 + 
 +  gatewayReference      String 
 + 
 +  status                String 
 + 
 +  amount                Decimal @db.Decimal(10,2) 
 + 
 +  createdAt             DateTime @default(now()) 
 + 
 +  payment               Payment @relation( 
 +                            fields:[paymentId], 
 +                            references:[id] 
 +                         ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Refund ====== 
 + 
 +<code prisma> 
 +model Refund { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  paymentId             String 
 + 
 +  amount                Decimal @db.Decimal(10,2) 
 + 
 +  reason                String? 
 + 
 +  refundedAt            DateTime? 
 + 
 +  payment               Payment @relation( 
 +                            fields:[paymentId], 
 +                            references:[id] 
 +                         ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Facturation ====== 
 + 
 +===== Invoice ===== 
 + 
 +<code prisma> 
 +model Invoice { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  tenantId              String 
 + 
 +  reservationId         String 
 + 
 +  invoiceNumber         String @unique 
 + 
 +  issueDate             DateTime 
 + 
 +  dueDate               DateTime 
 + 
 +  amountExclTax         Decimal @db.Decimal(10,2) 
 + 
 +  taxAmount             Decimal @db.Decimal(10,2) 
 + 
 +  amountInclTax         Decimal @db.Decimal(10,2) 
 + 
 +  status                InvoiceStatus 
 + 
 +  pdfUrl                String? 
 + 
 +  createdAt             DateTime @default(now()) 
 + 
 +  reservation           Reservation @relation( 
 +                            fields:[reservationId], 
 +                            references:[id] 
 +                         ) 
 + 
 +  tenant                Tenant @relation( 
 +                            fields:[tenantId], 
 +                            references:[id] 
 +                         ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== InvoiceStatus ===== 
 + 
 +<code prisma> 
 +enum InvoiceStatus { 
 + 
 +  DRAFT 
 + 
 +  ISSUED 
 + 
 +  PAID 
 + 
 +  PARTIALLY_PAID 
 + 
 +  CANCELLED 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Comptabilité ====== 
 + 
 +===== AccountingEntry ===== 
 + 
 +<code prisma> 
 +model AccountingEntry { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  tenantId              String 
 + 
 +  entryDate             DateTime 
 + 
 +  accountCode           String 
 + 
 +  label                 String 
 + 
 +  debit                 Decimal @db.Decimal(12,2) 
 + 
 +  credit                Decimal @db.Decimal(12,2) 
 + 
 +  reference             String? 
 + 
 +  createdAt             DateTime @default(now()) 
 + 
 +  tenant                Tenant @relation( 
 +                            fields:[tenantId], 
 +                            references:[id] 
 +                         ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Indexes ====== 
 + 
 +===== Contract ===== 
 + 
 +<code prisma> 
 +@@index([reservationId]) 
 + 
 +@@index([status]) 
 + 
 +@@index([contractNumber]) 
 +</code> 
 + 
 +---- 
 + 
 +===== Payment ===== 
 + 
 +<code prisma> 
 +@@index([reservationId]) 
 + 
 +@@index([status]) 
 + 
 +@@index([paymentReference]) 
 +</code> 
 + 
 +---- 
 + 
 +===== Invoice ===== 
 + 
 +<code prisma> 
 +@@index([reservationId]) 
 + 
 +@@index([invoiceNumber]) 
 + 
 +@@index([status]) 
 +</code> 
 + 
 +---- 
 + 
 +====== Validation ====== 
 + 
 +<code bash> 
 +npx prisma format 
 + 
 +npx prisma validate 
 + 
 +npx prisma generate 
 +</code> 
 + 
 +---- 
 + 
 +====== Migration ====== 
 + 
 +<code bash> 
 +npx prisma migrate dev \ 
 +--name contracts_payments_invoices 
 +</code> 
 + 
 +---- 
 + 
 +====== État du noyau métier ====== 
 + 
 +À ce stade, le schéma couvre :
  
 <code> <code>
 +Tenant
 +
 +User
 +
 +RBAC
 +
 +Owner
 +
 Property Property
 +
 +Customer
 +
 +Reservation
 +
 +Contract
 +
 +Document
 +
 +Payment
 +
 +Invoice
 +
 +Accounting
 +</code>
 +
 +----
 +
 +====== Flux métier désormais couvert ======
 +
 +<code>
 +Owner
 +
 +
 +
 +Property
 +
 +
 +
 +Customer
  
  
Ligne 2100: Ligne 2786:
  
 Contract Contract
 +
 +
 +
 +Signature
  
  
Ligne 2108: Ligne 2798:
  
 Invoice Invoice
 +
 +
 +
 +Accounting
 +</code>
 +
 +----
 +
 +====== Phase 2-F — CRM & Relation Client ======
 +
 +===== Objectif =====
 +
 +Mettre en place le CRM intégré de la plateforme.
 +
 +Contrairement à un CRM externe, ce module est directement connecté aux :
 +
 +  * Clients
 +  * Réservations
 +  * Contrats
 +  * Paiements
 +  * Propriétaires
 +  * Campagnes marketing
 +
 +Le CRM devient ainsi la vue 360° du client.
 +
 +----
 +
 +====== Architecture CRM ======
 +
 +===== Domaines =====
 +
 +<code>
 +Lead
 +
 +Opportunity
 +
 +Pipeline
 +
 +PipelineStage
 +
 +Activity
 +
 +Task
 +
 +CustomerNote
 +
 +Tag
 +
 +Segment
 +
 +CustomerTag
 +
 +LeadSource
 +</code>
 +
 +----
 +
 +====== Vue d'ensemble ======
 +
 +<code>
 +Lead
 +
 +
 +
 +Qualification
 +
 +
 +
 +Opportunity
 +
 +
 +
 +Reservation
 +
 +
 +
 +Customer
 +</code>
 +
 +----
 +
 +====== Lead ======
 +
 +===== Prospect =====
 +
 +<code prisma>
 +model Lead {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  leadNumber            String @unique
 +
 +  firstName             String
 +
 +  lastName              String
 +
 +  email                 String?
 +
 +  phone                 String?
 +
 +  company               String?
 +
 +  sourceId              String?
 +
 +  status                LeadStatus
 +
 +  score                 Int @default(0)
 +
 +  estimatedBudget       Decimal? @db.Decimal(10,2)
 +
 +  expectedCheckIn       DateTime?
 +
 +  expectedCheckOut      DateTime?
 +
 +  notes                 String?
 +
 +  assignedToUserId      String?
 +
 +  convertedAt           DateTime?
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  source                LeadSource? @relation(
 +                            fields:[sourceId],
 +                            references:[id]
 +                         )
 +
 +  opportunities         Opportunity[]
 +
 +  activities            Activity[]
 +}
 +</code>
 +
 +----
 +
 +===== LeadStatus =====
 +
 +<code prisma>
 +enum LeadStatus {
 +
 +  NEW
 +
 +  QUALIFIED
 +
 +  CONTACTED
 +
 +  PROPOSAL
 +
 +  WON
 +
 +  LOST
 +
 +  ARCHIVED
 +}
 +</code>
 +
 +----
 +
 +====== LeadSource ======
 +
 +===== Origine du prospect =====
 +
 +<code prisma>
 +model LeadSource {
 +
 +  id                    String @id @default(uuid())
 +
 +  code                  String @unique
 +
 +  name                  String
 +
 +  leads                 Lead[]
 +}
 +</code>
 +
 +----
 +
 +===== Valeurs =====
 +
 +<code>
 +WEBSITE
 +
 +PHONE
 +
 +EMAIL
 +
 +FACEBOOK
 +
 +INSTAGRAM
 +
 +GOOGLE
 +
 +AIRBNB
 +
 +BOOKING
 +
 +REFERRAL
 +</code>
 +
 +----
 +
 +====== Pipeline ======
 +
 +===== Pipeline commercial =====
 +
 +<code prisma>
 +model Pipeline {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  name                  String
 +
 +  active                Boolean @default(true)
 +
 +  stages                PipelineStage[]
 +
 +  opportunities         Opportunity[]
 +}
 +</code>
 +
 +----
 +
 +====== PipelineStage ======
 +
 +<code prisma>
 +model PipelineStage {
 +
 +  id                    String @id @default(uuid())
 +
 +  pipelineId            String
 +
 +  name                  String
 +
 +  position              Int
 +
 +  probability           Int
 +
 +  pipeline              Pipeline @relation(
 +                            fields:[pipelineId],
 +                            references:[id]
 +                         )
 +}
 +</code>
 +
 +----
 +
 +===== Exemple =====
 +
 +<code>
 +Nouveau
 +
 +Qualification
 +
 +Proposition
 +
 +Négociation
 +
 +Gagné
 +
 +Perdu
 +</code>
 +
 +----
 +
 +====== Opportunity ======
 +
 +===== Opportunité commerciale =====
 +
 +<code prisma>
 +model Opportunity {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  leadId                String
 +
 +  pipelineId            String
 +
 +  stageId               String
 +
 +  title                 String
 +
 +  amount                Decimal? @db.Decimal(10,2)
 +
 +  probability           Int
 +
 +  expectedCloseDate     DateTime?
 +
 +  status                OpportunityStatus
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  lead                  Lead @relation(
 +                            fields:[leadId],
 +                            references:[id]
 +                         )
 +
 +  pipeline              Pipeline @relation(
 +                            fields:[pipelineId],
 +                            references:[id]
 +                         )
 +}
 +</code>
 +
 +----
 +
 +===== OpportunityStatus =====
 +
 +<code prisma>
 +enum OpportunityStatus {
 +
 +  OPEN
 +
 +  WON
 +
 +  LOST
 +
 +  CANCELLED
 +}
 +</code>
 +
 +----
 +
 +====== Activity ======
 +
 +===== Historique des interactions =====
 +
 +<code prisma>
 +model Activity {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  leadId                String?
 +
 +  customerId            String?
 +
 +  activityType          ActivityType
 +
 +  subject               String
 +
 +  description           String?
 +
 +  occurredAt            DateTime
 +
 +  createdByUserId       String
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  lead                  Lead? @relation(
 +                            fields:[leadId],
 +                            references:[id]
 +                         )
 +
 +  customer              Customer? @relation(
 +                            fields:[customerId],
 +                            references:[id]
 +                         )
 +}
 +</code>
 +
 +----
 +
 +===== ActivityType =====
 +
 +<code prisma>
 +enum ActivityType {
 +
 +  CALL
 +
 +  EMAIL
 +
 +  MEETING
 +
 +  SMS
 +
 +  NOTE
 +
 +  TASK
 +
 +  SYSTEM
 +}
 +</code>
 +
 +----
 +
 +====== Task ======
 +
 +===== Tâches CRM =====
 +
 +<code prisma>
 +model Task {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  title                 String
 +
 +  description           String?
 +
 +  assignedToUserId      String
 +
 +  dueDate               DateTime?
 +
 +  completedAt           DateTime?
 +
 +  priority              TaskPriority
 +
 +  status                TaskStatus
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +}
 +</code>
 +
 +----
 +
 +===== TaskPriority =====
 +
 +<code prisma>
 +enum TaskPriority {
 +
 +  LOW
 +
 +  MEDIUM
 +
 +  HIGH
 +
 +  URGENT
 +}
 +</code>
 +
 +----
 +
 +===== TaskStatus =====
 +
 +<code prisma>
 +enum TaskStatus {
 +
 +  OPEN
 +
 +  IN_PROGRESS
 +
 +  DONE
 +
 +  CANCELLED
 +}
 +</code>
 +
 +----
 +
 +====== CustomerNote ======
 +
 +===== Notes internes =====
 +
 +<code prisma>
 +model CustomerNote {
 +
 +  id                    String @id @default(uuid())
 +
 +  customerId            String
 +
 +  authorUserId          String
 +
 +  content               String
 +
 +  createdAt             DateTime @default(now())
 +
 +  customer              Customer @relation(
 +                            fields:[customerId],
 +                            references:[id]
 +                         )
 +}
 +</code>
 +
 +----
 +
 +====== Tag ======
 +
 +===== Classification =====
 +
 +<code prisma>
 +model Tag {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  code                  String @unique
 +
 +  name                  String
 +
 +  color                 String?
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  customerTags          CustomerTag[]
 +}
 +</code>
 +
 +----
 +
 +====== CustomerTag ======
 +
 +===== Relation N:N =====
 +
 +<code prisma>
 +model CustomerTag {
 +
 +  customerId            String
 +
 +  tagId                 String
 +
 +  customer              Customer @relation(
 +                            fields:[customerId],
 +                            references:[id]
 +                         )
 +
 +  tag                   Tag @relation(
 +                            fields:[tagId],
 +                            references:[id]
 +                         )
 +
 +  @@id([customerId, tagId])
 +}
 +</code>
 +
 +----
 +
 +====== Segment ======
 +
 +===== Segmentation marketing =====
 +
 +<code prisma>
 +model Segment {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  code                  String @unique
 +
 +  name                  String
 +
 +  description           String?
 +
 +  rules                 Json
 +
 +  active                Boolean @default(true)
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +}
 +</code>
 +
 +----
 +
 +====== Relations à ajouter ======
 +
 +===== Customer =====
 +
 +Ajouter :
 +
 +<code prisma>
 +activities Activity[]
 +
 +notes CustomerNote[]
 +
 +tags CustomerTag[]
 +</code>
 +
 +----
 +
 +===== Tenant =====
 +
 +Ajouter :
 +
 +<code prisma>
 +leads Lead[]
 +
 +opportunities Opportunity[]
 +
 +pipelines Pipeline[]
 +
 +tasks Task[]
 +
 +segments Segment[]
 +</code>
 +
 +----
 +
 +====== Indexes ======
 +
 +===== Lead =====
 +
 +<code prisma>
 +@@index([tenantId])
 +
 +@@index([status])
 +
 +@@index([email])
 +
 +@@index([assignedToUserId])
 +</code>
 +
 +----
 +
 +===== Opportunity =====
 +
 +<code prisma>
 +@@index([tenantId])
 +
 +@@index([status])
 +
 +@@index([expectedCloseDate])
 +</code>
 +
 +----
 +
 +===== Task =====
 +
 +<code prisma>
 +@@index([assignedToUserId])
 +
 +@@index([status])
 +
 +@@index([dueDate])
 +</code>
 +
 +----
 +
 +====== Validation ======
 +
 +<code bash>
 +npx prisma format
 +
 +npx prisma validate
 +
 +npx prisma generate
 +</code>
 +
 +----
 +
 +====== Migration ======
 +
 +<code bash>
 +npx prisma migrate dev \
 +--name crm_and_customer_relationship
 +</code>
 +
 +----
 +
 +====== Fonctionnalités désormais couvertes ======
 +
 +===== Sprint 8 =====
 +
 +<code>
 +Prospects
 +
 +Pipeline
 +
 +Relances
 +
 +Activités
 +
 +Tâches
 +
 +Segmentation
 +
 +Historique client
 +
 +Vue 360°
 +</code>
 +
 +----
 +
 +====== Nouveau flux métier ======
 +
 +<code>
 +Lead
 +
 +
 +
 +Qualification
 +
 +
 +
 +Opportunity
 +
 +
 +
 +Reservation
 +
 +
 +
 +Contract
 +
 +
 +
 +Payment
 +
 +
 +
 +Customer Loyalty
 +</code>
 +
 +----
 +
 +====== État global du schéma ======
 +
 +Le noyau métier couvre désormais :
 +
 +<code>
 +RBAC
 +
 +Utilisateurs
 +
 +Propriétaires
 +
 +Catalogue
 +
 +Réservations
 +
 +Contrats
 +
 +Paiements
 +
 +Facturation
 +
 +CRM
 +</code>
 +
 +soit environ :
 +
 +<code>
 +35 à 40 modèles Prisma
 +</code>
 +
 +----
 +
 +====== Phase 2-G — Notifications, Messagerie & Communication ======
 +
 +===== Objectif =====
 +
 +Mettre en place le centre de communication unifié de la plateforme.
 +
 +Ce domaine couvre :
 +
 +  * Notifications Back Office
 +  * Notifications Client
 +  * Notifications Propriétaire
 +  * Emails transactionnels
 +  * SMS transactionnels
 +  * Messagerie interne
 +  * Conversations liées aux réservations
 +  * Historique des communications
 +
 +Ce domaine sera utilisé par :
 +
 +<code>
 +Reservations
 +
 +Contracts
 +
 +Payments
 +
 +CRM
 +
 +Owner Portal
 +
 +Administration
 +</code>
 +
 +----
 +
 +====== Architecture ======
 +
 +===== Modèles =====
 +
 +<code>
 +Notification
 +
 +NotificationTemplate
 +
 +NotificationPreference
 +
 +Conversation
 +
 +ConversationParticipant
 +
 +Message
 +
 +EmailLog
 +
 +SmsLog
 +</code>
 +
 +----
 +
 +====== Notification ======
 +
 +===== Centre de notifications =====
 +
 +<code prisma>
 +model Notification {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  userId                String
 +
 +  type                  NotificationType
 +
 +  title                 String
 +
 +  content               String
 +
 +  status                NotificationStatus
 +
 +  entityType            String?
 +
 +  entityId              String?
 +
 +  readAt                DateTime?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  user                  User @relation(
 +                            fields:[userId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([userId])
 +
 +  @@index([status])
 +
 +  @@index([createdAt])
 +}
 +</code>
 +
 +----
 +
 +===== NotificationType =====
 +
 +<code prisma>
 +enum NotificationType {
 +
 +  SYSTEM
 +
 +  RESERVATION
 +
 +  CONTRACT
 +
 +  PAYMENT
 +
 +  CRM
 +
 +  OWNER
 +
 +  SECURITY
 +
 +  MARKETING
 +}
 +</code>
 +
 +----
 +
 +===== NotificationStatus =====
 +
 +<code prisma>
 +enum NotificationStatus {
 +
 +  UNREAD
 +
 +  READ
 +
 +  ARCHIVED
 +}
 +</code>
 +
 +----
 +
 +====== NotificationTemplate ======
 +
 +===== Modèles de notification =====
 +
 +<code prisma>
 +model NotificationTemplate {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  code                  String
 +
 +  name                  String
 +
 +  subject               String?
 +
 +  content               String
 +
 +  channel               NotificationChannel
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  @@unique([tenantId, code])
 +}
 +</code>
 +
 +----
 +
 +===== NotificationChannel =====
 +
 +<code prisma>
 +enum NotificationChannel {
 +
 +  IN_APP
 +
 +  EMAIL
 +
 +  SMS
 +
 +  PUSH
 +}
 +</code>
 +
 +----
 +
 +====== NotificationPreference ======
 +
 +===== Préférences utilisateur =====
 +
 +<code prisma>
 +model NotificationPreference {
 +
 +  id                    String @id @default(uuid())
 +
 +  userId                String
 +
 +  notificationType      NotificationType
 +
 +  emailEnabled          Boolean @default(true)
 +
 +  smsEnabled            Boolean @default(false)
 +
 +  pushEnabled           Boolean @default(false)
 +
 +  inAppEnabled          Boolean @default(true)
 +
 +  user                  User @relation(
 +                            fields:[userId],
 +                            references:[id]
 +                         )
 +
 +  @@unique([userId, notificationType])
 +}
 +</code>
 +
 +----
 +
 +====== Conversation ======
 +
 +===== Fil de discussion =====
 +
 +<code prisma>
 +model Conversation {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  reservationId         String?
 +
 +  subject               String
 +
 +  status                ConversationStatus
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  reservation           Reservation? @relation(
 +                            fields:[reservationId],
 +                            references:[id]
 +                         )
 +
 +  participants          ConversationParticipant[]
 +
 +  messages              Message[]
 +
 +  @@index([tenantId])
 +
 +  @@index([reservationId])
 +}
 +</code>
 +
 +----
 +
 +===== ConversationStatus =====
 +
 +<code prisma>
 +enum ConversationStatus {
 +
 +  OPEN
 +
 +  CLOSED
 +
 +  ARCHIVED
 +}
 +</code>
 +
 +----
 +
 +====== ConversationParticipant ======
 +
 +===== Participants =====
 +
 +<code prisma>
 +model ConversationParticipant {
 +
 +  conversationId        String
 +
 +  userId                String?
 +
 +  customerId            String?
 +
 +  ownerId               String?
 +
 +  joinedAt              DateTime @default(now())
 +
 +  conversation          Conversation @relation(
 +                            fields:[conversationId],
 +                            references:[id]
 +                         )
 +
 +  user                  User? @relation(
 +                            fields:[userId],
 +                            references:[id]
 +                         )
 +
 +  customer              Customer? @relation(
 +                            fields:[customerId],
 +                            references:[id]
 +                         )
 +
 +  owner                 Owner? @relation(
 +                            fields:[ownerId],
 +                            references:[id]
 +                         )
 +
 +  @@id([
 +    conversationId,
 +    userId,
 +    customerId,
 +    ownerId
 +  ])
 +}
 +</code>
 +
 +----
 +
 +====== Message ======
 +
 +===== Message =====
 +
 +<code prisma>
 +model Message {
 +
 +  id                    String @id @default(uuid())
 +
 +  conversationId        String
 +
 +  senderUserId          String?
 +
 +  senderCustomerId      String?
 +
 +  senderOwnerId         String?
 +
 +  content               String
 +
 +  sentAt                DateTime @default(now())
 +
 +  readAt                DateTime?
 +
 +  conversation          Conversation @relation(
 +                            fields:[conversationId],
 +                            references:[id]
 +                         )
 +
 +  senderUser            User? @relation(
 +                            fields:[senderUserId],
 +                            references:[id]
 +                         )
 +
 +  senderCustomer        Customer? @relation(
 +                            fields:[senderCustomerId],
 +                            references:[id]
 +                         )
 +
 +  senderOwner           Owner? @relation(
 +                            fields:[senderOwnerId],
 +                            references:[id]
 +                         )
 +
 +  @@index([conversationId])
 +
 +  @@index([sentAt])
 +}
 +</code>
 +
 +----
 +
 +====== EmailLog ======
 +
 +===== Historique Emails =====
 +
 +<code prisma>
 +model EmailLog {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  templateId            String?
 +
 +  recipientEmail        String
 +
 +  subject               String
 +
 +  provider              String?
 +
 +  providerMessageId     String?
 +
 +  status                EmailStatus
 +
 +  errorMessage          String?
 +
 +  sentAt                DateTime?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  template              NotificationTemplate?
 +                          @relation(
 +                            fields:[templateId],
 +                            references:[id]
 +                          )
 +
 +  @@index([tenantId])
 +
 +  @@index([recipientEmail])
 +
 +  @@index([status])
 +}
 +</code>
 +
 +----
 +
 +===== EmailStatus =====
 +
 +<code prisma>
 +enum EmailStatus {
 +
 +  PENDING
 +
 +  SENT
 +
 +  DELIVERED
 +
 +  OPENED
 +
 +  FAILED
 +
 +  BOUNCED
 +}
 +</code>
 +
 +----
 +
 +====== SmsLog ======
 +
 +===== Historique SMS =====
 +
 +<code prisma>
 +model SmsLog {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  recipientPhone        String
 +
 +  content               String
 +
 +  provider              String?
 +
 +  providerMessageId     String?
 +
 +  status                SmsStatus
 +
 +  errorMessage          String?
 +
 +  sentAt                DateTime?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([recipientPhone])
 +
 +  @@index([status])
 +}
 +</code>
 +
 +----
 +
 +===== SmsStatus =====
 +
 +<code prisma>
 +enum SmsStatus {
 +
 +  PENDING
 +
 +  SENT
 +
 +  DELIVERED
 +
 +  FAILED
 +}
 +</code>
 +
 +----
 +
 +====== Relations à ajouter ======
 +
 +===== User =====
 +
 +<code prisma>
 +notifications Notification[]
 +
 +notificationPreferences NotificationPreference[]
 +
 +conversationParticipants
 +  ConversationParticipant[]
 +
 +messages Message[]
 +</code>
 +
 +----
 +
 +===== Customer =====
 +
 +<code prisma>
 +conversationParticipants
 +  ConversationParticipant[]
 +
 +messages Message[]
 +</code>
 +
 +----
 +
 +===== Owner =====
 +
 +<code prisma>
 +conversationParticipants
 +  ConversationParticipant[]
 +
 +messages Message[]
 +</code>
 +
 +----
 +
 +===== Reservation =====
 +
 +<code prisma>
 +conversations Conversation[]
 +</code>
 +
 +----
 +
 +===== Tenant =====
 +
 +<code prisma>
 +notifications Notification[]
 +
 +notificationTemplates NotificationTemplate[]
 +
 +conversations Conversation[]
 +
 +emailLogs EmailLog[]
 +
 +smsLogs SmsLog[]
 +</code>
 +
 +----
 +
 +====== Validation ======
 +
 +<code bash>
 +npx prisma format
 +
 +npx prisma validate
 +
 +npx prisma generate
 +</code>
 +
 +----
 +
 +====== Migration ======
 +
 +<code bash>
 +npx prisma migrate dev \
 +--name notifications_messaging
 +</code>
 +
 +----
 +
 +====== Fonctionnalités couvertes ======
 +
 +===== Sprint 9 =====
 +
 +<code>
 +Notifications temps réel
 +
 +Centre de notifications
 +
 +Messagerie propriétaire
 +
 +Messagerie client
 +
 +Messagerie réservation
 +
 +Emails transactionnels
 +
 +SMS transactionnels
 +
 +Préférences utilisateur
 +</code>
 +
 +----
 +
 +====== État du schéma ======
 +
 +Après Phase 2-G :
 +
 +<code>
 +≈ 60 modèles Prisma
 +</code>
 +
 +avec les domaines :
 +
 +<code>
 +Core
 +
 +Security
 +
 +Properties
 +
 +Owners
 +
 +Customers
 +
 +Reservations
 +
 +Contracts
 +
 +Payments
 +
 +CRM
 +
 +Notifications
 +
 +Messaging
 +</code>
 +
 +----
 +
 +====== Phase 2-H — Campagnes Marketing & Automatisation ======
 +
 +===== Objectif =====
 +
 +Mettre en place la couche marketing et automatisation de la plateforme.
 +
 +Ce domaine permettra :
 +
 +  * Campagnes Email
 +  * Campagnes SMS
 +  * Segmentation avancée
 +  * Marketing Automation
 +  * Relances automatiques
 +  * Nurturing prospects
 +  * Fidélisation clients
 +  * Déclencheurs métiers
 +
 +Cette phase finalise :
 +
 +<code>
 +Sprint 8 CRM
 +
 +Sprint 9 Communication
 +
 +Sprint 13 Automatisation & IA
 +</code>
 +
 +----
 +
 +====== Architecture ======
 +
 +===== Modèles =====
 +
 +<code>
 +Campaign
 +
 +CampaignRecipient
 +
 +CampaignExecution
 +
 +MarketingSegment
 +
 +MarketingEvent
 +
 +AutomationRule
 +
 +AutomationExecution
 +</code>
 +
 +----
 +
 +====== Campaign ======
 +
 +===== Campagne Marketing =====
 +
 +<code prisma>
 +model Campaign {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  code                  String
 +
 +  name                  String
 +
 +  description           String?
 +
 +  campaignType          CampaignType
 +
 +  status                CampaignStatus
 +
 +  startDate             DateTime?
 +
 +  endDate               DateTime?
 +
 +  createdByUserId       String?
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  createdByUser         User? @relation(
 +                            "CampaignCreator",
 +                            fields:[createdByUserId],
 +                            references:[id]
 +                         )
 +
 +  recipients            CampaignRecipient[]
 +
 +  executions            CampaignExecution[]
 +
 +  @@unique([tenantId, code])
 +
 +  @@index([tenantId])
 +
 +  @@index([status])
 +}
 +</code>
 +
 +----
 +
 +===== CampaignType =====
 +
 +<code prisma>
 +enum CampaignType {
 +
 +  EMAIL
 +
 +  SMS
 +
 +  MIXED
 +
 +  PUSH
 +
 +  WORKFLOW
 +}
 +</code>
 +
 +----
 +
 +===== CampaignStatus =====
 +
 +<code prisma>
 +enum CampaignStatus {
 +
 +  DRAFT
 +
 +  SCHEDULED
 +
 +  RUNNING
 +
 +  COMPLETED
 +
 +  PAUSED
 +
 +  CANCELLED
 +}
 +</code>
 +
 +----
 +
 +====== CampaignRecipient ======
 +
 +===== Destinataires =====
 +
 +<code prisma>
 +model CampaignRecipient {
 +
 +  id                    String @id @default(uuid())
 +
 +  campaignId            String
 +
 +  customerId            String?
 +
 +  leadId                String?
 +
 +  email                 String?
 +
 +  phone                 String?
 +
 +  status                CampaignRecipientStatus
 +
 +  sentAt                DateTime?
 +
 +  openedAt              DateTime?
 +
 +  clickedAt             DateTime?
 +
 +  unsubscribedAt        DateTime?
 +
 +  campaign              Campaign @relation(
 +                            fields:[campaignId],
 +                            references:[id]
 +                         )
 +
 +  customer              Customer? @relation(
 +                            fields:[customerId],
 +                            references:[id]
 +                         )
 +
 +  lead                  Lead? @relation(
 +                            fields:[leadId],
 +                            references:[id]
 +                         )
 +
 +  @@index([campaignId])
 +
 +  @@index([status])
 +}
 +</code>
 +
 +----
 +
 +===== CampaignRecipientStatus =====
 +
 +<code prisma>
 +enum CampaignRecipientStatus {
 +
 +  PENDING
 +
 +  SENT
 +
 +  OPENED
 +
 +  CLICKED
 +
 +  FAILED
 +
 +  UNSUBSCRIBED
 +}
 +</code>
 +
 +----
 +
 +====== CampaignExecution ======
 +
 +===== Exécution =====
 +
 +<code prisma>
 +model CampaignExecution {
 +
 +  id                    String @id @default(uuid())
 +
 +  campaignId            String
 +
 +  startedAt             DateTime
 +
 +  completedAt           DateTime?
 +
 +  recipientsCount       Int
 +
 +  successCount          Int
 +
 +  failedCount           Int
 +
 +  status                ExecutionStatus
 +
 +  campaign              Campaign @relation(
 +                            fields:[campaignId],
 +                            references:[id]
 +                         )
 +
 +  @@index([campaignId])
 +
 +  @@index([status])
 +}
 +</code>
 +
 +----
 +
 +===== ExecutionStatus =====
 +
 +<code prisma>
 +enum ExecutionStatus {
 +
 +  PENDING
 +
 +  RUNNING
 +
 +  COMPLETED
 +
 +  FAILED
 +}
 +</code>
 +
 +----
 +
 +====== MarketingSegment ======
 +
 +===== Segmentation avancée =====
 +
 +<code prisma>
 +model MarketingSegment {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  code                  String
 +
 +  name                  String
 +
 +  description           String?
 +
 +  rules                 Json
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  @@unique([tenantId, code])
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +CLIENTS_FIDELES
 +
 +CLIENTS_INACTIFS
 +
 +PROPRIETAIRES_ACTIFS
 +
 +PROSPECTS_CHAUDS
 +
 +RESERVATIONS_30J
 +
 +ANNIVERSAIRES
 +</code>
 +
 +----
 +
 +====== MarketingEvent ======
 +
 +===== Événements Marketing =====
 +
 +<code prisma>
 +model MarketingEvent {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  customerId            String?
 +
 +  leadId                String?
 +
 +  eventType             MarketingEventType
 +
 +  payload               Json?
 +
 +  occurredAt            DateTime
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  customer              Customer? @relation(
 +                            fields:[customerId],
 +                            references:[id]
 +                         )
 +
 +  lead                  Lead? @relation(
 +                            fields:[leadId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([eventType])
 +
 +  @@index([occurredAt])
 +}
 +</code>
 +
 +----
 +
 +===== MarketingEventType =====
 +
 +<code prisma>
 +enum MarketingEventType {
 +
 +  EMAIL_OPEN
 +
 +  EMAIL_CLICK
 +
 +  SMS_SENT
 +
 +  PAGE_VISIT
 +
 +  FORM_SUBMIT
 +
 +  LEAD_CREATED
 +
 +  RESERVATION_CREATED
 +
 +  CONTRACT_SIGNED
 +
 +  PAYMENT_COMPLETED
 +}
 +</code>
 +
 +----
 +
 +====== AutomationRule ======
 +
 +===== Règle métier =====
 +
 +<code prisma>
 +model AutomationRule {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  code                  String
 +
 +  name                  String
 +
 +  description           String?
 +
 +  triggerEvent          String
 +
 +  conditions            Json?
 +
 +  actions               Json
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  executions            AutomationExecution[]
 +
 +  @@unique([tenantId, code])
 +
 +  @@index([tenantId])
 +
 +  @@index([active])
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +ReservationConfirmed
 +
 +
 +
 +SendEmail
 +
 +----------------
 +
 +PaymentReceived
 +
 +
 +
 +GenerateInvoice
 +
 +----------------
 +
 +LeadCreated
 +
 +
 +
 +AssignSalesAgent
 +</code>
 +
 +----
 +
 +====== AutomationExecution ======
 +
 +===== Historique =====
 +
 +<code prisma>
 +model AutomationExecution {
 +
 +  id                    String @id @default(uuid())
 +
 +  automationRuleId      String
 +
 +  status                ExecutionStatus
 +
 +  entityType            String?
 +
 +  entityId              String?
 +
 +  startedAt             DateTime
 +
 +  completedAt           DateTime?
 +
 +  errorMessage          String?
 +
 +  automationRule        AutomationRule @relation(
 +                            fields:[automationRuleId],
 +                            references:[id]
 +                         )
 +
 +  @@index([automationRuleId])
 +
 +  @@index([status])
 +}
 +</code>
 +
 +----
 +
 +====== Relations à ajouter ======
 +
 +===== Tenant =====
 +
 +<code prisma>
 +campaigns Campaign[]
 +
 +marketingSegments MarketingSegment[]
 +
 +marketingEvents MarketingEvent[]
 +
 +automationRules AutomationRule[]
 +</code>
 +
 +----
 +
 +===== Customer =====
 +
 +<code prisma>
 +campaignRecipients CampaignRecipient[]
 +
 +marketingEvents MarketingEvent[]
 +</code>
 +
 +----
 +
 +===== Lead =====
 +
 +<code prisma>
 +campaignRecipients CampaignRecipient[]
 +
 +marketingEvents MarketingEvent[]
 +</code>
 +
 +----
 +
 +===== User =====
 +
 +<code prisma>
 +createdCampaigns Campaign[]
 +  @relation("CampaignCreator")
 +</code>
 +
 +----
 +
 +====== Validation ======
 +
 +<code bash>
 +npx prisma format
 +
 +npx prisma validate
 +
 +npx prisma generate
 +</code>
 +
 +----
 +
 +====== Migration ======
 +
 +<code bash>
 +npx prisma migrate dev \
 +--name marketing_automation
 +</code>
 +
 +----
 +
 +====== Fonctionnalités couvertes ======
 +
 +===== CRM =====
 +
 +<code>
 +Lead Nurturing
 +
 +Relances
 +
 +Segmentation
 +
 +Scoring
 +
 +Qualification
 +</code>
 +
 +----
 +
 +===== Communication =====
 +
 +<code>
 +Campagnes Email
 +
 +Campagnes SMS
 +
 +Suivi Ouvertures
 +
 +Suivi Clics
 +
 +Désabonnement
 +</code>
 +
 +----
 +
 +===== Automatisation =====
 +
 +<code>
 +Déclencheurs
 +
 +Workflows
 +
 +Actions Automatiques
 +
 +Historisation
 +</code>
 +
 +----
 +
 +====== État du schéma ======
 +
 +Après Phase 2-H :
 +
 +<code>
 +≈ 67 modèles Prisma
 +</code>
 +
 +avec les domaines :
 +
 +<code>
 +Core
 +
 +Security
 +
 +Properties
 +
 +Owners
 +
 +Customers
 +
 +Reservations
 +
 +Contracts
 +
 +Payments
 +
 +CRM
 +
 +Messaging
 +
 +Marketing
 +
 +Automation
 +</code>
 +
 +----
 +
 +====== Phase 2-I — Administration, Audit & Gouvernance ======
 +
 +===== Objectif =====
 +
 +Mettre en place la couche transverse de gouvernance de la plateforme.
 +
 +Cette couche doit permettre :
 +
 +  * Audit complet des actions
 +  * Historisation métier
 +  * Activation dynamique de fonctionnalités
 +  * Workflows métiers configurables
 +  * Gouvernance des données
 +  * Traçabilité réglementaire
 +  * Préparation RGPD / ISO27001 / SOC2
 +
 +Cette phase prépare directement :
 +
 +<code>
 +Sprint 10 — Reporting
 +
 +Sprint 11 — Administration
 +
 +Sprint 19 — Gouvernance & Conformité
 +</code>
 +
 +----
 +
 +====== Architecture ======
 +
 +===== Modèles =====
 +
 +<code>
 +AuditLog
 +
 +EntityHistory
 +
 +FeatureFlag
 +
 +Workflow
 +
 +WorkflowStep
 +
 +WorkflowInstance
 +
 +WorkflowExecution
 +</code>
 +
 +----
 +
 +====== AuditLog ======
 +
 +===== Journal d'audit =====
 +
 +Toutes les actions sensibles doivent être tracées.
 +
 +<code prisma>
 +model AuditLog {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  userId                String?
 +
 +  entityType            String
 +
 +  entityId              String
 +
 +  action                AuditAction
 +
 +  oldValues             Json?
 +
 +  newValues             Json?
 +
 +  ipAddress             String?
 +
 +  userAgent             String?
 +
 +  correlationId         String?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  user                  User? @relation(
 +                            fields:[userId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([entityType])
 +
 +  @@index([entityId])
 +
 +  @@index([action])
 +
 +  @@index([createdAt])
 +}
 +</code>
 +
 +----
 +
 +===== AuditAction =====
 +
 +<code prisma>
 +enum AuditAction {
 +
 +  CREATE
 +
 +  UPDATE
 +
 +  DELETE
 +
 +  RESTORE
 +
 +  LOGIN
 +
 +  LOGOUT
 +
 +  EXPORT
 +
 +  IMPORT
 +
 +  EXECUTE
 +
 +  APPROVE
 +
 +  REJECT
 +}
 +</code>
 +
 +----
 +
 +====== EntityHistory ======
 +
 +===== Historisation métier =====
 +
 +Permet de reconstruire l'état d'une entité à n'importe quelle date.
 +
 +<code prisma>
 +model EntityHistory {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  entityType            String
 +
 +  entityId              String
 +
 +  version               Int
 +
 +  snapshot              Json
 +
 +  createdByUserId       String?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  createdByUser         User? @relation(
 +                            fields:[createdByUserId],
 +                            references:[id]
 +                         )
 +
 +  @@unique([
 +    entityType,
 +    entityId,
 +    version
 +  ])
 +
 +  @@index([tenantId])
 +
 +  @@index([entityType])
 +
 +  @@index([entityId])
 +}
 +</code>
 +
 +----
 +
 +====== FeatureFlag ======
 +
 +===== Activation dynamique =====
 +
 +Permet de déployer progressivement des fonctionnalités.
 +
 +<code prisma>
 +model FeatureFlag {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String?
 +
 +  code                  String @unique
 +
 +  name                  String
 +
 +  description           String?
 +
 +  enabled               Boolean @default(false)
 +
 +  configuration         Json?
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant? @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([enabled])
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +AI_ASSISTANT
 +
 +OWNER_PORTAL_V2
 +
 +OTA_SYNC
 +
 +REVENUE_MANAGEMENT
 +
 +ADVANCED_REPORTING
 +</code>
 +
 +----
 +
 +====== Workflow ======
 +
 +===== Définition d'un workflow =====
 +
 +<code prisma>
 +model Workflow {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  code                  String
 +
 +  name                  String
 +
 +  description           String?
 +
 +  entityType            String
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  steps                 WorkflowStep[]
 +
 +  instances             WorkflowInstance[]
 +
 +  @@unique([tenantId, code])
 +
 +  @@index([tenantId])
 +
 +  @@index([entityType])
 +}
 +</code>
 +
 +----
 +
 +====== WorkflowStep ======
 +
 +===== Étapes du workflow =====
 +
 +<code prisma>
 +model WorkflowStep {
 +
 +  id                    String @id @default(uuid())
 +
 +  workflowId            String
 +
 +  code                  String
 +
 +  name                  String
 +
 +  position              Int
 +
 +  approverRoleCode      String?
 +
 +  automatic             Boolean @default(false)
 +
 +  configuration         Json?
 +
 +  workflow              Workflow @relation(
 +                            fields:[workflowId],
 +                            references:[id]
 +                         )
 +
 +  @@unique([
 +    workflowId,
 +    code
 +  ])
 +
 +  @@index([workflowId])
 +
 +  @@index([position])
 +}
 +</code>
 +
 +----
 +
 +===== Exemple =====
 +
 +<code>
 +ReservationApproval
 +
 +
 +
 +ManagerApproval
 +
 +
 +
 +ContractGeneration
 +
 +
 +
 +PaymentValidation
 +
 +
 +
 +Completed
 +</code>
 +
 +----
 +
 +====== WorkflowInstance ======
 +
 +===== Exécution métier =====
 +
 +<code prisma>
 +model WorkflowInstance {
 +
 +  id                    String @id @default(uuid())
 +
 +  workflowId            String
 +
 +  entityType            String
 +
 +  entityId              String
 +
 +  currentStepId         String?
 +
 +  status                WorkflowInstanceStatus
 +
 +  startedAt             DateTime @default(now())
 +
 +  completedAt           DateTime?
 +
 +  workflow              Workflow @relation(
 +                            fields:[workflowId],
 +                            references:[id]
 +                         )
 +
 +  currentStep           WorkflowStep?
 +                          @relation(
 +                            fields:[currentStepId],
 +                            references:[id]
 +                          )
 +
 +  executions            WorkflowExecution[]
 +
 +  @@index([workflowId])
 +
 +  @@index([entityType])
 +
 +  @@index([entityId])
 +
 +  @@index([status])
 +}
 +</code>
 +
 +----
 +
 +===== WorkflowInstanceStatus =====
 +
 +<code prisma>
 +enum WorkflowInstanceStatus {
 +
 +  RUNNING
 +
 +  WAITING
 +
 +  APPROVED
 +
 +  REJECTED
 +
 +  COMPLETED
 +
 +  CANCELLED
 +}
 +</code>
 +
 +----
 +
 +====== WorkflowExecution ======
 +
 +===== Historique des étapes =====
 +
 +<code prisma>
 +model WorkflowExecution {
 +
 +  id                    String @id @default(uuid())
 +
 +  workflowInstanceId    String
 +
 +  workflowStepId        String
 +
 +  executedByUserId      String?
 +
 +  status                WorkflowExecutionStatus
 +
 +  comments              String?
 +
 +  executedAt            DateTime @default(now())
 +
 +  workflowInstance      WorkflowInstance @relation(
 +                            fields:[workflowInstanceId],
 +                            references:[id]
 +                         )
 +
 +  workflowStep          WorkflowStep @relation(
 +                            fields:[workflowStepId],
 +                            references:[id]
 +                         )
 +
 +  executedByUser        User? @relation(
 +                            fields:[executedByUserId],
 +                            references:[id]
 +                         )
 +
 +  @@index([workflowInstanceId])
 +
 +  @@index([workflowStepId])
 +
 +  @@index([executedAt])
 +}
 +</code>
 +
 +----
 +
 +===== WorkflowExecutionStatus =====
 +
 +<code prisma>
 +enum WorkflowExecutionStatus {
 +
 +  PENDING
 +
 +  APPROVED
 +
 +  REJECTED
 +
 +  SKIPPED
 +
 +  COMPLETED
 +}
 +</code>
 +
 +----
 +
 +====== Relations à ajouter ======
 +
 +===== Tenant =====
 +
 +<code prisma>
 +auditLogs AuditLog[]
 +
 +entityHistories EntityHistory[]
 +
 +featureFlags FeatureFlag[]
 +
 +workflows Workflow[]
 +</code>
 +
 +----
 +
 +===== User =====
 +
 +<code prisma>
 +auditLogs AuditLog[]
 +
 +entityHistories EntityHistory[]
 +
 +workflowExecutions WorkflowExecution[]
 +</code>
 +
 +----
 +
 +====== Cas d'usage métiers ======
 +
 +===== Réservation =====
 +
 +<code>
 +Reservation Created
 +
 +
 +
 +AuditLog
 +
 +
 +
 +Workflow Instance
 +
 +
 +
 +Manager Approval
 +
 +
 +
 +Contract Generation
 +</code>
 +
 +----
 +
 +===== Paiement =====
 +
 +<code>
 +Payment Refunded
 +
 +
 +
 +AuditLog
 +
 +
 +
 +History Snapshot
 +
 +
 +
 +Compliance Trace
 +</code>
 +
 +----
 +
 +===== Administration =====
 +
 +<code>
 +Feature Enabled
 +
 +
 +
 +AuditLog
 +
 +
 +
 +History
 +
 +
 +
 +Reporting
 +</code>
 +
 +----
 +
 +====== Validation ======
 +
 +<code bash>
 +npx prisma format
 +
 +npx prisma validate
 +
 +npx prisma generate
 +</code>
 +
 +----
 +
 +====== Migration ======
 +
 +<code bash>
 +npx prisma migrate dev \
 +--name administration_audit_governance
 +</code>
 +
 +----
 +
 +====== Fonctionnalités couvertes ======
 +
 +===== Administration =====
 +
 +<code>
 +Feature Flags
 +
 +Workflows
 +
 +Validation
 +
 +Approbation
 +</code>
 +
 +----
 +
 +===== Audit =====
 +
 +<code>
 +Journalisation
 +
 +Traçabilité
 +
 +Historisation
 +
 +Conformité
 +</code>
 +
 +----
 +
 +===== Gouvernance =====
 +
 +<code>
 +Contrôle
 +
 +Supervision
 +
 +Rétention
 +
 +Preuve d'audit
 +</code>
 +
 +----
 +
 +====== État du schéma ======
 +
 +Après Phase 2-I :
 +
 +<code>
 +≈ 74 modèles Prisma
 +</code>
 +
 +avec les domaines :
 +
 +<code>
 +Core
 +
 +Security
 +
 +Properties
 +
 +Owners
 +
 +Customers
 +
 +Reservations
 +
 +Contracts
 +
 +Payments
 +
 +CRM
 +
 +Messaging
 +
 +Marketing
 +
 +Automation
 +
 +Governance
 +</code>
 +
 +----
 +
 +====== Phase 2-J — OTA & Channel Manager ======
 +
 +===== Objectif =====
 +
 +Construire le moteur de distribution multicanal de la plateforme.
 +
 +Ce domaine permettra :
 +
 +  * Synchronisation Airbnb
 +  * Synchronisation Booking.com
 +  * Synchronisation Vrbo
 +  * Synchronisation Abritel
 +  * Publication automatique des biens
 +  * Synchronisation des disponibilités
 +  * Synchronisation des tarifs
 +  * Synchronisation des réservations
 +  * Gestion des erreurs de synchronisation
 +
 +Cette phase couvre :
 +
 +<code>
 +Sprint 12 — OTA & Distribution
 +
 +Sprint 14 — API & Partenaires
 +
 +Sprint 18 — Channel Manager Enterprise
 +</code>
 +
 +----
 +
 +====== Architecture ======
 +
 +===== Modèles =====
 +
 +<code>
 +Channel
 +
 +ChannelConnection
 +
 +PropertyDistribution
 +
 +ChannelReservation
 +
 +SyncExecution
 +
 +SyncError
 +</code>
 +
 +----
 +
 +====== Channel ======
 +
 +===== Catalogue OTA =====
 +
 +Référentiel des plateformes connectables.
 +
 +<code prisma>
 +model Channel {
 +
 +  id                    String @id @default(uuid())
 +
 +  code                  String @unique
 +
 +  name                  String
 +
 +  channelType           ChannelType
 +
 +  active                Boolean @default(true)
 +
 +  apiDocumentationUrl   String?
 +
 +  logoUrl               String?
 +
 +  createdAt             DateTime @default(now())
 +
 +  connections           ChannelConnection[]
 +
 +  distributions         PropertyDistribution[]
 +}
 +</code>
 +
 +----
 +
 +===== ChannelType =====
 +
 +<code prisma>
 +enum ChannelType {
 +
 +  OTA
 +
 +  DIRECT
 +
 +  PARTNER
 +
 +  API
 +
 +  MARKETPLACE
 +}
 +</code>
 +
 +----
 +
 +===== Valeurs initiales =====
 +
 +<code>
 +AIRBNB
 +
 +BOOKING
 +
 +VRBO
 +
 +ABRITEL
 +
 +EXPEDIA
 +
 +DIRECT_WEBSITE
 +</code>
 +
 +----
 +
 +====== ChannelConnection ======
 +
 +===== Connexion OTA =====
 +
 +Une agence peut posséder plusieurs connexions.
 +
 +<code prisma>
 +model ChannelConnection {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  channelId             String
 +
 +  connectionName        String
 +
 +  accountIdentifier     String?
 +
 +  apiKey                String?
 +
 +  apiSecret             String?
 +
 +  refreshToken          String?
 +
 +  configuration         Json?
 +
 +  active                Boolean @default(true)
 +
 +  lastSyncAt            DateTime?
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  channel               Channel @relation(
 +                            fields:[channelId],
 +                            references:[id]
 +                         )
 +
 +  propertyDistributions PropertyDistribution[]
 +
 +  syncExecutions        SyncExecution[]
 +
 +  @@index([tenantId])
 +
 +  @@index([channelId])
 +
 +  @@index([active])
 +}
 +</code>
 +
 +----
 +
 +====== PropertyDistribution ======
 +
 +===== Publication d'un bien =====
 +
 +Permet d'associer un bien à un canal de distribution.
 +
 +<code prisma>
 +model PropertyDistribution {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  propertyId            String
 +
 +  channelId             String
 +
 +  channelConnectionId   String
 +
 +  externalPropertyId    String?
 +
 +  externalListingId     String?
 +
 +  published             Boolean @default(false)
 +
 +  publicationStatus     DistributionStatus
 +
 +  publishedAt           DateTime?
 +
 +  lastSyncAt            DateTime?
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  property              Property @relation(
 +                            fields:[propertyId],
 +                            references:[id]
 +                         )
 +
 +  channel               Channel @relation(
 +                            fields:[channelId],
 +                            references:[id]
 +                         )
 +
 +  channelConnection     ChannelConnection @relation(
 +                            fields:[channelConnectionId],
 +                            references:[id]
 +                         )
 +
 +  reservations          ChannelReservation[]
 +
 +  @@unique([
 +    propertyId,
 +    channelConnectionId
 +  ])
 +
 +  @@index([tenantId])
 +
 +  @@index([propertyId])
 +
 +  @@index([channelId])
 +
 +  @@index([publicationStatus])
 +}
 +</code>
 +
 +----
 +
 +===== DistributionStatus =====
 +
 +<code prisma>
 +enum DistributionStatus {
 +
 +  DRAFT
 +
 +  PENDING
 +
 +  PUBLISHED
 +
 +  SUSPENDED
 +
 +  ERROR
 +
 +  ARCHIVED
 +}
 +</code>
 +
 +----
 +
 +====== ChannelReservation ======
 +
 +===== Réservation OTA =====
 +
 +Historise le lien entre la réservation interne et la réservation OTA.
 +
 +<code prisma>
 +model ChannelReservation {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  reservationId         String
 +
 +  propertyDistributionId String
 +
 +  externalReservationId String
 +
 +  externalStatus        String?
 +
 +  importedAt            DateTime @default(now())
 +
 +  lastSyncAt            DateTime?
 +
 +  reservation           Reservation @relation(
 +                            fields:[reservationId],
 +                            references:[id]
 +                         )
 +
 +  propertyDistribution  PropertyDistribution @relation(
 +                            fields:[propertyDistributionId],
 +                            references:[id]
 +                         )
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  @@unique([
 +    propertyDistributionId,
 +    externalReservationId
 +  ])
 +
 +  @@index([tenantId])
 +
 +  @@index([reservationId])
 +
 +  @@index([importedAt])
 +}
 +</code>
 +
 +----
 +
 +====== SyncExecution ======
 +
 +===== Historique des synchronisations =====
 +
 +Chaque synchronisation OTA doit être historisée.
 +
 +<code prisma>
 +model SyncExecution {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  channelConnectionId   String
 +
 +  syncType              SyncType
 +
 +  status                SyncStatus
 +
 +  startedAt             DateTime
 +
 +  completedAt           DateTime?
 +
 +  processedCount        Int @default(0)
 +
 +  successCount          Int @default(0)
 +
 +  errorCount            Int @default(0)
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  channelConnection     ChannelConnection @relation(
 +                            fields:[channelConnectionId],
 +                            references:[id]
 +                         )
 +
 +  errors                SyncError[]
 +
 +  @@index([tenantId])
 +
 +  @@index([channelConnectionId])
 +
 +  @@index([syncType])
 +
 +  @@index([status])
 +
 +  @@index([startedAt])
 +}
 +</code>
 +
 +----
 +
 +===== SyncType =====
 +
 +<code prisma>
 +enum SyncType {
 +
 +  PROPERTY_EXPORT
 +
 +  AVAILABILITY_EXPORT
 +
 +  RATE_EXPORT
 +
 +  RESERVATION_IMPORT
 +
 +  FULL_SYNC
 +}
 +</code>
 +
 +----
 +
 +===== SyncStatus =====
 +
 +<code prisma>
 +enum SyncStatus {
 +
 +  PENDING
 +
 +  RUNNING
 +
 +  COMPLETED
 +
 +  PARTIAL_SUCCESS
 +
 +  FAILED
 +}
 +</code>
 +
 +----
 +
 +====== SyncError ======
 +
 +===== Gestion des erreurs =====
 +
 +Permet d'analyser les échecs OTA.
 +
 +<code prisma>
 +model SyncError {
 +
 +  id                    String @id @default(uuid())
 +
 +  syncExecutionId       String
 +
 +  errorCode             String?
 +
 +  errorMessage          String
 +
 +  entityType            String?
 +
 +  entityId              String?
 +
 +  payload               Json?
 +
 +  occurredAt            DateTime @default(now())
 +
 +  syncExecution         SyncExecution @relation(
 +                            fields:[syncExecutionId],
 +                            references:[id]
 +                         )
 +
 +  @@index([syncExecutionId])
 +
 +  @@index([errorCode])
 +
 +  @@index([occurredAt])
 +}
 +</code>
 +
 +----
 +
 +====== Relations à ajouter ======
 +
 +===== Tenant =====
 +
 +<code prisma>
 +channelConnections ChannelConnection[]
 +
 +propertyDistributions PropertyDistribution[]
 +
 +channelReservations ChannelReservation[]
 +
 +syncExecutions SyncExecution[]
 +</code>
 +
 +----
 +
 +===== Property =====
 +
 +<code prisma>
 +propertyDistributions PropertyDistribution[]
 +</code>
 +
 +----
 +
 +===== Reservation =====
 +
 +<code prisma>
 +channelReservations ChannelReservation[]
 +</code>
 +
 +----
 +
 +====== Synchronisations couvertes ======
 +
 +===== Disponibilités =====
 +
 +<code>
 +PropertyAvailability
 +
 +
 +
 +OTA
 +</code>
 +
 +----
 +
 +===== Tarifs =====
 +
 +<code>
 +PropertyRate
 +
 +
 +
 +OTA
 +</code>
 +
 +----
 +
 +===== Réservations =====
 +
 +<code>
 +OTA
 +
 +
 +
 +ChannelReservation
 +
 +
 +
 +Reservation
 +</code>
 +
 +----
 +
 +===== Publication =====
 +
 +<code>
 +Property
 +
 +
 +
 +PropertyDistribution
 +
 +
 +
 +Airbnb
 +
 +Booking
 +
 +Vrbo
 +
 +Abritel
 +</code>
 +
 +----
 +
 +====== Validation ======
 +
 +<code bash>
 +npx prisma format
 +
 +npx prisma validate
 +
 +npx prisma generate
 +</code>
 +
 +----
 +
 +====== Migration ======
 +
 +<code bash>
 +npx prisma migrate dev \
 +--name ota_channel_manager
 +</code>
 +
 +----
 +
 +====== Fonctionnalités couvertes ======
 +
 +===== Sprint 12 =====
 +
 +<code>
 +Publication OTA
 +
 +Synchronisation calendrier
 +
 +Synchronisation tarifs
 +
 +Import réservations
 +</code>
 +
 +----
 +
 +===== Sprint 14 =====
 +
 +<code>
 +Partenaires
 +
 +API externes
 +
 +Marketplace
 +</code>
 +
 +----
 +
 +===== Sprint 18 =====
 +
 +<code>
 +Channel Manager Enterprise
 +
 +Multi-OTA
 +
 +Monitoring synchronisations
 +
 +Gestion erreurs
 +</code>
 +
 +----
 +
 +====== État du schéma ======
 +
 +Après Phase 2-J :
 +
 +<code>
 +≈ 80 modèles Prisma
 +</code>
 +
 +avec les domaines :
 +
 +<code>
 +Core
 +
 +Security
 +
 +Properties
 +
 +Owners
 +
 +Customers
 +
 +Reservations
 +
 +Contracts
 +
 +Payments
 +
 +CRM
 +
 +Messaging
 +
 +Marketing
 +
 +Automation
 +
 +Governance
 +
 +OTA
 +</code>
 +
 +----
 +
 +====== Phase 2-K — Revenue Management & Tarification Dynamique ======
 +
 +===== Objectif =====
 +
 +Construire le moteur de Revenue Management de la plateforme.
 +
 +Ce domaine permettra :
 +
 +  * Tarification dynamique
 +  * Yield Management
 +  * Prévisions de revenus
 +  * Analyse de la demande
 +  * Analyse concurrentielle
 +  * Optimisation automatique des prix
 +  * Simulation financière
 +  * Aide à la décision
 +
 +Cette phase couvre :
 +
 +<code>
 +Sprint 10 — Reporting
 +
 +Sprint 13 — IA & Prévisions
 +
 +Sprint 17 — Revenue Management
 +
 +Sprint 20 — Enterprise Analytics
 +</code>
 +
 +----
 +
 +====== Architecture ======
 +
 +===== Modèles =====
 +
 +<code>
 +PricingRule
 +
 +DynamicPrice
 +
 +RevenueForecast
 +
 +RevenueSimulation
 +
 +CompetitorSnapshot
 +
 +MarketDemand
 +</code>
 +
 +----
 +
 +====== PricingRule ======
 +
 +===== Règle tarifaire =====
 +
 +Définit les règles d'ajustement automatique.
 +
 +<code prisma>
 +model PricingRule {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  propertyId            String?
 +
 +  code                  String
 +
 +  name                  String
 +
 +  description           String?
 +
 +  priority              Int @default(100)
 +
 +  active                Boolean @default(true)
 +
 +  conditions            Json
 +
 +  actions               Json
 +
 +  validFrom             DateTime?
 +
 +  validTo               DateTime?
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  property              Property? @relation(
 +                            fields:[propertyId],
 +                            references:[id]
 +                         )
 +
 +  @@unique([tenantId, code])
 +
 +  @@index([tenantId])
 +
 +  @@index([propertyId])
 +
 +  @@index([active])
 +
 +  @@index([priority])
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +Occupation > 80%
 +
 +
 +
 ++15%
 +
 +----------------
 +
 +Weekend
 +
 +
 +
 ++10%
 +
 +----------------
 +
 +Haute saison
 +
 +
 +
 ++25%
 +</code>
 +
 +----
 +
 +====== DynamicPrice ======
 +
 +===== Prix calculé =====
 +
 +Prix final appliqué à une date donnée.
 +
 +<code prisma>
 +model DynamicPrice {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  propertyId            String
 +
 +  pricingDate           DateTime
 +
 +  basePrice             Decimal @db.Decimal(12,2)
 +
 +  adjustedPrice         Decimal @db.Decimal(12,2)
 +
 +  occupancyFactor       Decimal? @db.Decimal(5,2)
 +
 +  seasonalityFactor     Decimal? @db.Decimal(5,2)
 +
 +  demandFactor          Decimal? @db.Decimal(5,2)
 +
 +  competitorFactor      Decimal? @db.Decimal(5,2)
 +
 +  generatedAt           DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  property              Property @relation(
 +                            fields:[propertyId],
 +                            references:[id]
 +                         )
 +
 +  @@unique([
 +    propertyId,
 +    pricingDate
 +  ])
 +
 +  @@index([tenantId])
 +
 +  @@index([propertyId])
 +
 +  @@index([pricingDate])
 +}
 +</code>
 +
 +----
 +
 +====== RevenueForecast ======
 +
 +===== Prévisions =====
 +
 +Prévision de revenus futurs.
 +
 +<code prisma>
 +model RevenueForecast {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  propertyId            String?
 +
 +  forecastDate          DateTime
 +
 +  forecastPeriodStart   DateTime
 +
 +  forecastPeriodEnd     DateTime
 +
 +  expectedRevenue       Decimal @db.Decimal(14,2)
 +
 +  expectedOccupancy     Decimal @db.Decimal(5,2)
 +
 +  confidenceLevel       Decimal @db.Decimal(5,2)
 +
 +  modelVersion          String?
 +
 +  generatedAt           DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  property              Property? @relation(
 +                            fields:[propertyId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([propertyId])
 +
 +  @@index([forecastDate])
 +}
 +</code>
 +
 +----
 +
 +====== RevenueSimulation ======
 +
 +===== Simulation =====
 +
 +Analyse de scénarios.
 +
 +<code prisma>
 +model RevenueSimulation {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  propertyId            String?
 +
 +  name                  String
 +
 +  assumptions           Json
 +
 +  projectedRevenue      Decimal @db.Decimal(14,2)
 +
 +  projectedOccupancy    Decimal @db.Decimal(5,2)
 +
 +  createdByUserId       String?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  property              Property? @relation(
 +                            fields:[propertyId],
 +                            references:[id]
 +                         )
 +
 +  createdByUser         User? @relation(
 +                            fields:[createdByUserId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([propertyId])
 +}
 +</code>
 +
 +----
 +
 +===== Exemple =====
 +
 +<code>
 +Prix +10%
 +
 +
 +
 +Occupation -3%
 +
 +
 +
 +CA +6%
 +</code>
 +
 +----
 +
 +====== CompetitorSnapshot ======
 +
 +===== Veille concurrentielle =====
 +
 +Capture des prix concurrents.
 +
 +<code prisma>
 +model CompetitorSnapshot {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  propertyId            String
 +
 +  competitorName        String
 +
 +  competitorPropertyId  String?
 +
 +  snapshotDate          DateTime
 +
 +  nightlyRate           Decimal @db.Decimal(12,2)
 +
 +  occupancy             Decimal? @db.Decimal(5,2)
 +
 +  source                String?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  property              Property @relation(
 +                            fields:[propertyId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([propertyId])
 +
 +  @@index([snapshotDate])
 +}
 +</code>
 +
 +----
 +
 +====== MarketDemand ======
 +
 +===== Indicateurs marché =====
 +
 +Mesure de la demande.
 +
 +<code prisma>
 +model MarketDemand {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  regionCode            String
 +
 +  demandDate            DateTime
 +
 +  demandIndex           Decimal @db.Decimal(5,2)
 +
 +  occupancyIndex        Decimal @db.Decimal(5,2)
 +
 +  averageDailyRate      Decimal @db.Decimal(12,2)
 +
 +  source                String?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([regionCode])
 +
 +  @@index([demandDate])
 +}
 +</code>
 +
 +----
 +
 +====== Relations à ajouter ======
 +
 +===== Property =====
 +
 +<code prisma>
 +pricingRules PricingRule[]
 +
 +dynamicPrices DynamicPrice[]
 +
 +revenueForecasts RevenueForecast[]
 +
 +revenueSimulations RevenueSimulation[]
 +
 +competitorSnapshots CompetitorSnapshot[]
 +</code>
 +
 +----
 +
 +===== Tenant =====
 +
 +<code prisma>
 +pricingRules PricingRule[]
 +
 +dynamicPrices DynamicPrice[]
 +
 +revenueForecasts RevenueForecast[]
 +
 +revenueSimulations RevenueSimulation[]
 +
 +marketDemands MarketDemand[]
 +</code>
 +
 +----
 +
 +====== Cas d'usage ======
 +
 +===== Tarification dynamique =====
 +
 +<code>
 +Occupation
 +
 ++
 +
 +Saisonnalité
 +
 ++
 +
 +Concurrence
 +
 ++
 +
 +Demande
 +
 +
 +
 +Prix optimal
 +</code>
 +
 +----
 +
 +===== Prévision =====
 +
 +<code>
 +Historique réservations
 +
 +
 +
 +Forecast IA
 +
 +
 +
 +Revenus prévus
 +</code>
 +
 +----
 +
 +===== Simulation =====
 +
 +<code>
 +Nouveau tarif
 +
 +
 +
 +Simulation
 +
 +
 +
 +Impact CA
 +</code>
 +
 +----
 +
 +====== Validation ======
 +
 +<code bash>
 +npx prisma format
 +
 +npx prisma validate
 +
 +npx prisma generate
 +</code>
 +
 +----
 +
 +====== Migration ======
 +
 +<code bash>
 +npx prisma migrate dev \
 +--name revenue_management
 +</code>
 +
 +----
 +
 +====== Fonctionnalités couvertes ======
 +
 +===== Revenue Management =====
 +
 +<code>
 +Yield Management
 +
 +Dynamic Pricing
 +
 +Optimisation tarifaire
 +</code>
 +
 +----
 +
 +===== Analytics =====
 +
 +<code>
 +Forecast
 +
 +Simulation
 +
 +Benchmark concurrence
 +
 +Demand Analytics
 +</code>
 +
 +----
 +
 +===== IA =====
 +
 +<code>
 +Aide à la décision
 +
 +Prévisions
 +
 +Recommandations
 +</code>
 +
 +----
 +
 +====== État du schéma ======
 +
 +Après Phase 2-K :
 +
 +<code>
 +≈ 86 modèles Prisma
 +</code>
 +
 +avec les domaines :
 +
 +<code>
 +Core
 +
 +Security
 +
 +Properties
 +
 +Owners
 +
 +Customers
 +
 +Reservations
 +
 +Contracts
 +
 +Payments
 +
 +CRM
 +
 +Messaging
 +
 +Marketing
 +
 +Automation
 +
 +Governance
 +
 +OTA
 +
 +Revenue Management
 +</code>
 +
 +----
 +
 +====== Phase 2-L — Sécurité Enterprise & Conformité ======
 +
 +===== Objectif =====
 +
 +Construire la couche Enterprise de sécurité, conformité et gouvernance des données.
 +
 +Cette phase permettra :
 +
 +  * Conformité RGPD
 +  * Gestion des consentements
 +  * Gestion des risques
 +  * Gouvernance des données
 +  * Classification des données
 +  * Rétention réglementaire
 +  * Gestion des incidents de sécurité
 +  * Préparation ISO 27001
 +  * Préparation SOC2
 +  * Préparation NIS2
 +
 +Cette phase couvre :
 +
 +<code>
 +Sprint 19
 +
 +Governance
 +
 +Compliance
 +
 +Enterprise Security
 +</code>
 +
 +----
 +
 +====== Architecture ======
 +
 +===== Modèles =====
 +
 +<code>
 +Consent
 +
 +SecurityPolicy
 +
 +Risk
 +
 +ComplianceAudit
 +
 +SecurityIncident
 +
 +DataClassification
 +
 +RetentionPolicy
 +</code>
 +
 +----
 +
 +====== Consent ======
 +
 +===== Gestion des consentements =====
 +
 +Traçabilité complète des consentements utilisateurs.
 +
 +<code prisma>
 +model Consent {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  customerId            String?
 +
 +  userId                String?
 +
 +  consentType           ConsentType
 +
 +  granted               Boolean
 +
 +  version               String
 +
 +  source                String?
 +
 +  ipAddress             String?
 +
 +  userAgent             String?
 +
 +  grantedAt             DateTime
 +
 +  revokedAt             DateTime?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  customer              Customer? @relation(
 +                            fields:[customerId],
 +                            references:[id]
 +                         )
 +
 +  user                  User? @relation(
 +                            fields:[userId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([customerId])
 +
 +  @@index([userId])
 +
 +  @@index([consentType])
 +}
 +</code>
 +
 +----
 +
 +===== ConsentType =====
 +
 +<code prisma>
 +enum ConsentType {
 +
 +  GDPR
 +
 +  COOKIES
 +
 +  MARKETING_EMAIL
 +
 +  MARKETING_SMS
 +
 +  PROFILING
 +
 +  THIRD_PARTY_SHARING
 +}
 +</code>
 +
 +----
 +
 +====== SecurityPolicy ======
 +
 +===== Politiques de sécurité =====
 +
 +Configuration centralisée.
 +
 +<code prisma>
 +model SecurityPolicy {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String?
 +
 +  code                  String @unique
 +
 +  name                  String
 +
 +  description           String?
 +
 +  configuration         Json
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant? @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([active])
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +PASSWORD_POLICY
 +
 +SESSION_POLICY
 +
 +MFA_POLICY
 +
 +RETENTION_POLICY
 +
 +ACCESS_CONTROL_POLICY
 +</code>
 +
 +----
 +
 +====== Risk ======
 +
 +===== Registre des risques =====
 +
 +<code prisma>
 +model Risk {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  code                  String
 +
 +  title                 String
 +
 +  description           String?
 +
 +  category              RiskCategory
 +
 +  probability           Int
 +
 +  impact                Int
 +
 +  score                 Int
 +
 +  mitigationPlan        String?
 +
 +  ownerUserId           String?
 +
 +  status                RiskStatus
 +
 +  identifiedAt          DateTime
 +
 +  reviewedAt            DateTime?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  ownerUser             User? @relation(
 +                            fields:[ownerUserId],
 +                            references:[id]
 +                         )
 +
 +  @@unique([tenantId, code])
 +
 +  @@index([tenantId])
 +
 +  @@index([status])
 +
 +  @@index([score])
 +}
 +</code>
 +
 +----
 +
 +===== RiskCategory =====
 +
 +<code prisma>
 +enum RiskCategory {
 +
 +  SECURITY
 +
 +  COMPLIANCE
 +
 +  OPERATIONAL
 +
 +  FINANCIAL
 +
 +  LEGAL
 +
 +  TECHNICAL
 +}
 +</code>
 +
 +----
 +
 +===== RiskStatus =====
 +
 +<code prisma>
 +enum RiskStatus {
 +
 +  IDENTIFIED
 +
 +  ASSESSED
 +
 +  MITIGATED
 +
 +  ACCEPTED
 +
 +  CLOSED
 +}
 +</code>
 +
 +----
 +
 +====== ComplianceAudit ======
 +
 +===== Audits réglementaires =====
 +
 +<code prisma>
 +model ComplianceAudit {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  auditType             ComplianceAuditType
 +
 +  scope                 String?
 +
 +  status                ComplianceAuditStatus
 +
 +  auditor               String?
 +
 +  findings              Json?
 +
 +  recommendations       Json?
 +
 +  startedAt             DateTime
 +
 +  completedAt           DateTime?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([auditType])
 +
 +  @@index([status])
 +}
 +</code>
 +
 +----
 +
 +===== ComplianceAuditType =====
 +
 +<code prisma>
 +enum ComplianceAuditType {
 +
 +  GDPR
 +
 +  ISO27001
 +
 +  SOC2
 +
 +  NIS2
 +
 +  INTERNAL
 +}
 +</code>
 +
 +----
 +
 +===== ComplianceAuditStatus =====
 +
 +<code prisma>
 +enum ComplianceAuditStatus {
 +
 +  PLANNED
 +
 +  RUNNING
 +
 +  COMPLETED
 +
 +  CLOSED
 +}
 +</code>
 +
 +----
 +
 +====== SecurityIncident ======
 +
 +===== Gestion des incidents =====
 +
 +<code prisma>
 +model SecurityIncident {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  code                  String
 +
 +  title                 String
 +
 +  description           String?
 +
 +  severity              IncidentSeverity
 +
 +  status                IncidentStatus
 +
 +  detectedAt            DateTime
 +
 +  resolvedAt            DateTime?
 +
 +  reportedByUserId      String?
 +
 +  rootCause             String?
 +
 +  correctiveActions     String?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  reportedByUser        User? @relation(
 +                            fields:[reportedByUserId],
 +                            references:[id]
 +                         )
 +
 +  @@unique([tenantId, code])
 +
 +  @@index([tenantId])
 +
 +  @@index([severity])
 +
 +  @@index([status])
 +}
 +</code>
 +
 +----
 +
 +===== IncidentSeverity =====
 +
 +<code prisma>
 +enum IncidentSeverity {
 +
 +  LOW
 +
 +  MEDIUM
 +
 +  HIGH
 +
 +  CRITICAL
 +}
 +</code>
 +
 +----
 +
 +===== IncidentStatus =====
 +
 +<code prisma>
 +enum IncidentStatus {
 +
 +  OPEN
 +
 +  INVESTIGATING
 +
 +  MITIGATED
 +
 +  RESOLVED
 +
 +  CLOSED
 +}
 +</code>
 +
 +----
 +
 +====== DataClassification ======
 +
 +===== Classification des données =====
 +
 +<code prisma>
 +model DataClassification {
 +
 +  id                    String @id @default(uuid())
 +
 +  code                  String @unique
 +
 +  name                  String
 +
 +  description           String?
 +
 +  level                 ClassificationLevel
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +}
 +</code>
 +
 +----
 +
 +===== ClassificationLevel =====
 +
 +<code prisma>
 +enum ClassificationLevel {
 +
 +  PUBLIC
 +
 +  INTERNAL
 +
 +  CONFIDENTIAL
 +
 +  RESTRICTED
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +Client
 +
 +→ CONFIDENTIAL
 +
 +----------------
 +
 +Paiement
 +
 +→ RESTRICTED
 +
 +----------------
 +
 +Catalogue public
 +
 +→ PUBLIC
 +</code>
 +
 +----
 +
 +====== RetentionPolicy ======
 +
 +===== Politique de conservation =====
 +
 +<code prisma>
 +model RetentionPolicy {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String?
 +
 +  code                  String @unique
 +
 +  entityType            String
 +
 +  retentionDays         Int
 +
 +  archiveBeforeDelete   Boolean @default(true)
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant? @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([entityType])
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +AuditLog
 +
 +3650 jours
 +
 +----------------
 +
 +LoginHistory
 +
 +365 jours
 +
 +----------------
 +
 +MarketingEvent
 +
 +1095 jours
 +
 +----------------
 +
 +Consent
 +
 +1825 jours
 +</code>
 +
 +----
 +
 +====== Relations à ajouter ======
 +
 +===== Tenant =====
 +
 +<code prisma>
 +consents Consent[]
 +
 +securityPolicies SecurityPolicy[]
 +
 +risks Risk[]
 +
 +complianceAudits ComplianceAudit[]
 +
 +securityIncidents SecurityIncident[]
 +
 +retentionPolicies RetentionPolicy[]
 +</code>
 +
 +----
 +
 +===== User =====
 +
 +<code prisma>
 +consents Consent[]
 +
 +ownedRisks Risk[]
 +
 +reportedIncidents SecurityIncident[]
 +</code>
 +
 +----
 +
 +===== Customer =====
 +
 +<code prisma>
 +consents Consent[]
 +</code>
 +
 +----
 +
 +====== Validation ======
 +
 +<code bash>
 +npx prisma format
 +
 +npx prisma validate
 +
 +npx prisma generate
 +</code>
 +
 +----
 +
 +====== Migration ======
 +
 +<code bash>
 +npx prisma migrate dev \
 +--name enterprise_security_compliance
 +</code>
 +
 +----
 +
 +====== Fonctionnalités couvertes ======
 +
 +===== RGPD =====
 +
 +<code>
 +Consentements
 +
 +Traçabilité
 +
 +Conservation
 +
 +Export
 +
 +Suppression
 +</code>
 +
 +----
 +
 +===== Sécurité =====
 +
 +<code>
 +Politiques
 +
 +Incidents
 +
 +MFA
 +
 +Gestion des risques
 +</code>
 +
 +----
 +
 +===== Gouvernance =====
 +
 +<code>
 +Classification
 +
 +Rétention
 +
 +Audit
 +
 +Conformité
 +</code>
 +
 +----
 +
 +====== État du schéma ======
 +
 +Après Phase 2-L :
 +
 +<code>
 +≈ 93 modèles Prisma
 +</code>
 +
 +avec les domaines :
 +
 +<code>
 +Core
 +
 +Security
 +
 +Properties
 +
 +Owners
 +
 +Customers
 +
 +Reservations
 +
 +Contracts
 +
 +Payments
 +
 +CRM
 +
 +Messaging
 +
 +Marketing
 +
 +Automation
 +
 +Governance
 +
 +OTA
 +
 +Revenue Management
 +
 +Enterprise Security
 +</code>
 +
 +----
 +
 +====== Phase 2-M — Internationalisation & Multi-régions ======
 +
 +===== Objectif =====
 +
 +Transformer la plateforme en solution SaaS internationale capable de gérer :
 +
 +  * Plusieurs langues
 +  * Plusieurs devises
 +  * Plusieurs pays
 +  * Plusieurs fuseaux horaires
 +  * Plusieurs régions d'exploitation
 +  * Plusieurs marques
 +  * Plusieurs réseaux d'agences
 +  * Plusieurs juridictions
 +
 +Cette phase couvre :
 +
 +<code>
 +Sprint 15 — Réseau d'agences
 +
 +Sprint 20 — Internationalisation
 +
 +Enterprise SaaS
 +
 +Commercialisation internationale
 +</code>
 +
 +----
 +
 +====== Architecture ======
 +
 +===== Modèles =====
 +
 +<code>
 +Country
 +
 +Currency
 +
 +Language
 +
 +Timezone
 +
 +CurrencyRate
 +
 +Translation
 +
 +Region
 +
 +EnterpriseLicense
 +</code>
 +
 +----
 +
 +====== Country ======
 +
 +===== Référentiel pays =====
 +
 +Norme ISO 3166.
 +
 +<code prisma>
 +model Country {
 +
 +  code                  String @id
 +
 +  iso3                  String @unique
 +
 +  name                  String
 +
 +  nativeName            String?
 +
 +  phonePrefix           String?
 +
 +  euMember              Boolean @default(false)
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  regions               Region[]
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +FR
 +
 +BE
 +
 +CH
 +
 +ES
 +
 +IT
 +
 +DE
 +
 +UK
 +
 +US
 +
 +CA
 +</code>
 +
 +----
 +
 +====== Currency ======
 +
 +===== Référentiel devises =====
 +
 +Norme ISO 4217.
 +
 +<code prisma>
 +model Currency {
 +
 +  code                  String @id
 +
 +  numericCode           String?
 +
 +  name                  String
 +
 +  symbol                String
 +
 +  decimalPlaces         Int @default(2)
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  rates                 CurrencyRate[]
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +EUR
 +
 +USD
 +
 +GBP
 +
 +CHF
 +
 +CAD
 +</code>
 +
 +----
 +
 +====== Language ======
 +
 +===== Référentiel langues =====
 +
 +Norme ISO 639.
 +
 +<code prisma>
 +model Language {
 +
 +  code                  String @id
 +
 +  name                  String
 +
 +  nativeName            String
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  translations          Translation[]
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +fr
 +
 +en
 +
 +de
 +
 +es
 +
 +it
 +
 +nl
 +</code>
 +
 +----
 +
 +====== Timezone ======
 +
 +===== Fuseaux horaires =====
 +
 +<code prisma>
 +model Timezone {
 +
 +  id                    String @id
 +
 +  displayName           String
 +
 +  utcOffset             String
 +
 +  active                Boolean @default(true)
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +Europe/Paris
 +
 +Europe/London
 +
 +America/New_York
 +
 +America/Montreal
 +
 +Asia/Tokyo
 +</code>
 +
 +----
 +
 +====== CurrencyRate ======
 +
 +===== Taux de change =====
 +
 +Historisation des taux.
 +
 +<code prisma>
 +model CurrencyRate {
 +
 +  id                    String @id @default(uuid())
 +
 +  fromCurrencyCode      String
 +
 +  toCurrencyCode        String
 +
 +  rate                  Decimal @db.Decimal(18,8)
 +
 +  rateDate              DateTime
 +
 +  source                String?
 +
 +  createdAt             DateTime @default(now())
 +
 +  fromCurrency          Currency
 +                          @relation(
 +                            "FromCurrency",
 +                            fields:[fromCurrencyCode],
 +                            references:[code]
 +                          )
 +
 +  toCurrency            Currency
 +                          @relation(
 +                            "ToCurrency",
 +                            fields:[toCurrencyCode],
 +                            references:[code]
 +                          )
 +
 +  @@unique([
 +    fromCurrencyCode,
 +    toCurrencyCode,
 +    rateDate
 +  ])
 +
 +  @@index([rateDate])
 +}
 +</code>
 +
 +----
 +
 +====== Translation ======
 +
 +===== Traductions =====
 +
 +Permet l'internationalisation dynamique.
 +
 +<code prisma>
 +model Translation {
 +
 +  id                    String @id @default(uuid())
 +
 +  languageCode          String
 +
 +  namespace             String
 +
 +  translationKey        String
 +
 +  translationValue      String
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  language              Language @relation(
 +                            fields:[languageCode],
 +                            references:[code]
 +                         )
 +
 +  @@unique([
 +    languageCode,
 +    namespace,
 +    translationKey
 +  ])
 +
 +  @@index([namespace])
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +property.title
 +
 +reservation.confirm
 +
 +payment.invoice
 +</code>
 +
 +----
 +
 +====== Region ======
 +
 +===== Régions d'exploitation =====
 +
 +Permet la gestion géographique.
 +
 +<code prisma>
 +model Region {
 +
 +  id                    String @id @default(uuid())
 +
 +  countryCode           String
 +
 +  code                  String
 +
 +  name                  String
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  country               Country @relation(
 +                            fields:[countryCode],
 +                            references:[code]
 +                         )
 +
 +  @@unique([
 +    countryCode,
 +    code
 +  ])
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +FR_OCCITANIE
 +
 +FR_PACA
 +
 +FR_IDF
 +
 +ES_CATALUNYA
 +
 +US_FLORIDA
 +</code>
 +
 +----
 +
 +====== EnterpriseLicense ======
 +
 +===== Licence SaaS Enterprise =====
 +
 +Gestion des déploiements internationaux.
 +
 +<code prisma>
 +model EnterpriseLicense {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  licenseKey            String @unique
 +
 +  edition               EnterpriseEdition
 +
 +  maxUsers              Int?
 +
 +  maxProperties         Int?
 +
 +  maxAgencies           Int?
 +
 +  validFrom             DateTime
 +
 +  validTo               DateTime?
 +
 +  active                Boolean @default(true)
 +
 +  features              Json?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([active])
 +}
 +</code>
 +
 +----
 +
 +===== EnterpriseEdition =====
 +
 +<code prisma>
 +enum EnterpriseEdition {
 +
 +  COMMUNITY
 +
 +  PROFESSIONAL
 +
 +  BUSINESS
 +
 +  ENTERPRISE
 +
 +  ENTERPRISE_PLUS
 +}
 +</code>
 +
 +----
 +
 +====== Évolutions du modèle Tenant ======
 +
 +===== Tenant =====
 +
 +Ajouter :
 +
 +<code prisma>
 +countryCode String?
 +
 +currencyCode String?
 +
 +languageCode String?
 +
 +timezoneId String?
 +
 +enterpriseLicense EnterpriseLicense?
 +</code>
 +
 +----
 +
 +===== Relations =====
 +
 +<code prisma>
 +country Country?
 +
 +currency Currency?
 +
 +language Language?
 +
 +timezone Timezone?
 +</code>
 +
 +----
 +
 +====== Évolutions du modèle Property ======
 +
 +===== Property =====
 +
 +Ajouter :
 +
 +<code prisma>
 +currencyCode String?
 +</code>
 +
 +----
 +
 +===== Relation =====
 +
 +<code prisma>
 +currency Currency?
 +</code>
 +
 +----
 +
 +====== Évolutions du modèle Reservation ======
 +
 +===== Reservation =====
 +
 +Ajouter :
 +
 +<code prisma>
 +currencyCode String?
 +exchangeRate Decimal?
 +</code>
 +
 +----
 +
 +====== Cas d'usage ======
 +
 +===== Multi-langues =====
 +
 +<code>
 +FR
 +
 +
 +
 +EN
 +
 +
 +
 +DE
 +
 +
 +
 +ES
 +</code>
 +
 +----
 +
 +===== Multi-devises =====
 +
 +<code>
 +EUR
 +
 +
 +
 +USD
 +
 +
 +
 +GBP
 +
 +
 +
 +CHF
 +</code>
 +
 +----
 +
 +===== Multi-régions =====
 +
 +<code>
 +France
 +
 +
 +
 +Occitanie
 +
 +
 +
 +Agence
 +
 +
 +
 +Biens
 +</code>
 +
 +----
 +
 +===== Réseau international =====
 +
 +<code>
 +Tenant
 +
 +
 +
 +Multi-marques
 +
 +
 +
 +Multi-pays
 +
 +
 +
 +Multi-régions
 +</code>
 +
 +----
 +
 +====== Validation ======
 +
 +<code bash>
 +npx prisma format
 +
 +npx prisma validate
 +
 +npx prisma generate
 +</code>
 +
 +----
 +
 +====== Migration ======
 +
 +<code bash>
 +npx prisma migrate dev \
 +--name internationalization_multiregion
 +</code>
 +
 +----
 +
 +====== Fonctionnalités couvertes ======
 +
 +===== Internationalisation =====
 +
 +<code>
 +Multi-langues
 +
 +Multi-devises
 +
 +Multi-fuseaux
 +</code>
 +
 +----
 +
 +===== Réseau =====
 +
 +<code>
 +Multi-pays
 +
 +Multi-régions
 +
 +Multi-agences
 +</code>
 +
 +----
 +
 +===== Enterprise =====
 +
 +<code>
 +Licensing
 +
 +Commercialisation
 +
 +SaaS mondial
 +</code>
 +
 +----
 +
 +====== État du schéma ======
 +
 +Après Phase 2-M :
 +
 +<code>
 +≈ 101 modèles Prisma
 +</code>
 +
 +avec les domaines :
 +
 +<code>
 +Core
 +
 +Security
 +
 +Properties
 +
 +Owners
 +
 +Customers
 +
 +Reservations
 +
 +Contracts
 +
 +Payments
 +
 +CRM
 +
 +Messaging
 +
 +Marketing
 +
 +Automation
 +
 +Governance
 +
 +OTA
 +
 +Revenue Management
 +
 +Enterprise Security
 +
 +Internationalization
 +</code>
 +
 +----
 +
 +====== Phase 2-M — Internationalisation & Multi-régions ======
 +
 +===== Objectif =====
 +
 +Transformer la plateforme en solution SaaS internationale capable de gérer :
 +
 +  * Plusieurs langues
 +  * Plusieurs devises
 +  * Plusieurs pays
 +  * Plusieurs fuseaux horaires
 +  * Plusieurs régions d'exploitation
 +  * Plusieurs marques
 +  * Plusieurs réseaux d'agences
 +  * Plusieurs juridictions
 +
 +Cette phase couvre :
 +
 +<code>
 +Sprint 15 — Réseau d'agences
 +
 +Sprint 20 — Internationalisation
 +
 +Enterprise SaaS
 +
 +Commercialisation internationale
 +</code>
 +
 +----
 +
 +====== Architecture ======
 +
 +===== Modèles =====
 +
 +<code>
 +Country
 +
 +Currency
 +
 +Language
 +
 +Timezone
 +
 +CurrencyRate
 +
 +Translation
 +
 +Region
 +
 +EnterpriseLicense
 +</code>
 +
 +----
 +
 +====== Country ======
 +
 +===== Référentiel pays =====
 +
 +Norme ISO 3166.
 +
 +<code prisma>
 +model Country {
 +
 +  code                  String @id
 +
 +  iso3                  String @unique
 +
 +  name                  String
 +
 +  nativeName            String?
 +
 +  phonePrefix           String?
 +
 +  euMember              Boolean @default(false)
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  regions               Region[]
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +FR
 +
 +BE
 +
 +CH
 +
 +ES
 +
 +IT
 +
 +DE
 +
 +UK
 +
 +US
 +
 +CA
 +</code>
 +
 +----
 +
 +====== Currency ======
 +
 +===== Référentiel devises =====
 +
 +Norme ISO 4217.
 +
 +<code prisma>
 +model Currency {
 +
 +  code                  String @id
 +
 +  numericCode           String?
 +
 +  name                  String
 +
 +  symbol                String
 +
 +  decimalPlaces         Int @default(2)
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  rates                 CurrencyRate[]
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +EUR
 +
 +USD
 +
 +GBP
 +
 +CHF
 +
 +CAD
 +</code>
 +
 +----
 +
 +====== Language ======
 +
 +===== Référentiel langues =====
 +
 +Norme ISO 639.
 +
 +<code prisma>
 +model Language {
 +
 +  code                  String @id
 +
 +  name                  String
 +
 +  nativeName            String
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  translations          Translation[]
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +fr
 +
 +en
 +
 +de
 +
 +es
 +
 +it
 +
 +nl
 +</code>
 +
 +----
 +
 +====== Timezone ======
 +
 +===== Fuseaux horaires =====
 +
 +<code prisma>
 +model Timezone {
 +
 +  id                    String @id
 +
 +  displayName           String
 +
 +  utcOffset             String
 +
 +  active                Boolean @default(true)
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +Europe/Paris
 +
 +Europe/London
 +
 +America/New_York
 +
 +America/Montreal
 +
 +Asia/Tokyo
 +</code>
 +
 +----
 +
 +====== CurrencyRate ======
 +
 +===== Taux de change =====
 +
 +Historisation des taux.
 +
 +<code prisma>
 +model CurrencyRate {
 +
 +  id                    String @id @default(uuid())
 +
 +  fromCurrencyCode      String
 +
 +  toCurrencyCode        String
 +
 +  rate                  Decimal @db.Decimal(18,8)
 +
 +  rateDate              DateTime
 +
 +  source                String?
 +
 +  createdAt             DateTime @default(now())
 +
 +  fromCurrency          Currency
 +                          @relation(
 +                            "FromCurrency",
 +                            fields:[fromCurrencyCode],
 +                            references:[code]
 +                          )
 +
 +  toCurrency            Currency
 +                          @relation(
 +                            "ToCurrency",
 +                            fields:[toCurrencyCode],
 +                            references:[code]
 +                          )
 +
 +  @@unique([
 +    fromCurrencyCode,
 +    toCurrencyCode,
 +    rateDate
 +  ])
 +
 +  @@index([rateDate])
 +}
 +</code>
 +
 +----
 +
 +====== Translation ======
 +
 +===== Traductions =====
 +
 +Permet l'internationalisation dynamique.
 +
 +<code prisma>
 +model Translation {
 +
 +  id                    String @id @default(uuid())
 +
 +  languageCode          String
 +
 +  namespace             String
 +
 +  translationKey        String
 +
 +  translationValue      String
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  language              Language @relation(
 +                            fields:[languageCode],
 +                            references:[code]
 +                         )
 +
 +  @@unique([
 +    languageCode,
 +    namespace,
 +    translationKey
 +  ])
 +
 +  @@index([namespace])
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +property.title
 +
 +reservation.confirm
 +
 +payment.invoice
 +</code>
 +
 +----
 +
 +====== Region ======
 +
 +===== Régions d'exploitation =====
 +
 +Permet la gestion géographique.
 +
 +<code prisma>
 +model Region {
 +
 +  id                    String @id @default(uuid())
 +
 +  countryCode           String
 +
 +  code                  String
 +
 +  name                  String
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  country               Country @relation(
 +                            fields:[countryCode],
 +                            references:[code]
 +                         )
 +
 +  @@unique([
 +    countryCode,
 +    code
 +  ])
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +FR_OCCITANIE
 +
 +FR_PACA
 +
 +FR_IDF
 +
 +ES_CATALUNYA
 +
 +US_FLORIDA
 +</code>
 +
 +----
 +
 +====== EnterpriseLicense ======
 +
 +===== Licence SaaS Enterprise =====
 +
 +Gestion des déploiements internationaux.
 +
 +<code prisma>
 +model EnterpriseLicense {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  licenseKey            String @unique
 +
 +  edition               EnterpriseEdition
 +
 +  maxUsers              Int?
 +
 +  maxProperties         Int?
 +
 +  maxAgencies           Int?
 +
 +  validFrom             DateTime
 +
 +  validTo               DateTime?
 +
 +  active                Boolean @default(true)
 +
 +  features              Json?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([active])
 +}
 +</code>
 +
 +----
 +
 +===== EnterpriseEdition =====
 +
 +<code prisma>
 +enum EnterpriseEdition {
 +
 +  COMMUNITY
 +
 +  PROFESSIONAL
 +
 +  BUSINESS
 +
 +  ENTERPRISE
 +
 +  ENTERPRISE_PLUS
 +}
 +</code>
 +
 +----
 +
 +====== Évolutions du modèle Tenant ======
 +
 +===== Tenant =====
 +
 +Ajouter :
 +
 +<code prisma>
 +countryCode String?
 +
 +currencyCode String?
 +
 +languageCode String?
 +
 +timezoneId String?
 +
 +enterpriseLicense EnterpriseLicense?
 +</code>
 +
 +----
 +
 +===== Relations =====
 +
 +<code prisma>
 +country Country?
 +
 +currency Currency?
 +
 +language Language?
 +
 +timezone Timezone?
 +</code>
 +
 +----
 +
 +====== Évolutions du modèle Property ======
 +
 +===== Property =====
 +
 +Ajouter :
 +
 +<code prisma>
 +currencyCode String?
 +</code>
 +
 +----
 +
 +===== Relation =====
 +
 +<code prisma>
 +currency Currency?
 +</code>
 +
 +----
 +
 +====== Évolutions du modèle Reservation ======
 +
 +===== Reservation =====
 +
 +Ajouter :
 +
 +<code prisma>
 +currencyCode String?
 +exchangeRate Decimal?
 +</code>
 +
 +----
 +
 +====== Cas d'usage ======
 +
 +===== Multi-langues =====
 +
 +<code>
 +FR
 +
 +
 +
 +EN
 +
 +
 +
 +DE
 +
 +
 +
 +ES
 +</code>
 +
 +----
 +
 +===== Multi-devises =====
 +
 +<code>
 +EUR
 +
 +
 +
 +USD
 +
 +
 +
 +GBP
 +
 +
 +
 +CHF
 +</code>
 +
 +----
 +
 +===== Multi-régions =====
 +
 +<code>
 +France
 +
 +
 +
 +Occitanie
 +
 +
 +
 +Agence
 +
 +
 +
 +Biens
 +</code>
 +
 +----
 +
 +===== Réseau international =====
 +
 +<code>
 +Tenant
 +
 +
 +
 +Multi-marques
 +
 +
 +
 +Multi-pays
 +
 +
 +
 +Multi-régions
 +</code>
 +
 +----
 +
 +====== Validation ======
 +
 +<code bash>
 +npx prisma format
 +
 +npx prisma validate
 +
 +npx prisma generate
 +</code>
 +
 +----
 +
 +====== Migration ======
 +
 +<code bash>
 +npx prisma migrate dev \
 +--name internationalization_multiregion
 +</code>
 +
 +----
 +
 +====== Fonctionnalités couvertes ======
 +
 +===== Internationalisation =====
 +
 +<code>
 +Multi-langues
 +
 +Multi-devises
 +
 +Multi-fuseaux
 +</code>
 +
 +----
 +
 +===== Réseau =====
 +
 +<code>
 +Multi-pays
 +
 +Multi-régions
 +
 +Multi-agences
 +</code>
 +
 +----
 +
 +===== Enterprise =====
 +
 +<code>
 +Licensing
 +
 +Commercialisation
 +
 +SaaS mondial
 +</code>
 +
 +----
 +
 +====== État du schéma ======
 +
 +Après Phase 2-M :
 +
 +<code>
 +≈ 101 modèles Prisma
 +</code>
 +
 +avec les domaines :
 +
 +<code>
 +Core
 +
 +Security
 +
 +Properties
 +
 +Owners
 +
 +Customers
 +
 +Reservations
 +
 +Contracts
 +
 +Payments
 +
 +CRM
 +
 +Messaging
 +
 +Marketing
 +
 +Automation
 +
 +Governance
 +
 +OTA
 +
 +Revenue Management
 +
 +Enterprise Security
 +
 +Internationalization
 +</code>
 +
 +----
 +
 +====== Phase 2-N — IA, Knowledge Base & Automatisation Avancée ======
 +
 +===== Objectif =====
 +
 +Construire la couche d'intelligence artificielle de la plateforme.
 +
 +Cette couche permettra :
 +
 +  * Assistant IA interne
 +  * Recherche sémantique
 +  * Base de connaissances
 +  * Recommandations intelligentes
 +  * Analyse documentaire
 +  * Automatisation avancée
 +  * Aide à la décision
 +  * Support opérationnel
 +
 +Cette phase finalise :
 +
 +<code>
 +Sprint 13 — IA & Automatisation
 +
 +Sprint 20 — Enterprise Analytics
 +</code>
 +
 +----
 +
 +====== Architecture ======
 +
 +===== Modèles =====
 +
 +<code>
 +AiConversation
 +
 +AiMessage
 +
 +KnowledgeDocument
 +
 +KnowledgeChunk
 +
 +AutomationScenario
 +
 +AutomationExecution
 +
 +Recommendation
 +</code>
 +
 +----
 +
 +====== AiConversation ======
 +
 +===== Conversations IA =====
 +
 +Historisation des échanges avec l'assistant.
 +
 +<code prisma>
 +model AiConversation {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  userId                String
 +
 +  title                 String?
 +
 +  modelName             String
 +
 +  contextType           String?
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  user                  User @relation(
 +                            fields:[userId],
 +                            references:[id]
 +                         )
 +
 +  messages              AiMessage[]
 +
 +  @@index([tenantId])
 +
 +  @@index([userId])
 +
 +  @@index([createdAt])
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +Analyse réservations
 +
 +Prévision revenus
 +
 +Recherche client
 +
 +Analyse contrat
 +
 +Support utilisateur
 +</code>
 +
 +----
 +
 +====== AiMessage ======
 +
 +===== Messages IA =====
 +
 +<code prisma>
 +model AiMessage {
 +
 +  id                    String @id @default(uuid())
 +
 +  conversationId        String
 +
 +  role                  AiRole
 +
 +  content               String
 +
 +  tokenCount            Int?
 +
 +  createdAt             DateTime @default(now())
 +
 +  conversation          AiConversation
 +                          @relation(
 +                            fields:[conversationId],
 +                            references:[id]
 +                          )
 +
 +  @@index([conversationId])
 +
 +  @@index([createdAt])
 +}
 +</code>
 +
 +----
 +
 +===== AiRole =====
 +
 +<code prisma>
 +enum AiRole {
 +
 +  SYSTEM
 +
 +  USER
 +
 +  ASSISTANT
 +
 +  TOOL
 +}
 +</code>
 +
 +----
 +
 +====== KnowledgeDocument ======
 +
 +===== Base documentaire =====
 +
 +Documents utilisés par l'IA.
 +
 +<code prisma>
 +model KnowledgeDocument {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  documentId            String?
 +
 +  title                 String
 +
 +  sourceType            KnowledgeSourceType
 +
 +  sourceReference       String?
 +
 +  content               String?
 +
 +  metadata              Json?
 +
 +  indexed               Boolean @default(false)
 +
 +  indexedAt             DateTime?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  document              Document? @relation(
 +                            fields:[documentId],
 +                            references:[id]
 +                         )
 +
 +  chunks                KnowledgeChunk[]
 +
 +  @@index([tenantId])
 +
 +  @@index([indexed])
 +}
 +</code>
 +
 +----
 +
 +===== KnowledgeSourceType =====
 +
 +<code prisma>
 +enum KnowledgeSourceType {
 +
 +  DOCUMENT
 +
 +  CONTRACT
 +
 +  FAQ
 +
 +  WEBSITE
 +
 +  POLICY
 +
 +  PROCEDURE
 +}
 +</code>
 +
 +----
 +
 +====== KnowledgeChunk ======
 +
 +===== Découpage vectoriel =====
 +
 +Préparation RAG.
 +
 +<code prisma>
 +model KnowledgeChunk {
 +
 +  id                    String @id @default(uuid())
 +
 +  knowledgeDocumentId   String
 +
 +  chunkIndex            Int
 +
 +  content               String
 +
 +  embeddingId           String?
 +
 +  metadata              Json?
 +
 +  createdAt             DateTime @default(now())
 +
 +  knowledgeDocument     KnowledgeDocument
 +                          @relation(
 +                            fields:[knowledgeDocumentId],
 +                            references:[id]
 +                          )
 +
 +  @@unique([
 +    knowledgeDocumentId,
 +    chunkIndex
 +  ])
 +
 +  @@index([knowledgeDocumentId])
 +}
 +</code>
 +
 +----
 +
 +====== AutomationScenario ======
 +
 +===== Automatisations avancées =====
 +
 +Version métier évoluée de :
 +
 +<code>
 +AutomationRule
 +</code>
 +
 +<code prisma>
 +model AutomationScenario {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  code                  String
 +
 +  name                  String
 +
 +  description           String?
 +
 +  triggerType           String
 +
 +  configuration         Json
 +
 +  active                Boolean @default(true)
 +
 +  createdAt             DateTime @default(now())
 +
 +  updatedAt             DateTime @updatedAt
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  executions            AutomationExecution[]
 +
 +  @@unique([tenantId, code])
 +
 +  @@index([tenantId])
 +
 +  @@index([active])
 +}
 +</code>
 +
 +----
 +
 +===== Exemples =====
 +
 +<code>
 +ReservationConfirmed
 +
 +
 +
 +SendContract
 +
 +
 +
 +CreateTask
 +
 +
 +
 +NotifyOwner
 +
 +----------------
 +
 +PaymentReceived
 +
 +
 +
 +GenerateInvoice
 +
 +
 +
 +NotifyCustomer
 +</code>
 +
 +----
 +
 +====== AutomationExecution ======
 +
 +===== Historique d'exécution =====
 +
 +Extension du modèle existant.
 +
 +<code prisma>
 +model AutomationExecution {
 +
 +  id                    String @id @default(uuid())
 +
 +  automationScenarioId  String?
 +
 +  automationRuleId      String?
 +
 +  status                ExecutionStatus
 +
 +  entityType            String?
 +
 +  entityId              String?
 +
 +  executionContext      Json?
 +
 +  startedAt             DateTime
 +
 +  completedAt           DateTime?
 +
 +  errorMessage          String?
 +
 +  createdAt             DateTime @default(now())
 +
 +  automationScenario    AutomationScenario?
 +                          @relation(
 +                            fields:[automationScenarioId],
 +                            references:[id]
 +                          )
 +
 +  automationRule        AutomationRule?
 +                          @relation(
 +                            fields:[automationRuleId],
 +                            references:[id]
 +                          )
 +
 +  @@index([automationScenarioId])
 +
 +  @@index([automationRuleId])
 +
 +  @@index([status])
 +}
 +</code>
 +
 +----
 +
 +====== Recommendation ======
 +
 +===== Recommandations IA =====
 +
 +Aide à la décision.
 +
 +<code prisma>
 +model Recommendation {
 +
 +  id                    String @id @default(uuid())
 +
 +  tenantId              String
 +
 +  entityType            String
 +
 +  entityId              String
 +
 +  recommendationType    RecommendationType
 +
 +  title                 String
 +
 +  description           String
 +
 +  confidenceScore       Decimal @db.Decimal(5,2)
 +
 +  accepted              Boolean?
 +
 +  acceptedAt            DateTime?
 +
 +  createdAt             DateTime @default(now())
 +
 +  tenant                Tenant @relation(
 +                            fields:[tenantId],
 +                            references:[id]
 +                         )
 +
 +  @@index([tenantId])
 +
 +  @@index([entityType])
 +
 +  @@index([recommendationType])
 +
 +  @@index([confidenceScore])
 +}
 +</code>
 +
 +----
 +
 +===== RecommendationType =====
 +
 +<code prisma>
 +enum RecommendationType {
 +
 +  PRICE_OPTIMIZATION
 +
 +  CUSTOMER_RETENTION
 +
 +  LEAD_CONVERSION
 +
 +  REVENUE_FORECAST
 +
 +  PROPERTY_IMPROVEMENT
 +
 +  RISK_ALERT
 +
 +  AUTOMATION
 +}
 +</code>
 +
 +----
 +
 +====== Relations à ajouter ======
 +
 +===== Tenant =====
 +
 +<code prisma>
 +aiConversations AiConversation[]
 +
 +knowledgeDocuments KnowledgeDocument[]
 +
 +automationScenarios AutomationScenario[]
 +
 +recommendations Recommendation[]
 +</code>
 +
 +----
 +
 +===== User =====
 +
 +<code prisma>
 +aiConversations AiConversation[]
 +</code>
 +
 +----
 +
 +===== Document =====
 +
 +<code prisma>
 +knowledgeDocuments KnowledgeDocument[]
 +</code>
 +
 +----
 +
 +====== Cas d'usage ======
 +
 +===== Assistant Agence =====
 +
 +<code>
 +"Quels biens sont sous-performants ?"
 +
 +
 +
 +Analyse IA
 +
 +
 +
 +Recommandations
 +</code>
 +
 +----
 +
 +===== Assistant Commercial =====
 +
 +<code>
 +"Nouveaux leads prioritaires"
 +
 +
 +
 +Scoring
 +
 +
 +
 +Liste qualifiée
 +</code>
 +
 +----
 +
 +===== Assistant Revenue =====
 +
 +<code>
 +"Optimiser les tarifs"
 +
 +
 +
 +Forecast
 +
 +
 +
 +Recommandations
 +</code>
 +
 +----
 +
 +===== Recherche documentaire =====
 +
 +<code>
 +Question
 +
 +
 +
 +RAG
 +
 +
 +
 +KnowledgeDocument
 +
 +
 +
 +KnowledgeChunk
 +
 +
 +
 +Réponse
 +</code>
 +
 +----
 +
 +====== Validation ======
 +
 +<code bash>
 +npx prisma format
 +
 +npx prisma validate
 +
 +npx prisma generate
 +</code>
 +
 +----
 +
 +====== Migration ======
 +
 +<code bash>
 +npx prisma migrate dev \
 +--name ai_knowledge_automation
 +</code>
 +
 +----
 +
 +====== Fonctionnalités couvertes ======
 +
 +===== IA =====
 +
 +<code>
 +Assistant conversationnel
 +
 +Recherche sémantique
 +
 +Analyse métier
 +
 +Aide à la décision
 +</code>
 +
 +----
 +
 +===== Knowledge Base =====
 +
 +<code>
 +FAQ
 +
 +Procédures
 +
 +Contrats
 +
 +Documentation
 +</code>
 +
 +----
 +
 +===== Automatisation =====
 +
 +<code>
 +Workflows avancés
 +
 +Scénarios
 +
 +Actions automatiques
 +</code>
 +
 +----
 +
 +====== État final du schéma ======
 +
 +Après Phase 2-N :
 +
 +<code>
 +≈ 108 à 112 modèles Prisma
 +</code>
 +
 +répartis sur :
 +
 +<code>
 +Core
 +
 +Security
 +
 +RBAC
 +
 +Properties
 +
 +Owners
 +
 +Customers
 +
 +Reservations
 +
 +Contracts
 +
 +Payments
 +
 +Accounting
 +
 +CRM
 +
 +Messaging
 +
 +Marketing
 +
 +Automation
 +
 +Governance
 +
 +OTA
 +
 +Revenue Management
 +
 +Enterprise Security
 +
 +Internationalization
 +
 +Artificial Intelligence
 +</code>
 +
 +----
 +
 +====== Fin de la Phase 2 ======
 +
 +Le schéma Prisma couvre désormais l'intégralité des sprints :
 +
 +<code>
 +Sprint 1  → Sprint 20
 +</code>
 +
 +et constitue la base pour :
 +
 +<code>
 +Phase 3
 +
 +OpenAPI 3.1 complet
 +
 +
 +
 +DTO NestJS
 +
 +
 +
 +SDK TypeScript
 +
 +
 +
 +Génération Backend NestJS
 +
 +
 +
 +Génération Frontend NextJS
 +
 +
 +
 +Monorepo Enterprise 4.0
 </code> </code>
ujusum/3-codage/1-repository/2-prisma-schema.1780802841.txt.gz · Dernière modification : 2026/06/07 05:27 de 91.170.108.99

DokuWiki Appliance - Powered by TurnKey Linux