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

Prochaine révision
Révision précédente
ujusum:3-codage:1-repository:2-prisma-schema [2026/06/07 04:44] – créée 91.170.108.99ujusum:3-codage:1-repository:2-prisma-schema [2026/06/07 19:04] (Version actuelle) 91.170.108.99
Ligne 1: Ligne 1:
-====== Gestion Git complète du projet ======+====== Phase 2 — Prisma Schema ======
  
 ===== Objectif ===== ===== Objectif =====
  
-Mettre en place un dépôt Git professionnel prêt pour :+Construire le schéma Prisma qui deviendra la source de vérité unique du système.
  
-  * Développement multi-développeurs +À partir de ce schéma seront générés :
-  * CI/CD +
-  * Revue de code +
-  * Releases +
-  * Hotfixes +
-  * Déploiements automatiques+
  
-À la fin de cette procédure :+  * PostgreSQL 
 +  * Prisma Client 
 +  * DTO 
 +  * Entités NestJS 
 +  * OpenAPI 
 +  * SDK TypeScript 
 +  * Migrations SQL 
 + 
 +Le schéma doit refléter l'intégralité des domaines définis dans les 20 sprints. 
 + 
 +---- 
 + 
 +====== Objectifs techniques ====== 
 + 
 +Le schéma Prisma doit supporter :
  
 <code> <code>
-Git local+Multi-tenant
  
-GitHub+Audit
  
-Branches+Historisation
  
-Protection+Soft Delete
  
-CI+RBAC
  
-Versioning+CRM
  
-Templates+Catalogue
  
-Hooks+Réservations
  
-Documentation+Paiements 
 + 
 +Contrats 
 + 
 +OTA 
 + 
 +IA 
 + 
 +Revenue Management 
 + 
 +Internationalisation 
 + 
 +Sécurité Enterprise
 </code> </code>
  
-seront opérationnels.+---- 
 + 
 +====== Ordre de construction recommandé ====== 
 + 
 +Ne jamais commencer par les 80 tables. 
 + 
 +Construire par couches.
  
 ---- ----
  
-====== Étape 1 — Initialisation locale ======+===== Couche 1 — Fondations =====
  
-===== Création du dépôt =====+Construire en premier : 
 + 
 +<code> 
 +Tenant 
 + 
 +User 
 + 
 +Role 
 + 
 +Permission 
 + 
 +UserRole 
 + 
 +RolePermission 
 +</code> 
 + 
 +Ces tables sont nécessaires partout. 
 + 
 +---- 
 + 
 +===== Couche 2 — Référentiels ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +Address 
 + 
 +Country 
 + 
 +Language 
 + 
 +Currency 
 + 
 +Timezone 
 +</code> 
 + 
 +---- 
 + 
 +===== Couche 3 — Catalogue ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +Property 
 + 
 +PropertyType 
 + 
 +PropertyMedia 
 + 
 +PropertyFeature 
 + 
 +PropertyAvailability 
 + 
 +PropertyRate 
 +</code> 
 + 
 +---- 
 + 
 +===== Couche 4 — Réservations ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +Reservation 
 + 
 +ReservationGuest 
 + 
 +ReservationStatus 
 + 
 +ReservationEvent 
 +</code> 
 + 
 +---- 
 + 
 +===== Couche 5 — Contrats ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +Contract 
 + 
 +ContractTemplate 
 + 
 +ContractSignature 
 + 
 +Document 
 +</code> 
 + 
 +---- 
 + 
 +===== Couche 6 — Paiements ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +Payment 
 + 
 +Invoice 
 + 
 +Refund 
 + 
 +AccountingEntry 
 +</code> 
 + 
 +---- 
 + 
 +===== Couche 7 — CRM ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +Lead 
 + 
 +Customer 
 + 
 +Activity 
 + 
 +Task 
 + 
 +Pipeline 
 +</code> 
 + 
 +---- 
 + 
 +===== Couche 8 — Propriétaires ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +Owner 
 + 
 +OwnerProperty 
 + 
 +OwnerDocument 
 +</code> 
 + 
 +---- 
 + 
 +===== Couche 9 — Notifications ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +Notification 
 + 
 +NotificationTemplate 
 + 
 +Message 
 + 
 +Campaign 
 +</code> 
 + 
 +---- 
 + 
 +===== Couche 10 — Administration ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +AuditLog 
 + 
 +FeatureFlag 
 + 
 +CustomField 
 + 
 +Workflow 
 +</code> 
 + 
 +---- 
 + 
 +===== Couche 11 — IA ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +AiConversation 
 + 
 +AiMessage 
 + 
 +KnowledgeDocument 
 + 
 +AutomationRule 
 +</code> 
 + 
 +---- 
 + 
 +===== Couche 12 — OTA ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +Channel 
 + 
 +ChannelConnection 
 + 
 +PropertyDistribution 
 + 
 +ChannelReservation 
 +</code> 
 + 
 +---- 
 + 
 +===== Couche 13 — Revenue Management ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +PricingRule 
 + 
 +DynamicPrice 
 + 
 +RevenueSimulation 
 + 
 +CompetitorSnapshot 
 +</code> 
 + 
 +---- 
 + 
 +===== Couche 14 — Sécurité ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +Consent 
 + 
 +SecurityPolicy 
 + 
 +Risk 
 + 
 +ComplianceAudit 
 +</code> 
 + 
 +---- 
 + 
 +===== Couche 15 — Internationalisation ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +Translation 
 + 
 +CurrencyRate 
 + 
 +Region 
 + 
 +EnterpriseLicense 
 +</code> 
 + 
 +---- 
 + 
 +====== Organisation du dossier Prisma ====== 
 + 
 +Au lieu d'un unique fichier géant : 
 + 
 +<code> 
 +prisma/ 
 + 
 +├── schema.prisma 
 +│ 
 +├── models/ 
 +│ 
 +│   ├── tenant.prisma 
 +│   ├── user.prisma 
 +│   ├── property.prisma 
 +│   ├── reservation.prisma 
 +│   ├── contract.prisma 
 +│   ├── payment.prisma 
 +│   ├── crm.prisma 
 +│   ├── owner.prisma 
 +│   ├── notification.prisma 
 +│   ├── audit.prisma 
 +│   ├── ai.prisma 
 +│   ├── channel.prisma 
 +│   ├── revenue.prisma 
 +│   ├── security.prisma 
 +│   └── localization.prisma 
 +</code> 
 + 
 +---- 
 + 
 +====== Configuration initiale ====== 
 + 
 +===== schema.prisma ===== 
 + 
 +Version minimale : 
 + 
 +<code prisma> 
 +generator client { 
 +  provider = "prisma-client-js" 
 +
 + 
 +datasource db { 
 +  provider = "postgresql" 
 +  url      = env("DATABASE_URL"
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Première implémentation ====== 
 + 
 +===== Étape 1 ===== 
 + 
 +Créer : 
 + 
 +<code> 
 +prisma/models/tenant.prisma 
 +</code> 
 + 
 +---- 
 + 
 +===== Tenant ===== 
 + 
 +<code prisma> 
 +model Tenant { 
 + 
 +  id            String   @id @default(uuid()) 
 + 
 +  code          String   @unique 
 + 
 +  name          String 
 + 
 +  status        TenantStatus 
 + 
 +  createdAt     DateTime @default(now()) 
 + 
 +  updatedAt     DateTime @updatedAt 
 + 
 +  users         User[] 
 + 
 +  properties    Property[] 
 + 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== Enum ===== 
 + 
 +<code prisma> 
 +enum TenantStatus { 
 + 
 +  ACTIVE 
 + 
 +  SUSPENDED 
 + 
 +  TRIAL 
 + 
 +  ARCHIVED 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Étape 2 ====== 
 + 
 +Créer : 
 + 
 +<code> 
 +prisma/models/user.prisma 
 +</code> 
 + 
 +---- 
 + 
 +===== User ===== 
 + 
 +<code prisma> 
 +model User { 
 + 
 +  id              String @id @default(uuid()) 
 + 
 +  tenantId        String 
 + 
 +  email           String @unique 
 + 
 +  passwordHash    String 
 + 
 +  firstName       String 
 + 
 +  lastName        String 
 + 
 +  active          Boolean @default(true) 
 + 
 +  createdAt       DateTime @default(now()) 
 + 
 +  updatedAt       DateTime @updatedAt 
 + 
 +  tenant          Tenant @relation( 
 +                    fields:[tenantId], 
 +                    references:[id] 
 +                  ) 
 + 
 +  roles           UserRole[] 
 + 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== Role ===== 
 + 
 +<code prisma> 
 +model Role { 
 + 
 +  id            String @id @default(uuid()) 
 + 
 +  code          String @unique 
 + 
 +  name          String 
 + 
 +  userRoles     UserRole[] 
 + 
 +  permissions   RolePermission[] 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== Permission ===== 
 + 
 +<code prisma> 
 +model Permission { 
 + 
 +  id            String @id @default(uuid()) 
 + 
 +  code          String @unique 
 + 
 +  name          String 
 + 
 +  rolePermissions RolePermission[] 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== UserRole ===== 
 + 
 +<code prisma> 
 +model UserRole { 
 + 
 +  userId        String 
 + 
 +  roleId        String 
 + 
 +  assignedAt    DateTime @default(now()) 
 + 
 +  user          User @relation( 
 +                  fields:[userId], 
 +                  references:[id] 
 +                ) 
 + 
 +  role          Role @relation( 
 +                  fields:[roleId], 
 +                  references:[id] 
 +                ) 
 + 
 +  @@id([userId, roleId]) 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== RolePermission ===== 
 + 
 +<code prisma> 
 +model RolePermission { 
 + 
 +  roleId        String 
 + 
 +  permissionId  String 
 + 
 +  role          Role @relation( 
 +                  fields:[roleId], 
 +                  references:[id] 
 +                ) 
 + 
 +  permission    Permission @relation( 
 +                  fields:[permissionId], 
 +                  references:[id] 
 +                ) 
 + 
 +  @@id([roleId, permissionId]) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Génération ====== 
 + 
 +Après chaque bloc important :
  
 <code bash> <code bash>
-mkdir rental-platform+npx prisma format 
 +</code>
  
-cd rental-platform+----
  
-git init+===== Validation ===== 
 + 
 +<code bash> 
 +npx prisma validate
 </code> </code>
  
 ---- ----
  
-===== Vérification =====+===== Génération Client =====
  
 <code bash> <code bash>
-git status+npx prisma generate
 </code> </code>
  
-Résultat :+----
  
-<code> +===== Migration =====
-On branch main+
  
-No commits yet+<code bash> 
 +npx prisma migrate dev \ 
 +--name init_security
 </code> </code>
  
 ---- ----
  
-====== Étape 2 — Configuration Git globale ======+====== Vérification ======
  
-===== Vérifier =====+Ouvrir :
  
 <code bash> <code bash>
-git config --global user.name+npx prisma studio 
 +</code> 
 + 
 +Vérifier la présence : 
 + 
 +<code> 
 +Tenant 
 + 
 +User 
 + 
 +Role 
 + 
 +Permission 
 + 
 +UserRole 
 + 
 +RolePermission 
 +</code> 
 + 
 +---- 
 + 
 +====== Phase 2-A — Fondation complète (Tenant + RBAC + Propriétés de sécurité) ====== 
 + 
 +Vous avez raison. 
 + 
 +La version précédente contient : 
 + 
 +  * Tenant 
 +  * User 
 +  * Role 
 +  * Permission 
 +  * UserRole 
 +  * RolePermission 
 + 
 +mais il manque plusieurs éléments indispensables pour un véritable système Enterprise : 
 + 
 +  * propriétés du compte utilisateur 
 +  * préférences utilisateur 
 +  * sessions 
 +  * refresh tokens 
 +  * MFA 
 +  * audit de connexion 
 +  * catalogue complet des permissions 
 + 
 +Sans ces éléments, le Sprint 1 (Authentification) et le Sprint 19 (Sécurité Enterprise) ne pourront pas être implémentés proprement. 
 + 
 +---- 
 + 
 +====== Modèle User complet ====== 
 + 
 +===== User ===== 
 + 
 +<code prisma> 
 +model User { 
 + 
 +  id                String      @id @default(uuid()) 
 + 
 +  tenantId          String 
 + 
 +  email             String      @unique 
 + 
 +  passwordHash      String 
 + 
 +  firstName         String 
 + 
 +  lastName          String 
 + 
 +  phone             String? 
 + 
 +  avatarUrl         String? 
 + 
 +  languageCode      String? 
 + 
 +  timezoneCode      String? 
 + 
 +  active            Boolean     @default(true) 
 + 
 +  emailVerified     Boolean     @default(false) 
 + 
 +  lastLoginAt       DateTime? 
 + 
 +  createdAt         DateTime    @default(now()) 
 + 
 +  updatedAt         DateTime    @updatedAt 
 + 
 +  deletedAt         DateTime? 
 + 
 +  tenant            Tenant      @relation( 
 +                                  fields:[tenantId], 
 +                                  references:[id] 
 +                                ) 
 + 
 +  roles             UserRole[] 
 + 
 +  sessions          UserSession[] 
 + 
 +  refreshTokens     RefreshToken[] 
 + 
 +  preferences       UserPreference? 
 + 
 +  loginHistory      LoginHistory[] 
 + 
 +  mfaMethods        UserMfaMethod[] 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Préférences utilisateur ====== 
 + 
 +===== UserPreference ===== 
 + 
 +<code prisma> 
 +model UserPreference { 
 + 
 +  id                String      @id @default(uuid()) 
 + 
 +  userId            String      @unique 
 + 
 +  theme             String? 
 + 
 +  language          String? 
 + 
 +  timezone          String? 
 + 
 +  notifications     Json? 
 + 
 +  createdAt         DateTime    @default(now()) 
 + 
 +  updatedAt         DateTime    @updatedAt 
 + 
 +  user              User @relation( 
 +                        fields:[userId], 
 +                        references:[id] 
 +                      ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Gestion des sessions ====== 
 + 
 +===== UserSession ===== 
 + 
 +<code prisma> 
 +model UserSession { 
 + 
 +  id                String      @id @default(uuid()) 
 + 
 +  userId            String 
 + 
 +  ipAddress         String? 
 + 
 +  userAgent         String? 
 + 
 +  country           String? 
 + 
 +  city              String? 
 + 
 +  lastActivityAt    DateTime 
 + 
 +  expiresAt         DateTime 
 + 
 +  revokedAt         DateTime? 
 + 
 +  createdAt         DateTime    @default(now()) 
 + 
 +  user              User @relation( 
 +                        fields:[userId], 
 +                        references:[id] 
 +                      ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Refresh Tokens ====== 
 + 
 +===== RefreshToken ===== 
 + 
 +<code prisma> 
 +model RefreshToken { 
 + 
 +  id                String      @id @default(uuid()) 
 + 
 +  userId            String 
 + 
 +  tokenHash         String 
 + 
 +  expiresAt         DateTime 
 + 
 +  revokedAt         DateTime? 
 + 
 +  createdAt         DateTime    @default(now()) 
 + 
 +  user              User @relation( 
 +                        fields:[userId], 
 +                        references:[id] 
 +                      ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Historique des connexions ====== 
 + 
 +===== LoginHistory ===== 
 + 
 +<code prisma> 
 +model LoginHistory { 
 + 
 +  id                String      @id @default(uuid()) 
 + 
 +  userId            String 
 + 
 +  success           Boolean 
 + 
 +  ipAddress         String? 
 + 
 +  userAgent         String? 
 + 
 +  country           String? 
 + 
 +  city              String? 
 + 
 +  createdAt         DateTime @default(now()) 
 + 
 +  user              User @relation( 
 +                        fields:[userId], 
 +                        references:[id] 
 +                      ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== MFA ====== 
 + 
 +===== UserMfaMethod ===== 
 + 
 +<code prisma> 
 +model UserMfaMethod { 
 + 
 +  id                String      @id @default(uuid()) 
 + 
 +  userId            String 
 + 
 +  methodType        String 
 + 
 +  secret            String? 
 + 
 +  enabled           Boolean     @default(true) 
 + 
 +  createdAt         DateTime    @default(now()) 
 + 
 +  user              User @relation( 
 +                        fields:[userId], 
 +                        references:[id] 
 +                      ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== RBAC Enterprise ====== 
 + 
 +===== Role ===== 
 + 
 +<code prisma> 
 +model Role { 
 + 
 +  id                String      @id @default(uuid()) 
 + 
 +  code              String      @unique 
 + 
 +  name              String 
 + 
 +  description       String? 
 + 
 +  systemRole        Boolean     @default(false) 
 + 
 +  createdAt         DateTime    @default(now()) 
 + 
 +  updatedAt         DateTime    @updatedAt 
 + 
 +  userRoles         UserRole[] 
 + 
 +  permissions       RolePermission[] 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== Permission ===== 
 + 
 +<code prisma> 
 +model Permission { 
 + 
 +  id                String      @id @default(uuid()) 
 + 
 +  code              String      @unique 
 + 
 +  name              String 
 + 
 +  description       String? 
 + 
 +  module            String 
 + 
 +  createdAt         DateTime    @default(now()) 
 + 
 +  rolePermissions   RolePermission[] 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Catalogue initial des permissions ====== 
 + 
 +===== Auth ===== 
 + 
 +<code> 
 +AUTH_LOGIN 
 + 
 +AUTH_REGISTER 
 + 
 +AUTH_RESET_PASSWORD 
 + 
 +AUTH_MANAGE_USERS 
 +</code> 
 + 
 +---- 
 + 
 +===== Users ===== 
 + 
 +<code> 
 +USER_READ 
 + 
 +USER_CREATE 
 + 
 +USER_UPDATE 
 + 
 +USER_DELETE 
 +</code> 
 + 
 +---- 
 + 
 +===== Properties ===== 
 + 
 +<code> 
 +PROPERTY_READ 
 + 
 +PROPERTY_CREATE 
 + 
 +PROPERTY_UPDATE 
 + 
 +PROPERTY_DELETE 
 + 
 +PROPERTY_PUBLISH 
 +</code> 
 + 
 +---- 
 + 
 +===== Reservations ===== 
 + 
 +<code> 
 +RESERVATION_READ 
 + 
 +RESERVATION_CREATE 
 + 
 +RESERVATION_UPDATE 
 + 
 +RESERVATION_CANCEL 
 +</code> 
 + 
 +---- 
 + 
 +===== Contracts ===== 
 + 
 +<code> 
 +CONTRACT_READ 
 + 
 +CONTRACT_CREATE 
 + 
 +CONTRACT_SIGN 
 +</code> 
 + 
 +---- 
 + 
 +===== Payments ===== 
 + 
 +<code> 
 +PAYMENT_READ 
 + 
 +PAYMENT_CREATE 
 + 
 +PAYMENT_REFUND 
 +</code> 
 + 
 +---- 
 + 
 +===== CRM ===== 
 + 
 +<code> 
 +CRM_READ 
 + 
 +CRM_WRITE 
 + 
 +CRM_EXPORT 
 +</code> 
 + 
 +---- 
 + 
 +===== Administration ===== 
 + 
 +<code> 
 +ADMIN_READ 
 + 
 +ADMIN_WRITE 
 + 
 +ADMIN_AUDIT 
 + 
 +ADMIN_TENANT 
 +</code> 
 + 
 +---- 
 + 
 +====== Rôles système ====== 
 + 
 +===== SUPER_ADMIN ===== 
 + 
 +Accès complet plateforme. 
 + 
 +---- 
 + 
 +===== TENANT_ADMIN ===== 
 + 
 +Administration d'agence. 
 + 
 +---- 
 + 
 +===== AGENCY_MANAGER ===== 
 + 
 +Gestion opérationnelle. 
 + 
 +---- 
 + 
 +===== OWNER ===== 
 + 
 +Extranet propriétaire. 
 + 
 +---- 
 + 
 +===== AGENT ===== 
 + 
 +Collaborateur. 
 + 
 +---- 
 + 
 +===== CUSTOMER ===== 
 + 
 +Client final. 
 + 
 +---- 
 + 
 +====== Indexes recommandés ====== 
 + 
 +===== User ===== 
 + 
 +<code prisma> 
 +@@index([tenantId]) 
 + 
 +@@index([email]) 
 + 
 +@@index([active]) 
 +</code> 
 + 
 +---- 
 + 
 +===== LoginHistory ===== 
 + 
 +<code prisma> 
 +@@index([userId]) 
 + 
 +@@index([createdAt]) 
 +</code> 
 + 
 +---- 
 + 
 +===== UserSession ===== 
 + 
 +<code prisma> 
 +@@index([userId]) 
 + 
 +@@index([expiresAt]) 
 +</code> 
 + 
 +---- 
 + 
 +====== Architecture du domaine Property ====== 
 + 
 +===== Entités ===== 
 + 
 +<code> 
 +Property 
 + 
 +PropertyType 
 + 
 +PropertyStatus 
 + 
 +PropertyAddress 
 + 
 +PropertyFeature 
 + 
 +PropertyMedia 
 + 
 +PropertyAvailability 
 + 
 +PropertyRate 
 + 
 +PropertyOwner 
 +</code> 
 + 
 +---- 
 + 
 +====== Property ====== 
 + 
 +===== Table principale ===== 
 + 
 +<code prisma> 
 +model Property { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  tenantId              String 
 + 
 +  propertyTypeId        String 
 + 
 +  code                  String @unique 
 + 
 +  reference             String? 
 + 
 +  title                 String 
 + 
 +  slug                  String @unique 
 + 
 +  description           String? 
 + 
 +  shortDescription      String? 
 + 
 +  maxGuests             Int 
 + 
 +  bedrooms              Int 
 + 
 +  bathrooms             Int 
 + 
 +  area                  Decimal? @db.Decimal(10,2) 
 + 
 +  floor                 Int? 
 + 
 +  constructionYear      Int? 
 + 
 +  checkInTime           String? 
 + 
 +  checkOutTime          String? 
 + 
 +  active                Boolean @default(true) 
 + 
 +  published             Boolean @default(false) 
 + 
 +  createdAt             DateTime @default(now()) 
 + 
 +  updatedAt             DateTime @updatedAt 
 + 
 +  deletedAt             DateTime? 
 + 
 +  tenant                Tenant @relation( 
 +                            fields:[tenantId], 
 +                            references:[id] 
 +                         ) 
 + 
 +  propertyType          PropertyType @relation( 
 +                            fields:[propertyTypeId], 
 +                            references:[id] 
 +                         ) 
 + 
 +  address               PropertyAddress? 
 + 
 +  features              PropertyFeature[] 
 + 
 +  media                 PropertyMedia[] 
 + 
 +  availabilities        PropertyAvailability[] 
 + 
 +  rates                 PropertyRate[] 
 + 
 +  owners                PropertyOwner[] 
 + 
 +  reservations         Reservation[] 
 + 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== PropertyType ====== 
 + 
 +===== Référentiel ===== 
 + 
 +<code prisma> 
 +model PropertyType { 
 + 
 +  id                String @id @default(uuid()) 
 + 
 +  code              String @unique 
 + 
 +  name              String 
 + 
 +  properties        Property[] 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== Valeurs ===== 
 + 
 +<code> 
 +HOUSE 
 + 
 +APARTMENT 
 + 
 +VILLA 
 + 
 +STUDIO 
 + 
 +LOFT 
 + 
 +CHALET 
 + 
 +COTTAGE 
 + 
 +MOBILE_HOME 
 +</code> 
 + 
 +---- 
 + 
 +====== PropertyAddress ====== 
 + 
 +===== Adresse du bien ===== 
 + 
 +<code prisma> 
 +model PropertyAddress { 
 + 
 +  id                String @id @default(uuid()) 
 + 
 +  propertyId        String @unique 
 + 
 +  addressLine1      String 
 + 
 +  addressLine2      String? 
 + 
 +  postalCode        String 
 + 
 +  city              String 
 + 
 +  state             String? 
 + 
 +  countryCode       String 
 + 
 +  latitude          Decimal? @db.Decimal(10,7) 
 + 
 +  longitude         Decimal? @db.Decimal(10,7) 
 + 
 +  property          Property @relation( 
 +                      fields:[propertyId], 
 +                      references:[id] 
 +                    ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== PropertyFeature ====== 
 + 
 +===== Équipements ===== 
 + 
 +<code prisma> 
 +model PropertyFeature { 
 + 
 +  id                String @id @default(uuid()) 
 + 
 +  propertyId        String 
 + 
 +  featureCode       String 
 + 
 +  featureValue      String? 
 + 
 +  property          Property @relation( 
 +                      fields:[propertyId], 
 +                      references:[id] 
 +                    ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== Exemples ===== 
 + 
 +<code> 
 +POOL 
 + 
 +WIFI 
 + 
 +PARKING 
 + 
 +AIR_CONDITIONING 
 + 
 +TERRACE 
 + 
 +SEA_VIEW 
 + 
 +PET_ALLOWED 
 +</code> 
 + 
 +---- 
 + 
 +====== PropertyMedia ====== 
 + 
 +===== Médias ===== 
 + 
 +<code prisma> 
 +model PropertyMedia { 
 + 
 +  id                String @id @default(uuid()) 
 + 
 +  propertyId        String 
 + 
 +  fileName          String 
 + 
 +  fileUrl           String 
 + 
 +  mediaType         String 
 + 
 +  position          Int 
 + 
 +  isCover           Boolean @default(false) 
 + 
 +  createdAt         DateTime @default(now()) 
 + 
 +  property          Property @relation( 
 +                      fields:[propertyId], 
 +                      references:[id] 
 +                    ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== MediaType ===== 
 + 
 +<code> 
 +IMAGE 
 + 
 +VIDEO 
 + 
 +VIRTUAL_TOUR 
 + 
 +DOCUMENT 
 +</code> 
 + 
 +---- 
 + 
 +====== PropertyAvailability ====== 
 + 
 +===== Calendrier ===== 
 + 
 +<code prisma> 
 +model PropertyAvailability { 
 + 
 +  id                String @id @default(uuid()) 
 + 
 +  propertyId        String 
 + 
 +  startDate         DateTime 
 + 
 +  endDate           DateTime 
 + 
 +  status            AvailabilityStatus 
 + 
 +  property          Property @relation( 
 +                      fields:[propertyId], 
 +                      references:[id] 
 +                    ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== Enum ===== 
 + 
 +<code prisma> 
 +enum AvailabilityStatus { 
 + 
 +  AVAILABLE 
 + 
 +  RESERVED 
 + 
 +  BLOCKED 
 + 
 +  MAINTENANCE 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== PropertyRate ====== 
 + 
 +===== Tarification ===== 
 + 
 +<code prisma> 
 +model PropertyRate { 
 + 
 +  id                String @id @default(uuid()) 
 + 
 +  propertyId        String 
 + 
 +  startDate         DateTime 
 + 
 +  endDate           DateTime 
 + 
 +  nightlyRate       Decimal @db.Decimal(10,2) 
 + 
 +  weekendRate       Decimal? @db.Decimal(10,2) 
 + 
 +  cleaningFee       Decimal? @db.Decimal(10,2) 
 + 
 +  securityDeposit   Decimal? @db.Decimal(10,2) 
 + 
 +  currencyCode      String 
 + 
 +  property          Property @relation( 
 +                      fields:[propertyId], 
 +                      references:[id] 
 +                    ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== PropertyOwner ====== 
 + 
 +===== Association propriétaire ===== 
 + 
 +<code prisma> 
 +model PropertyOwner { 
 + 
 +  propertyId        String 
 + 
 +  ownerId           String 
 + 
 +  ownershipRate     Decimal @db.Decimal(5,2) 
 + 
 +  property          Property @relation( 
 +                      fields:[propertyId], 
 +                      references:[id] 
 +                    ) 
 + 
 +  owner             Owner @relation( 
 +                      fields:[ownerId], 
 +                      references:[id] 
 +                    ) 
 + 
 +  @@id([propertyId, ownerId]) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Indexes ====== 
 + 
 +===== Property ===== 
 + 
 +<code prisma> 
 +@@index([tenantId]) 
 + 
 +@@index([propertyTypeId]) 
 + 
 +@@index([published]) 
 + 
 +@@index([active]) 
 + 
 +@@index([title]) 
 + 
 +@@index([slug]) 
 +</code> 
 + 
 +---- 
 + 
 +===== PropertyAvailability ===== 
 + 
 +<code prisma> 
 +@@index([propertyId]) 
 + 
 +@@index([startDate]) 
 + 
 +@@index([endDate]) 
 +</code> 
 + 
 +---- 
 + 
 +===== PropertyRate ===== 
 + 
 +<code prisma> 
 +@@index([propertyId]) 
 + 
 +@@index([startDate]) 
 + 
 +@@index([endDate]) 
 +</code> 
 + 
 +---- 
 + 
 +====== Domaine Owner ====== 
 + 
 +===== Architecture ===== 
 + 
 +<code> 
 +Owner 
 + 
 +OwnerAddress 
 + 
 +OwnerDocument 
 + 
 +OwnerBankAccount 
 + 
 +PropertyOwner 
 +</code> 
 + 
 +---- 
 + 
 +====== Owner ====== 
 + 
 +<code prisma> 
 +model Owner { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  tenantId              String 
 + 
 +  code                  String @unique 
 + 
 +  companyName           String? 
 + 
 +  firstName             String? 
 + 
 +  lastName              String? 
 + 
 +  email                 String 
 + 
 +  phone                 String? 
 + 
 +  mobile                String? 
 + 
 +  taxIdentifier         String? 
 + 
 +  vatNumber             String? 
 + 
 +  active                Boolean @default(true) 
 + 
 +  createdAt             DateTime @default(now()) 
 + 
 +  updatedAt             DateTime @updatedAt 
 + 
 +  deletedAt             DateTime? 
 + 
 +  tenant                Tenant @relation( 
 +                            fields:[tenantId], 
 +                            references:[id] 
 +                         ) 
 + 
 +  address               OwnerAddress? 
 + 
 +  documents             OwnerDocument[] 
 + 
 +  bankAccounts          OwnerBankAccount[] 
 + 
 +  properties            PropertyOwner[] 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== OwnerAddress ====== 
 + 
 +<code prisma> 
 +model OwnerAddress { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  ownerId               String @unique 
 + 
 +  addressLine1          String 
 + 
 +  addressLine2          String? 
 + 
 +  postalCode            String 
 + 
 +  city                  String 
 + 
 +  state                 String? 
 + 
 +  countryCode           String 
 + 
 +  owner                 Owner @relation( 
 +                            fields:[ownerId], 
 +                            references:[id] 
 +                         ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== OwnerDocument ====== 
 + 
 +<code prisma> 
 +model OwnerDocument { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  ownerId               String 
 + 
 +  documentType          String 
 + 
 +  fileUrl               String 
 + 
 +  createdAt             DateTime @default(now()) 
 + 
 +  owner                 Owner @relation( 
 +                            fields:[ownerId], 
 +                            references:[id] 
 +                         ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== Document Types ===== 
 + 
 +<code> 
 +IDENTITY 
 + 
 +TAX_DOCUMENT 
 + 
 +MANDATE 
 + 
 +BANK_DETAILS 
 + 
 +INSURANCE 
 +</code> 
 + 
 +---- 
 + 
 +====== OwnerBankAccount ====== 
 + 
 +<code prisma> 
 +model OwnerBankAccount { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  ownerId               String 
 + 
 +  iban                  String 
 + 
 +  bic                   String? 
 + 
 +  accountHolder         String 
 + 
 +  active                Boolean @default(true) 
 + 
 +  owner                 Owner @relation( 
 +                            fields:[ownerId], 
 +                            references:[id] 
 +                         ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Domaine Reservation ====== 
 + 
 +===== Architecture ===== 
 + 
 +<code> 
 +Reservation 
 + 
 +ReservationGuest 
 + 
 +ReservationStatusHistory 
 + 
 +ReservationEvent 
 + 
 +ReservationPricing 
 +</code> 
 + 
 +---- 
 + 
 +====== Reservation ====== 
 + 
 +===== Table centrale ===== 
 + 
 +<code prisma> 
 +model Reservation { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  tenantId              String 
 + 
 +  propertyId            String 
 + 
 +  customerId            String? 
 + 
 +  reference             String @unique 
 + 
 +  status                ReservationStatus 
 + 
 +  checkInDate           DateTime 
 + 
 +  checkOutDate          DateTime 
 + 
 +  nights                Int 
 + 
 +  adults                Int 
 + 
 +  children              Int 
 + 
 +  infants               Int 
 + 
 +  totalGuests           Int 
 + 
 +  notes                 String? 
 + 
 +  source                ReservationSource 
 + 
 +  createdAt             DateTime @default(now()) 
 + 
 +  updatedAt             DateTime @updatedAt 
 + 
 +  cancelledAt           DateTime? 
 + 
 +  tenant                Tenant @relation( 
 +                            fields:[tenantId], 
 +                            references:[id] 
 +                         ) 
 + 
 +  property              Property @relation( 
 +                            fields:[propertyId], 
 +                            references:[id] 
 +                         ) 
 + 
 +  guests                ReservationGuest[] 
 + 
 +  events                ReservationEvent[] 
 + 
 +  statusHistory         ReservationStatusHistory[] 
 + 
 +  pricing               ReservationPricing? 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== ReservationStatus ====== 
 + 
 +<code prisma> 
 +enum ReservationStatus { 
 + 
 +  DRAFT 
 + 
 +  PENDING 
 + 
 +  CONFIRMED 
 + 
 +  SIGNED 
 + 
 +  PAID 
 + 
 +  CHECKED_IN 
 + 
 +  COMPLETED 
 + 
 +  CANCELLED 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== ReservationSource ====== 
 + 
 +<code prisma> 
 +enum ReservationSource { 
 + 
 +  WEBSITE 
 + 
 +  BACKOFFICE 
 + 
 +  AIRBNB 
 + 
 +  BOOKING 
 + 
 +  VRBO 
 + 
 +  API 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== ReservationGuest ====== 
 + 
 +<code prisma> 
 +model ReservationGuest { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  reservationId         String 
 + 
 +  firstName             String 
 + 
 +  lastName              String 
 + 
 +  birthDate             DateTime? 
 + 
 +  email                 String? 
 + 
 +  phone                 String? 
 + 
 +  isPrimary             Boolean @default(false) 
 + 
 +  reservation           Reservation @relation( 
 +                            fields:[reservationId], 
 +                            references:[id] 
 +                         ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== ReservationPricing ====== 
 + 
 +<code prisma> 
 +model ReservationPricing { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  reservationId         String @unique 
 + 
 +  nightlyAmount         Decimal @db.Decimal(10,2) 
 + 
 +  cleaningFee           Decimal @db.Decimal(10,2) 
 + 
 +  touristTax            Decimal @db.Decimal(10,2) 
 + 
 +  discountAmount        Decimal @db.Decimal(10,2) 
 + 
 +  totalAmount           Decimal @db.Decimal(10,2) 
 + 
 +  currencyCode          String 
 + 
 +  reservation           Reservation @relation( 
 +                            fields:[reservationId], 
 +                            references:[id] 
 +                         ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== ReservationEvent ====== 
 + 
 +<code prisma> 
 +model ReservationEvent { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  reservationId         String 
 + 
 +  eventType             String 
 + 
 +  payload               Json? 
 + 
 +  createdAt             DateTime @default(now()) 
 + 
 +  reservation           Reservation @relation( 
 +                            fields:[reservationId], 
 +                            references:[id] 
 +                         ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== Event Types ===== 
 + 
 +<code> 
 +CREATED 
 + 
 +CONFIRMED 
 + 
 +SIGNED 
 + 
 +PAID 
 + 
 +CHECK_IN 
 + 
 +CHECK_OUT 
 + 
 +CANCELLED 
 +</code> 
 + 
 +---- 
 + 
 +====== ReservationStatusHistory ====== 
 + 
 +<code prisma> 
 +model ReservationStatusHistory { 
 + 
 +  id                    String @id @default(uuid()) 
 + 
 +  reservationId         String 
 + 
 +  previousStatus        ReservationStatus? 
 + 
 +  newStatus             ReservationStatus 
 + 
 +  changedAt             DateTime @default(now()) 
 + 
 +  reservation           Reservation @relation( 
 +                            fields:[reservationId], 
 +                            references:[id] 
 +                         ) 
 +
 +</code> 
 + 
 +---- 
 + 
 +====== Relations à ajouter ====== 
 + 
 +===== Property ===== 
 + 
 +Ajouter : 
 + 
 +<code prisma> 
 +reservations Reservation[] 
 +</code> 
 + 
 +---- 
 + 
 +===== Tenant ===== 
 + 
 +Ajouter : 
 + 
 +<code prisma> 
 +owners Owner[] 
 + 
 +reservations Reservation[] 
 +</code> 
 + 
 +---- 
 + 
 +====== Indexes ====== 
 + 
 +===== Owner ===== 
 + 
 +<code prisma> 
 +@@index([tenantId]) 
 + 
 +@@index([email]) 
 + 
 +@@index([active]) 
 +</code> 
 + 
 +---- 
 + 
 +===== Reservation ===== 
 + 
 +<code prisma> 
 +@@index([tenantId]) 
 + 
 +@@index([propertyId]) 
 + 
 +@@index([status]) 
 + 
 +@@index([checkInDate]) 
 + 
 +@@index([checkOutDate]) 
 + 
 +@@index([reference]) 
 +</code> 
 + 
 +---- 
 + 
 +===== ReservationGuest =====
  
-git config --global user.email+<code prisma> 
 +@@index([reservationId])
 </code> </code>
  
 ---- ----
  
-===== Configurer =====+====== Validation ======
  
 <code bash> <code bash>
-git config --global user.name "Votre Nom"+npx prisma format
  
-git config --global user.email "email@domaine.com"+npx prisma validate 
 + 
 +npx prisma generate
 </code> </code>
  
 ---- ----
  
-===== Configuration utile =====+====== Migration ======
  
 <code bash> <code bash>
-git config --global init.defaultBranch main+npx prisma migrate dev \ 
 +--name owners_and_reservations 
 +</code>
  
-git config --global pull.rebase false+----
  
-git config --global core.autocrlf input+====== État actuel du schéma ====== 
 + 
 +À ce stade, le noyau fonctionnel est enfin présent : 
 + 
 +<code> 
 +Tenant 
 + 
 +User 
 + 
 +Role 
 + 
 +Permission 
 + 
 +Owner 
 + 
 +Property 
 + 
 +Reservation 
 +</code> 
 + 
 +avec : 
 + 
 +<code> 
 +Catalogue Immobilier 
 + 
 +Propriétaires 
 + 
 +Réservations 
 + 
 +RBAC 
 + 
 +Multi-tenant
 </code> </code>
  
 ---- ----
  
-====== Étape 3 — Création du dépôt GitHub ======+====== Phase 2-E — Contrats, Documents, Paiements & Facturation ======
  
-Créer :+===== Objectif ===== 
 + 
 +Construire le premier flux métier complet de la plateforme :
  
 <code> <code>
-rental-platform+Client 
 + 
 +↓ 
 + 
 +Réservation 
 + 
 +↓ 
 + 
 +Contrat 
 + 
 +↓ 
 + 
 +Signature 
 + 
 +↓ 
 + 
 +Paiement 
 + 
 +↓ 
 + 
 +Facture 
 + 
 +↓ 
 + 
 +Comptabilité
 </code> </code>
  
-Options :+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> <code>
-Private+Tenant
  
-README+User
  
-.gitignore = Node+Role
  
-License = MIT (ou propriétaire)+Permission 
 + 
 +Owner 
 + 
 +Property 
 + 
 +Reservation
 </code> </code>
  
 ---- ----
  
-===== Ajouter le remote =====+====== 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> 
 +Contract 
 + 
 +ContractTemplate 
 + 
 +ContractVersion 
 + 
 +ContractSignature 
 +</code> 
 + 
 +---- 
 + 
 +====== 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 
 + 
 +PaymentTransaction 
 + 
 +Refund 
 + 
 +PaymentMethod 
 +</code> 
 + 
 +---- 
 + 
 +====== Payment ====== 
 + 
 +<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> <code bash>
-git remote add origin git@github.com:organisation/rental-platform.git+npx prisma format 
 + 
 +npx prisma validate 
 + 
 +npx prisma generate
 </code> </code>
  
 ---- ----
  
-===== Vérifier =====+====== Migration ======
  
 <code bash> <code bash>
-git remote -v+npx prisma migrate dev \ 
 +--name contracts_payments_invoices
 </code> </code>
  
 ---- ----
  
-====== Étape 4 — Génération de la clé SSH ======+====== État du noyau métier ======
  
-===== Vérifier =====+À ce stade, le schéma couvre : 
 + 
 +<code> 
 +Tenant 
 + 
 +User 
 + 
 +RBAC 
 + 
 +Owner 
 + 
 +Property 
 + 
 +Customer 
 + 
 +Reservation 
 + 
 +Contract 
 + 
 +Document 
 + 
 +Payment 
 + 
 +Invoice 
 + 
 +Accounting 
 +</code> 
 + 
 +---- 
 + 
 +====== Flux métier désormais couvert ====== 
 + 
 +<code> 
 +Owner 
 + 
 +↓ 
 + 
 +Property 
 + 
 +↓ 
 + 
 +Customer 
 + 
 +↓ 
 + 
 +Reservation 
 + 
 +↓ 
 + 
 +Contract 
 + 
 +↓ 
 + 
 +Signature 
 + 
 +↓ 
 + 
 +Payment 
 + 
 +↓ 
 + 
 +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> <code bash>
-ls ~/.ssh+npx prisma format 
 + 
 +npx prisma validate 
 + 
 +npx prisma generate
 </code> </code>
  
 ---- ----
  
-===== Générer =====+====== Migration ======
  
 <code bash> <code bash>
-ssh-keygen -t ed25519 +npx prisma migrate dev 
--C "email@domaine.com"+--name crm_and_customer_relationship
 </code> </code>
  
 ---- ----
  
-===== Afficher =====+====== 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> <code bash>
-cat ~/.ssh/id_ed25519.pub+npx prisma format 
 + 
 +npx prisma validate 
 + 
 +npx prisma generate
 </code> </code>
  
 ---- ----
  
-===== Ajouter dans GitHub =====+====== Migration ====== 
 + 
 +<code bash> 
 +npx prisma migrate dev \ 
 +--name notifications_messaging 
 +</code> 
 + 
 +---- 
 + 
 +====== Fonctionnalités couvertes ====== 
 + 
 +===== Sprint 9 =====
  
 <code> <code>
-Settings+Notifications temps réel
  
-SSH Keys+Centre de notifications
  
-New SSH Key+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> </code>
  
 ---- ----
  
-===== Tester =====+====== Validation ======
  
 <code bash> <code bash>
-ssh -T git@github.com+npx prisma format 
 + 
 +npx prisma validate 
 + 
 +npx prisma generate
 </code> </code>
  
 ---- ----
  
-====== Étape 5 — Création du .gitignore ======+====== Migration ======
  
-===== Racine =====+<code bash> 
 +npx prisma migrate dev \ 
 +--name marketing_automation 
 +</code> 
 + 
 +---- 
 + 
 +====== Fonctionnalités couvertes ====== 
 + 
 +===== CRM =====
  
 <code> <code>
-.gitignore+Lead Nurturing 
 + 
 +Relances 
 + 
 +Segmentation 
 + 
 +Scoring 
 + 
 +Qualification
 </code> </code>
  
 ---- ----
  
-===== Contenu =====+===== Communication =====
  
 <code> <code>
-node_modules/+Campagnes Email
  
-dist/+Campagnes SMS
  
-.next/+Suivi Ouvertures
  
-coverage/+Suivi Clics
  
-.env+Désabonnement 
 +</code>
  
-.env.*+----
  
-*.log+===== Automatisation =====
  
-.prisma/client+<code> 
 +Déclencheurs
  
-.idea/+Workflows
  
-.vscode/+Actions Automatiques
  
-.DS_Store+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
  
-tmp/+Marketing
  
-.cache/+Automation
 </code> </code>
  
 ---- ----
  
-====== Étape 6 — README principal ======+====== Phase 2-I — Administration, Audit & Gouvernance ======
  
-===== Créer =====+===== 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> <code>
-README.md+Sprint 10 — Reporting 
 + 
 +Sprint 11 — Administration 
 + 
 +Sprint 19 — Gouvernance & Conformité
 </code> </code>
  
 ---- ----
  
-===== Contenu minimal =====+====== Architecture ======
  
-<code markdown> +===== Modèles =====
-# Rental Platform+
  
-Property Management System+<code> 
 +AuditLog
  
-## Installation+EntityHistory
  
-docker compose up+FeatureFlag
  
-## Documentation+Workflow
  
-/swagger+WorkflowStep
  
-## Architecture+WorkflowInstance
  
-NestJS +WorkflowExecution
-NextJS +
-Prisma +
-PostgreSQL +
-Redis+
 </code> </code>
  
 ---- ----
  
-====== Étape 7 — Premier commit ======+====== 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> <code bash>
-git add .+npx prisma format 
 + 
 +npx prisma validate
  
-git commit -m "chore: initial repository setup"+npx prisma generate
 </code> </code>
  
 ---- ----
  
-===== Push =====+====== Migration ======
  
 <code bash> <code bash>
-git push -u origin main+npx prisma migrate dev \ 
 +--name administration_audit_governance
 </code> </code>
  
 ---- ----
  
-====== Étape 8 — Protection de branche ======+====== Fonctionnalités couvertes ======
  
-===== GitHub =====+===== Administration =====
  
 <code> <code>
-Settings+Feature Flags 
 + 
 +Workflows
  
-Branches+Validation
  
-Add Rule+Approbation
 </code> </code>
  
 ---- ----
  
-===== Branche =====+===== Audit =====
  
 <code> <code>
-main+Journalisation 
 + 
 +Traçabilité 
 + 
 +Historisation 
 + 
 +Conformité
 </code> </code>
  
 ---- ----
  
-===== Activer =====+===== Gouvernance =====
  
 <code> <code>
-Require Pull Request+Contrôle
  
-Require Status Checks+Supervision
  
-Require Review+Rétention
  
-Dismiss Stale Reviews+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
  
-Prevent Force Push+Governance
 </code> </code>
  
 ---- ----
  
-====== Étape 9 — Stratégie Git ======+====== Phase 2-J — OTA & Channel Manager ======
  
-===== Branches permanentes =====+===== 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> <code>
-main+Sprint 12 — OTA & Distribution 
 + 
 +Sprint 14 — API & Partenaires
  
-develop+Sprint 18 — Channel Manager Enterprise
 </code> </code>
  
 ---- ----
  
-===== Création =====+====== 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> <code bash>
-git checkout -b develop+npx prisma format 
 + 
 +npx prisma validate
  
-git push -u origin develop+npx prisma generate
 </code> </code>
  
 ---- ----
  
-===== Branches temporaires =====+====== Migration ====== 
 + 
 +<code bash> 
 +npx prisma migrate dev \ 
 +--name ota_channel_manager 
 +</code> 
 + 
 +---- 
 + 
 +====== Fonctionnalités couvertes ====== 
 + 
 +===== Sprint 12 =====
  
 <code> <code>
-feature/auth-module+Publication OTA
  
-feature/user-module+Synchronisation calendrier
  
-feature/property-module+Synchronisation tarifs
  
-bugfix/login+Import réservations 
 +</code> 
 + 
 +---- 
 + 
 +===== Sprint 14 ===== 
 + 
 +<code> 
 +Partenaires 
 + 
 +API externes
  
-hotfix/security+Marketplace
 </code> </code>
  
 ---- ----
  
-====== Étape 10 — Convention de commits ======+===== Sprint 18 =====
  
-===== Format =====+<code> 
 +Channel Manager Enterprise 
 + 
 +Multi-OTA 
 + 
 +Monitoring synchronisations 
 + 
 +Gestion erreurs 
 +</code> 
 + 
 +---- 
 + 
 +====== État du schéma ====== 
 + 
 +Après Phase 2-J :
  
 <code> <code>
-type(scope)description+≈ 80 modèles Prisma 
 +</code> 
 + 
 +avec les domaines : 
 + 
 +<code> 
 +Core 
 + 
 +Security 
 + 
 +Properties 
 + 
 +Owners 
 + 
 +Customers 
 + 
 +Reservations 
 + 
 +Contracts 
 + 
 +Payments 
 + 
 +CRM 
 + 
 +Messaging 
 + 
 +Marketing 
 + 
 +Automation 
 + 
 +Governance 
 + 
 +OTA
 </code> </code>
  
 ---- ----
  
-===== Types =====+====== 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> <code>
-feat+Sprint 10 — Reporting
  
-fix+Sprint 13 — IA & Prévisions
  
-refactor+Sprint 17 — Revenue Management
  
-perf+Sprint 20 — Enterprise Analytics 
 +</code> 
 + 
 +---- 
 + 
 +====== Architecture ====== 
 + 
 +===== Modèles ===== 
 + 
 +<code> 
 +PricingRule
  
-docs+DynamicPrice
  
-test+RevenueForecast
  
-chore+RevenueSimulation
  
-build+CompetitorSnapshot
  
-ci+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> </code>
  
Ligne 396: Ligne 6368:
  
 <code> <code>
-feat(auth): add login endpoint+Occupation > 80% 
 + 
 +↓ 
 + 
 ++15% 
 + 
 +---------------- 
 + 
 +Weekend 
 + 
 +↓ 
 + 
 ++10% 
 + 
 +----------------
  
-feat(users): add profile page+Haute saison
  
-fix(jwt): refresh token validation+
  
-docs(api): update swagger++25%
 </code> </code>
  
 ---- ----
  
-====== Étape 11 — Commitlint ======+====== DynamicPrice ======
  
-===== Installation =====+===== Prix calculé =====
  
-<code bash+Prix final appliqué à une date donnée. 
-npm install -D \ + 
-@commitlint/cli \ +<code prisma
-@commitlint/config-conventional+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> </code>
  
 ---- ----
  
-===== commitlint.config.js =====+====== RevenueForecast ======
  
-<code javascript+===== Prévisions ===== 
-module.exports = + 
-  extends: [ +Prévision de revenus futurs. 
-    '@commitlint/config-conventional' + 
-  ]+<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> </code>
Ligne 431: Ligne 6500:
 ---- ----
  
-====== Étape 12 — Husky ======+====== RevenueSimulation ======
  
-===== Installation =====+===== 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> <code bash>
-npm install -D husky+npx prisma format 
 + 
 +npx prisma validate 
 + 
 +npx prisma generate
 </code> </code>
  
 ---- ----
  
-===== Initialisation =====+====== Migration ======
  
 <code bash> <code bash>
-npx husky init+npx prisma migrate dev \ 
 +--name revenue_management
 </code> </code>
  
 ---- ----
  
-===== Hook pre-commit =====+====== Fonctionnalités couvertes ====== 
 + 
 +===== Revenue Management =====
  
 <code> <code>
-.husky/pre-commit+Yield Management 
 + 
 +Dynamic Pricing 
 + 
 +Optimisation tarifaire
 </code> </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> <code bash>
-npm run lint+npx prisma format 
 + 
 +npx prisma validate
  
-npm run test+npx prisma generate
 </code> </code>
  
 ---- ----
  
-===== Hook commit-msg =====+====== Migration ====== 
 + 
 +<code bash> 
 +npx prisma migrate dev \ 
 +--name enterprise_security_compliance 
 +</code> 
 + 
 +---- 
 + 
 +====== Fonctionnalités couvertes ====== 
 + 
 +===== RGPD =====
  
 <code> <code>
-.husky/commit-msg+Consentements 
 + 
 +Traçabilité 
 + 
 +Conservation 
 + 
 +Export 
 + 
 +Suppression
 </code> </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> <code bash>
-npx commitlint --edit $1+npx prisma format 
 + 
 +npx prisma validate 
 + 
 +npx prisma generate
 </code> </code>
  
 ---- ----
  
-====== Étape 13 — Pull Request Template ======+====== Migration ======
  
-===== Créer =====+<code bash> 
 +npx prisma migrate dev \ 
 +--name internationalization_multiregion 
 +</code> 
 + 
 +---- 
 + 
 +====== Fonctionnalités couvertes ====== 
 + 
 +===== Internationalisation =====
  
 <code> <code>
-.github/pull_request_template.md+Multi-langues 
 + 
 +Multi-devises 
 + 
 +Multi-fuseaux
 </code> </code>
  
 ---- ----
  
-===== Contenu =====+===== Réseau =====
  
-<code markdown+<code> 
-## Description+Multi-pays
  
-## Changes+Multi-régions
  
-## Screenshots+Multi-agences 
 +</code>
  
-## Tests+----
  
-## Checklist+===== Enterprise =====
  
-- [ ] Tests OK+<code> 
 +Licensing
  
-- [ ] Swagger OK+Commercialisation
  
-- [ ] Migration OK+SaaS mondial
 </code> </code>
  
 ---- ----
  
-====== Étape 14 — Issue Templates ======+====== État du schéma ======
  
-===== Créer =====+Après Phase 2-M :
  
 <code> <code>
-.github/ISSUE_TEMPLATE+≈ 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> </code>
  
 ---- ----
  
-===== Bug =====+====== 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> <code>
-bug_report.yml+Sprint 15 — Réseau d'agences 
 + 
 +Sprint 20 — Internationalisation 
 + 
 +Enterprise SaaS 
 + 
 +Commercialisation internationale
 </code> </code>
  
 ---- ----
  
-===== Feature =====+====== Architecture ====== 
 + 
 +===== Modèles =====
  
 <code> <code>
-feature_request.yml+Country 
 + 
 +Currency 
 + 
 +Language 
 + 
 +Timezone 
 + 
 +CurrencyRate 
 + 
 +Translation 
 + 
 +Region 
 + 
 +EnterpriseLicense
 </code> </code>
  
 ---- ----
  
-====== Étape 15 — GitHub Labels ======+====== Country ======
  
-Créer :+===== 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> <code>
-bug+FR
  
-feature+BE
  
-enhancement+CH
  
-documentation+ES
  
-security+IT
  
-performance+DE
  
-infra+UK
  
-backend+US
  
-frontend+CA 
 +</code>
  
-api+----
  
-database+====== 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> </code>
  
 ---- ----
  
-====== Étape 16 — GitHub Projects ======+===== Exemples =====
  
-===== Colonnes =====+<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> <code>
-Backlog+fr
  
-Ready+en
  
-In Progress+de
  
-Review+es
  
-Testing+it
  
-Done+nl
 </code> </code>
  
 ---- ----
  
-====== Étape 17 — GitHub Actions ======+====== Timezone ======
  
-===== Créer =====+===== Fuseaux horaires ===== 
 + 
 +<code prisma> 
 +model Timezone { 
 + 
 +  id                    String @id 
 + 
 +  displayName           String 
 + 
 +  utcOffset             String 
 + 
 +  active                Boolean @default(true) 
 +
 +</code> 
 + 
 +---- 
 + 
 +===== Exemples =====
  
 <code> <code>
-.github/workflows/ci.yml+Europe/Paris 
 + 
 +Europe/London 
 + 
 +America/New_York 
 + 
 +America/Montreal 
 + 
 +Asia/Tokyo
 </code> </code>
  
 ---- ----
  
-===== Pipeline minimal =====+====== CurrencyRate ======
  
-<code yaml> +===== Taux de change =====
-name: CI+
  
-on: +Historisation des taux.
-  pull_request: +
-  push:+
  
-jobs:+<code prisma> 
 +model CurrencyRate {
  
-  build:+  id                    String @id @default(uuid())
  
-    runs-on: ubuntu-latest+  fromCurrencyCode      String
  
-    steps:+  toCurrencyCode        String
  
-      - uses: actions/checkout@v4+  rate                  Decimal @db.Decimal(18,8)
  
-      - uses: actions/setup-node@v4+  rateDate              DateTime
  
-      - run: npm install+  source                String?
  
-      - run: npm run lint+  createdAt             DateTime @default(now())
  
-      - runnpm run test+  fromCurrency          Currency 
 +                          @relation( 
 +                            "FromCurrency", 
 +                            fields:[fromCurrencyCode], 
 +                            references:[code] 
 +                          )
  
-      - runnpm run build+  toCurrency            Currency 
 +                          @relation( 
 +                            "ToCurrency", 
 +                            fields:[toCurrencyCode], 
 +                            references:[code] 
 +                          ) 
 + 
 +  @@unique([ 
 +    fromCurrencyCode, 
 +    toCurrencyCode, 
 +    rateDate 
 +  ]) 
 + 
 +  @@index([rateDate]) 
 +}
 </code> </code>
  
 ---- ----
  
-====== Étape 18 — Gestion des secrets ======+====== Translation ======
  
-===== GitHub =====+===== 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> <code>
-Settings+property.title
  
-Secrets+reservation.confirm
  
-Actions+payment.invoice
 </code> </code>
  
 ---- ----
  
-===== Ajouter =====+====== 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> <code>
-DATABASE_URL+FR_OCCITANIE
  
-JWT_SECRET+FR_PACA
  
-REDIS_URL+FR_IDF
  
-MINIO_ACCESS_KEY+ES_CATALUNYA
  
-MINIO_SECRET_KEY+US_FLORIDA
 </code> </code>
  
 ---- ----
  
-====== Étape 19 — Gestion des releases ======+====== EnterpriseLicense ======
  
-===== Convention =====+===== 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> <code>
-v1.0.0+FR
  
-v1.1.0+
  
-v1.2.0+EN
  
-v2.0.0+↓ 
 + 
 +DE 
 + 
 +↓ 
 + 
 +ES
 </code> </code>
  
 ---- ----
  
-===== Créer =====+===== 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> <code bash>
-git tag v1.0.0+npx prisma format 
 + 
 +npx prisma validate
  
-git push origin v1.0.0+npx prisma generate
 </code> </code>
  
 ---- ----
  
-====== Étape 20 — CODEOWNERS ======+====== Migration ======
  
-===== Créer =====+<code bash> 
 +npx prisma migrate dev \ 
 +--name internationalization_multiregion 
 +</code> 
 + 
 +---- 
 + 
 +====== Fonctionnalités couvertes ====== 
 + 
 +===== Internationalisation =====
  
 <code> <code>
-.github/CODEOWNERS+Multi-langues 
 + 
 +Multi-devises 
 + 
 +Multi-fuseaux
 </code> </code>
  
 ---- ----
  
-===== Exemple =====+===== Réseau =====
  
 <code> <code>
-* @techlead+Multi-pays
  
-apps/api/* @backend-team+Multi-régions
  
-apps/web/* @frontend-team+Multi-agences 
 +</code> 
 + 
 +---- 
 + 
 +===== Enterprise ===== 
 + 
 +<code> 
 +Licensing 
 + 
 +Commercialisation
  
-prisma/* @backend-team+SaaS mondial
 </code> </code>
  
 ---- ----
  
-====== Étape 21 — Documentation du dépôt ======+====== État du schéma ======
  
-===== Créer =====+Après Phase 2-M :
  
 <code> <code>
-docs/+≈ 101 modèles Prisma 
 +</code>
  
-docs/architecture+avec les domaines :
  
-docs/api+<code> 
 +Core
  
-docs/database+Security
  
-docs/deployment+Properties 
 + 
 +Owners 
 + 
 +Customers 
 + 
 +Reservations 
 + 
 +Contracts 
 + 
 +Payments 
 + 
 +CRM 
 + 
 +Messaging 
 + 
 +Marketing 
 + 
 +Automation 
 + 
 +Governance 
 + 
 +OTA 
 + 
 +Revenue Management 
 + 
 +Enterprise Security 
 + 
 +Internationalization
 </code> </code>
  
 ---- ----
  
-====== Vérification finale ======+====== Phase 2-N — IA, Knowledge Base & Automatisation Avancée ======
  
-Le dépôt est considéré opérationnel lorsque :+===== 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> <code>
-✓ Git initialisé+Sprint 13 — IA & Automatisation
  
-✓ GitHub connecté+Sprint 20 — Enterprise Analytics 
 +</code>
  
-✓ SSH fonctionnel+----
  
-✓ Branch protection active+====== Architecture ======
  
-✓ Workflows CI actifs+===== Modèles =====
  
-✓ Pull Requests obligatoires+<code> 
 +AiConversation
  
-✓ Husky actif+AiMessage
  
-✓ Commitlint actif+KnowledgeDocument
  
-✓ Templates actifs+KnowledgeChunk
  
-✓ Releases configurées+AutomationScenario
  
-✓ CODEOWNERS actif+AutomationExecution
  
-✓ Documentation présente+Recommendation
 </code> </code>
  
 ---- ----
  
-====== Niveau Enterprise recommandé ======+====== AiConversation ======
  
-Pour ce projet SaaS Enterpriseajouter également :+===== 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> <code>
-✓ Dependabot+Analyse réservations
  
-✓ CodeQL+Prévision revenus
  
-✓ Secret Scanning+Recherche client
  
-✓ Container Scanning+Analyse contrat
  
-✓ SBOM+Support utilisateur 
 +</code>
  
-✓ SAST+----
  
-✓ DAST+====== AiMessage ======
  
-✓ Security Policy+===== Messages IA =====
  
-✓ CHANGELOG automatique+<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> </code>
  
-Ces éléments seront nécessaires à partir des Sprints 12 à 20 pour maintenir un niveau de qualité et de sécurité compatible avec une exploitation professionnelle à grande échelle.+---- 
 + 
 +===== 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.
 +</code>
ujusum/3-codage/1-repository/2-prisma-schema.1780800251.txt.gz · Dernière modification : 2026/06/07 04:44 de 91.170.108.99

DokuWiki Appliance - Powered by TurnKey Linux