ujusum:3-codage:1-repository:2-prisma-schema
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| ujusum:3-codage:1-repository:2-prisma-schema [2026/06/07 04:44] – 91.170.108.99 | ujusum:3-codage:1-repository:2-prisma-schema [2026/06/07 19:04] (Version actuelle) – 91.170.108.99 | ||
|---|---|---|---|
| Ligne 615: | Ligne 615: | ||
| ---- | ---- | ||
| - | ====== | + | ====== Phase 2-A — Fondation complète (Tenant + RBAC + Propriétés de sécurité) |
| - | La première sous-phase est terminée lorsque | + | 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 | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | email | ||
| + | |||
| + | passwordHash | ||
| + | |||
| + | firstName | ||
| + | |||
| + | lastName | ||
| + | |||
| + | phone | ||
| + | |||
| + | avatarUrl | ||
| + | |||
| + | languageCode | ||
| + | |||
| + | timezoneCode | ||
| + | |||
| + | active | ||
| + | |||
| + | emailVerified | ||
| + | |||
| + | lastLoginAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | deletedAt | ||
| + | |||
| + | tenant | ||
| + | fields:[tenantId], | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | roles | ||
| + | |||
| + | sessions | ||
| + | |||
| + | refreshTokens | ||
| + | |||
| + | preferences | ||
| + | |||
| + | loginHistory | ||
| + | |||
| + | mfaMethods | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Préférences utilisateur ====== | ||
| + | |||
| + | ===== UserPreference ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model UserPreference { | ||
| + | |||
| + | id String | ||
| + | |||
| + | userId | ||
| + | |||
| + | theme | ||
| + | |||
| + | language | ||
| + | |||
| + | timezone | ||
| + | |||
| + | notifications | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | user User @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Gestion des sessions ====== | ||
| + | |||
| + | ===== UserSession ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model UserSession { | ||
| + | |||
| + | id String | ||
| + | |||
| + | userId | ||
| + | |||
| + | ipAddress | ||
| + | |||
| + | userAgent | ||
| + | |||
| + | country | ||
| + | |||
| + | city String? | ||
| + | |||
| + | lastActivityAt | ||
| + | |||
| + | expiresAt | ||
| + | |||
| + | revokedAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | user User @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Refresh Tokens ====== | ||
| + | |||
| + | ===== RefreshToken ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model RefreshToken { | ||
| + | |||
| + | id String | ||
| + | |||
| + | userId | ||
| + | |||
| + | tokenHash | ||
| + | |||
| + | expiresAt | ||
| + | |||
| + | revokedAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | user User @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Historique des connexions ====== | ||
| + | |||
| + | ===== LoginHistory ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model LoginHistory { | ||
| + | |||
| + | id String | ||
| + | |||
| + | userId | ||
| + | |||
| + | success | ||
| + | |||
| + | ipAddress | ||
| + | |||
| + | userAgent | ||
| + | |||
| + | country | ||
| + | |||
| + | city String? | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | user User @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== MFA ====== | ||
| + | |||
| + | ===== UserMfaMethod ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model UserMfaMethod { | ||
| + | |||
| + | id String | ||
| + | |||
| + | userId | ||
| + | |||
| + | methodType | ||
| + | |||
| + | secret | ||
| + | |||
| + | enabled | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | user User @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== RBAC Enterprise ====== | ||
| + | |||
| + | ===== Role ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Role { | ||
| + | |||
| + | id String | ||
| + | |||
| + | code String | ||
| + | |||
| + | name String | ||
| + | |||
| + | description | ||
| + | |||
| + | systemRole | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | userRoles | ||
| + | |||
| + | permissions | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Permission ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Permission { | ||
| + | |||
| + | id String | ||
| + | |||
| + | code String | ||
| + | |||
| + | name String | ||
| + | |||
| + | description | ||
| + | |||
| + | module | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | rolePermissions | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Catalogue initial des permissions ====== | ||
| + | |||
| + | ===== Auth ===== | ||
| < | < | ||
| - | ✓ Tenant | + | AUTH_LOGIN |
| - | ✓ User | + | AUTH_REGISTER |
| - | ✓ Role | + | AUTH_RESET_PASSWORD |
| - | ✓ Permission | + | AUTH_MANAGE_USERS |
| + | </ | ||
| - | ✓ UserRole | + | ---- |
| - | ✓ RolePermission | + | ===== Users ===== |
| - | ✓ Migration exécutée | + | < |
| + | USER_READ | ||
| + | |||
| + | USER_CREATE | ||
| - | ✓ Prisma Client généré | + | USER_UPDATE |
| - | ✓ Prisma Studio fonctionnel | + | USER_DELETE |
| </ | </ | ||
| ---- | ---- | ||
| - | ====== Étape suivante ====== | + | ===== Properties |
| - | Une fois cette sous-phase validée, nous produirons : | + | < |
| + | PROPERTY_READ | ||
| - | ===== Phase 2-B ===== | + | PROPERTY_CREATE |
| - | Référentiels globaux : | + | PROPERTY_UPDATE |
| + | |||
| + | PROPERTY_DELETE | ||
| + | |||
| + | PROPERTY_PUBLISH | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Reservations ===== | ||
| < | < | ||
| - | Country | + | RESERVATION_READ |
| - | Language | + | RESERVATION_CREATE |
| - | Currency | + | RESERVATION_UPDATE |
| - | Timezone | + | RESERVATION_CANCEL |
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Contracts ===== | ||
| + | |||
| + | < | ||
| + | CONTRACT_READ | ||
| - | Address | + | CONTRACT_CREATE |
| - | Contact | + | CONTRACT_SIGN |
| </ | </ | ||
| - | puis : | + | ---- |
| - | ===== Phase 2-C ===== | + | ===== Payments |
| + | |||
| + | < | ||
| + | PAYMENT_READ | ||
| + | |||
| + | PAYMENT_CREATE | ||
| + | |||
| + | PAYMENT_REFUND | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| - | Catalogue Immobilier : | + | ===== CRM ===== |
| + | |||
| + | < | ||
| + | CRM_READ | ||
| + | |||
| + | CRM_WRITE | ||
| + | |||
| + | CRM_EXPORT | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Administration ===== | ||
| + | |||
| + | < | ||
| + | ADMIN_READ | ||
| + | |||
| + | ADMIN_WRITE | ||
| + | |||
| + | ADMIN_AUDIT | ||
| + | |||
| + | ADMIN_TENANT | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Rôles système ====== | ||
| + | |||
| + | ===== SUPER_ADMIN ===== | ||
| + | |||
| + | Accès complet plateforme. | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== TENANT_ADMIN ===== | ||
| + | |||
| + | Administration d' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 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]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== LoginHistory ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([userId]) | ||
| + | |||
| + | @@index([createdAt]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== UserSession ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([userId]) | ||
| + | |||
| + | @@index([expiresAt]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Architecture du domaine Property ====== | ||
| + | |||
| + | ===== Entités ===== | ||
| < | < | ||
| Property | Property | ||
| - | PropertyMedia | + | PropertyType |
| + | |||
| + | PropertyStatus | ||
| + | |||
| + | PropertyAddress | ||
| PropertyFeature | PropertyFeature | ||
| + | |||
| + | PropertyMedia | ||
| PropertyAvailability | PropertyAvailability | ||
| PropertyRate | PropertyRate | ||
| + | |||
| + | PropertyOwner | ||
| </ | </ | ||
| - | qui constituera | + | ---- |
| + | |||
| + | ====== Property ====== | ||
| + | |||
| + | ===== Table principale ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Property { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | propertyTypeId | ||
| + | |||
| + | code String @unique | ||
| + | |||
| + | reference | ||
| + | |||
| + | title | ||
| + | |||
| + | slug String @unique | ||
| + | |||
| + | description | ||
| + | |||
| + | shortDescription | ||
| + | |||
| + | maxGuests | ||
| + | |||
| + | bedrooms | ||
| + | |||
| + | bathrooms | ||
| + | |||
| + | area Decimal? @db.Decimal(10, | ||
| + | |||
| + | floor | ||
| + | |||
| + | constructionYear | ||
| + | |||
| + | checkInTime | ||
| + | |||
| + | checkOutTime | ||
| + | |||
| + | active | ||
| + | |||
| + | published | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | deletedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | propertyType | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | address | ||
| + | |||
| + | features | ||
| + | |||
| + | media | ||
| + | |||
| + | availabilities | ||
| + | |||
| + | rates | ||
| + | |||
| + | owners | ||
| + | |||
| + | reservations | ||
| + | |||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== PropertyType ====== | ||
| + | |||
| + | ===== Référentiel ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model PropertyType { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | code String @unique | ||
| + | |||
| + | name String | ||
| + | |||
| + | properties | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Valeurs ===== | ||
| + | |||
| + | < | ||
| + | HOUSE | ||
| + | |||
| + | APARTMENT | ||
| + | |||
| + | VILLA | ||
| + | |||
| + | STUDIO | ||
| + | |||
| + | LOFT | ||
| + | |||
| + | CHALET | ||
| + | |||
| + | COTTAGE | ||
| + | |||
| + | MOBILE_HOME | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== PropertyAddress ====== | ||
| + | |||
| + | ===== Adresse du bien ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model PropertyAddress { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | propertyId | ||
| + | |||
| + | addressLine1 | ||
| + | |||
| + | addressLine2 | ||
| + | |||
| + | postalCode | ||
| + | |||
| + | city String | ||
| + | |||
| + | state | ||
| + | |||
| + | countryCode | ||
| + | |||
| + | latitude | ||
| + | |||
| + | longitude | ||
| + | |||
| + | property | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== PropertyFeature ====== | ||
| + | |||
| + | ===== Équipements ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model PropertyFeature { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | propertyId | ||
| + | |||
| + | featureCode | ||
| + | |||
| + | featureValue | ||
| + | |||
| + | property | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | POOL | ||
| + | |||
| + | WIFI | ||
| + | |||
| + | PARKING | ||
| + | |||
| + | AIR_CONDITIONING | ||
| + | |||
| + | TERRACE | ||
| + | |||
| + | SEA_VIEW | ||
| + | |||
| + | PET_ALLOWED | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== PropertyMedia ====== | ||
| + | |||
| + | ===== Médias ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model PropertyMedia { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | propertyId | ||
| + | |||
| + | fileName | ||
| + | |||
| + | fileUrl | ||
| + | |||
| + | mediaType | ||
| + | |||
| + | position | ||
| + | |||
| + | isCover | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | property | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== MediaType ===== | ||
| + | |||
| + | < | ||
| + | IMAGE | ||
| + | |||
| + | VIDEO | ||
| + | |||
| + | VIRTUAL_TOUR | ||
| + | |||
| + | DOCUMENT | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== PropertyAvailability ====== | ||
| + | |||
| + | ===== Calendrier ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model PropertyAvailability { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | propertyId | ||
| + | |||
| + | startDate | ||
| + | |||
| + | endDate | ||
| + | |||
| + | status | ||
| + | |||
| + | property | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Enum ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum AvailabilityStatus { | ||
| + | |||
| + | AVAILABLE | ||
| + | |||
| + | RESERVED | ||
| + | |||
| + | BLOCKED | ||
| + | |||
| + | MAINTENANCE | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== PropertyRate ====== | ||
| + | |||
| + | ===== Tarification ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model PropertyRate { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | propertyId | ||
| + | |||
| + | startDate | ||
| + | |||
| + | endDate | ||
| + | |||
| + | nightlyRate | ||
| + | |||
| + | weekendRate | ||
| + | |||
| + | cleaningFee | ||
| + | |||
| + | securityDeposit | ||
| + | |||
| + | currencyCode | ||
| + | |||
| + | property | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== PropertyOwner ====== | ||
| + | |||
| + | ===== Association propriétaire ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model PropertyOwner { | ||
| + | |||
| + | propertyId | ||
| + | |||
| + | ownerId | ||
| + | |||
| + | ownershipRate | ||
| + | |||
| + | property | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | owner Owner @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@id([propertyId, | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Indexes ====== | ||
| + | |||
| + | ===== Property ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([propertyTypeId]) | ||
| + | |||
| + | @@index([published]) | ||
| + | |||
| + | @@index([active]) | ||
| + | |||
| + | @@index([title]) | ||
| + | |||
| + | @@index([slug]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== PropertyAvailability ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([propertyId]) | ||
| + | |||
| + | @@index([startDate]) | ||
| + | |||
| + | @@index([endDate]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== PropertyRate ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([propertyId]) | ||
| + | |||
| + | @@index([startDate]) | ||
| + | |||
| + | @@index([endDate]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Domaine Owner ====== | ||
| + | |||
| + | ===== Architecture ===== | ||
| + | |||
| + | < | ||
| + | Owner | ||
| + | |||
| + | OwnerAddress | ||
| + | |||
| + | OwnerDocument | ||
| + | |||
| + | OwnerBankAccount | ||
| + | |||
| + | PropertyOwner | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Owner ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model Owner { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String @unique | ||
| + | |||
| + | companyName | ||
| + | |||
| + | firstName | ||
| + | |||
| + | lastName | ||
| + | |||
| + | email | ||
| + | |||
| + | phone | ||
| + | |||
| + | mobile | ||
| + | |||
| + | taxIdentifier | ||
| + | |||
| + | vatNumber | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | deletedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | address | ||
| + | |||
| + | documents | ||
| + | |||
| + | bankAccounts | ||
| + | |||
| + | properties | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== OwnerAddress ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model OwnerAddress { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | ownerId | ||
| + | |||
| + | addressLine1 | ||
| + | |||
| + | addressLine2 | ||
| + | |||
| + | postalCode | ||
| + | |||
| + | city String | ||
| + | |||
| + | state | ||
| + | |||
| + | countryCode | ||
| + | |||
| + | owner Owner @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== OwnerDocument ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model OwnerDocument { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | ownerId | ||
| + | |||
| + | documentType | ||
| + | |||
| + | fileUrl | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | owner Owner @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Document Types ===== | ||
| + | |||
| + | < | ||
| + | IDENTITY | ||
| + | |||
| + | TAX_DOCUMENT | ||
| + | |||
| + | MANDATE | ||
| + | |||
| + | BANK_DETAILS | ||
| + | |||
| + | INSURANCE | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== OwnerBankAccount ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model OwnerBankAccount { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | ownerId | ||
| + | |||
| + | iban String | ||
| + | |||
| + | bic | ||
| + | |||
| + | accountHolder | ||
| + | |||
| + | active | ||
| + | |||
| + | owner Owner @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Domaine Reservation ====== | ||
| + | |||
| + | ===== Architecture ===== | ||
| + | |||
| + | < | ||
| + | Reservation | ||
| + | |||
| + | ReservationGuest | ||
| + | |||
| + | ReservationStatusHistory | ||
| + | |||
| + | ReservationEvent | ||
| + | |||
| + | ReservationPricing | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Reservation ====== | ||
| + | |||
| + | ===== Table centrale ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Reservation { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | propertyId | ||
| + | |||
| + | customerId | ||
| + | |||
| + | reference | ||
| + | |||
| + | status | ||
| + | |||
| + | checkInDate | ||
| + | |||
| + | checkOutDate | ||
| + | |||
| + | nights | ||
| + | |||
| + | adults | ||
| + | |||
| + | children | ||
| + | |||
| + | infants | ||
| + | |||
| + | totalGuests | ||
| + | |||
| + | notes | ||
| + | |||
| + | source | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | cancelledAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | property | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | guests | ||
| + | |||
| + | events | ||
| + | |||
| + | statusHistory | ||
| + | |||
| + | pricing | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== ReservationStatus ====== | ||
| + | |||
| + | <code prisma> | ||
| + | enum ReservationStatus { | ||
| + | |||
| + | DRAFT | ||
| + | |||
| + | PENDING | ||
| + | |||
| + | CONFIRMED | ||
| + | |||
| + | SIGNED | ||
| + | |||
| + | PAID | ||
| + | |||
| + | CHECKED_IN | ||
| + | |||
| + | COMPLETED | ||
| + | |||
| + | CANCELLED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== ReservationSource ====== | ||
| + | |||
| + | <code prisma> | ||
| + | enum ReservationSource { | ||
| + | |||
| + | WEBSITE | ||
| + | |||
| + | BACKOFFICE | ||
| + | |||
| + | AIRBNB | ||
| + | |||
| + | BOOKING | ||
| + | |||
| + | VRBO | ||
| + | |||
| + | API | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== ReservationGuest ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model ReservationGuest { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | reservationId | ||
| + | |||
| + | firstName | ||
| + | |||
| + | lastName | ||
| + | |||
| + | birthDate | ||
| + | |||
| + | email | ||
| + | |||
| + | phone | ||
| + | |||
| + | isPrimary | ||
| + | |||
| + | reservation | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== ReservationPricing ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model ReservationPricing { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | reservationId | ||
| + | |||
| + | nightlyAmount | ||
| + | |||
| + | cleaningFee | ||
| + | |||
| + | touristTax | ||
| + | |||
| + | discountAmount | ||
| + | |||
| + | totalAmount | ||
| + | |||
| + | currencyCode | ||
| + | |||
| + | reservation | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== ReservationEvent ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model ReservationEvent { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | reservationId | ||
| + | |||
| + | eventType | ||
| + | |||
| + | payload | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | reservation | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Event Types ===== | ||
| + | |||
| + | < | ||
| + | CREATED | ||
| + | |||
| + | CONFIRMED | ||
| + | |||
| + | SIGNED | ||
| + | |||
| + | PAID | ||
| + | |||
| + | CHECK_IN | ||
| + | |||
| + | CHECK_OUT | ||
| + | |||
| + | CANCELLED | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== ReservationStatusHistory ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model ReservationStatusHistory { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | reservationId | ||
| + | |||
| + | previousStatus | ||
| + | |||
| + | newStatus | ||
| + | |||
| + | changedAt | ||
| + | |||
| + | reservation | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Relations à ajouter ====== | ||
| + | |||
| + | ===== Property ===== | ||
| + | |||
| + | Ajouter : | ||
| + | |||
| + | <code prisma> | ||
| + | reservations Reservation[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Tenant ===== | ||
| + | |||
| + | Ajouter : | ||
| + | |||
| + | <code prisma> | ||
| + | owners Owner[] | ||
| + | |||
| + | reservations Reservation[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Indexes ====== | ||
| + | |||
| + | ===== Owner ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([email]) | ||
| + | |||
| + | @@index([active]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Reservation ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([propertyId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | |||
| + | @@index([checkInDate]) | ||
| + | |||
| + | @@index([checkOutDate]) | ||
| + | |||
| + | @@index([reference]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== ReservationGuest ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([reservationId]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Validation ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma format | ||
| + | |||
| + | npx prisma validate | ||
| + | |||
| + | npx prisma generate | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Migration ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma migrate dev \ | ||
| + | --name owners_and_reservations | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== État actuel du schéma ====== | ||
| + | |||
| + | À ce stade, le noyau fonctionnel est enfin présent : | ||
| + | |||
| + | < | ||
| + | Tenant | ||
| + | |||
| + | User | ||
| + | |||
| + | Role | ||
| + | |||
| + | Permission | ||
| + | |||
| + | Owner | ||
| + | |||
| + | Property | ||
| + | |||
| + | Reservation | ||
| + | </ | ||
| + | |||
| + | avec : | ||
| + | |||
| + | < | ||
| + | Catalogue Immobilier | ||
| + | |||
| + | Propriétaires | ||
| + | |||
| + | Réservations | ||
| + | |||
| + | RBAC | ||
| + | |||
| + | Multi-tenant | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Phase 2-E — Contrats, Documents, Paiements & Facturation ====== | ||
| + | |||
| + | ===== Objectif ===== | ||
| + | |||
| + | Construire | ||
| + | |||
| + | < | ||
| + | Client | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Réservation | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Contrat | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Signature | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Paiement | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Facture | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Comptabilité | ||
| + | </ | ||
| + | |||
| + | Cette phase couvre : | ||
| + | |||
| + | * Sprint 5 — Contrats & Signature Électronique | ||
| + | * Sprint 6 — Paiements & Facturation | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Prérequis ====== | ||
| + | |||
| + | Avant cette phase, le schéma doit déjà contenir : | ||
| + | |||
| + | < | ||
| + | Tenant | ||
| + | |||
| + | User | ||
| + | |||
| + | Role | ||
| + | |||
| + | Permission | ||
| + | |||
| + | Owner | ||
| + | |||
| + | Property | ||
| + | |||
| + | Reservation | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Domaine Client ====== | ||
| + | |||
| + | Avant les contrats et paiements, il faut définir le client. | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Customer ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Customer { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | customerNumber | ||
| + | |||
| + | firstName | ||
| + | |||
| + | lastName | ||
| + | |||
| + | email | ||
| + | |||
| + | phone | ||
| + | |||
| + | mobile | ||
| + | |||
| + | birthDate | ||
| + | |||
| + | nationality | ||
| + | |||
| + | languageCode | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | deletedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | address | ||
| + | |||
| + | documents | ||
| + | |||
| + | reservations | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== CustomerAddress ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model CustomerAddress { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | customerId | ||
| + | |||
| + | addressLine1 | ||
| + | |||
| + | addressLine2 | ||
| + | |||
| + | postalCode | ||
| + | |||
| + | city String | ||
| + | |||
| + | state | ||
| + | |||
| + | countryCode | ||
| + | |||
| + | customer | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== CustomerDocument ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model CustomerDocument { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | customerId | ||
| + | |||
| + | documentType | ||
| + | |||
| + | fileUrl | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | customer | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Mise à jour Reservation ====== | ||
| + | |||
| + | ===== Ajouter ===== | ||
| + | |||
| + | <code prisma> | ||
| + | customerId String? | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Relation ===== | ||
| + | |||
| + | <code prisma> | ||
| + | customer Customer? @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Domaine Contrats ====== | ||
| + | |||
| + | ===== Architecture ===== | ||
| + | |||
| + | < | ||
| + | Contract | ||
| + | |||
| + | ContractTemplate | ||
| + | |||
| + | ContractVersion | ||
| + | |||
| + | ContractSignature | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Contract ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model Contract { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | reservationId | ||
| + | |||
| + | templateId | ||
| + | |||
| + | contractNumber | ||
| + | |||
| + | status | ||
| + | |||
| + | signedAt | ||
| + | |||
| + | generatedAt | ||
| + | |||
| + | pdfUrl | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | reservation | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | template | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | signatures | ||
| + | |||
| + | versions | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== ContractStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum ContractStatus { | ||
| + | |||
| + | DRAFT | ||
| + | |||
| + | GENERATED | ||
| + | |||
| + | SENT | ||
| + | |||
| + | VIEWED | ||
| + | |||
| + | SIGNED | ||
| + | |||
| + | CANCELLED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== ContractTemplate ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model ContractTemplate { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | code String @unique | ||
| + | |||
| + | name String | ||
| + | |||
| + | content | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | contracts | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== ContractVersion ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model ContractVersion { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | contractId | ||
| + | |||
| + | versionNumber | ||
| + | |||
| + | pdfUrl | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | contract | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== ContractSignature ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model ContractSignature { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | contractId | ||
| + | |||
| + | signerName | ||
| + | |||
| + | signerEmail | ||
| + | |||
| + | signedAt | ||
| + | |||
| + | providerReference | ||
| + | |||
| + | status | ||
| + | |||
| + | contract | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Domaine Documents ====== | ||
| + | |||
| + | ===== Document ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Document { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | documentType | ||
| + | |||
| + | fileName | ||
| + | |||
| + | fileUrl | ||
| + | |||
| + | mimeType | ||
| + | |||
| + | fileSize | ||
| + | |||
| + | uploadedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Domaine Paiements ====== | ||
| + | |||
| + | ===== Architecture ===== | ||
| + | |||
| + | < | ||
| + | Payment | ||
| + | |||
| + | PaymentTransaction | ||
| + | |||
| + | Refund | ||
| + | |||
| + | PaymentMethod | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Payment ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model Payment { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | reservationId | ||
| + | |||
| + | paymentReference | ||
| + | |||
| + | status | ||
| + | |||
| + | amount | ||
| + | |||
| + | currencyCode | ||
| + | |||
| + | paidAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | reservation | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | transactions | ||
| + | |||
| + | refunds | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== PaymentStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum PaymentStatus { | ||
| + | |||
| + | PENDING | ||
| + | |||
| + | AUTHORIZED | ||
| + | |||
| + | PAID | ||
| + | |||
| + | FAILED | ||
| + | |||
| + | CANCELLED | ||
| + | |||
| + | REFUNDED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== PaymentTransaction ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model PaymentTransaction { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | paymentId | ||
| + | |||
| + | gateway | ||
| + | |||
| + | gatewayReference | ||
| + | |||
| + | status | ||
| + | |||
| + | amount | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | payment | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Refund ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model Refund { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | paymentId | ||
| + | |||
| + | amount | ||
| + | |||
| + | reason | ||
| + | |||
| + | refundedAt | ||
| + | |||
| + | payment | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Facturation ====== | ||
| + | |||
| + | ===== Invoice ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Invoice { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | reservationId | ||
| + | |||
| + | invoiceNumber | ||
| + | |||
| + | issueDate | ||
| + | |||
| + | dueDate | ||
| + | |||
| + | amountExclTax | ||
| + | |||
| + | taxAmount | ||
| + | |||
| + | amountInclTax | ||
| + | |||
| + | status | ||
| + | |||
| + | pdfUrl | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | reservation | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== InvoiceStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum InvoiceStatus { | ||
| + | |||
| + | DRAFT | ||
| + | |||
| + | ISSUED | ||
| + | |||
| + | PAID | ||
| + | |||
| + | PARTIALLY_PAID | ||
| + | |||
| + | CANCELLED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Comptabilité ====== | ||
| + | |||
| + | ===== AccountingEntry ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model AccountingEntry { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | entryDate | ||
| + | |||
| + | accountCode | ||
| + | |||
| + | label | ||
| + | |||
| + | debit | ||
| + | |||
| + | credit | ||
| + | |||
| + | reference | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Indexes ====== | ||
| + | |||
| + | ===== Contract ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([reservationId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | |||
| + | @@index([contractNumber]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Payment ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([reservationId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | |||
| + | @@index([paymentReference]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Invoice ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([reservationId]) | ||
| + | |||
| + | @@index([invoiceNumber]) | ||
| + | |||
| + | @@index([status]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Validation ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma format | ||
| + | |||
| + | npx prisma validate | ||
| + | |||
| + | npx prisma generate | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Migration ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma migrate dev \ | ||
| + | --name contracts_payments_invoices | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== État du noyau métier ====== | ||
| + | |||
| + | À ce stade, le schéma couvre : | ||
| + | |||
| + | < | ||
| + | Tenant | ||
| + | |||
| + | User | ||
| + | |||
| + | RBAC | ||
| + | |||
| + | Owner | ||
| + | |||
| + | Property | ||
| + | |||
| + | Customer | ||
| + | |||
| + | Reservation | ||
| + | |||
| + | Contract | ||
| + | |||
| + | Document | ||
| + | |||
| + | Payment | ||
| + | |||
| + | Invoice | ||
| + | |||
| + | Accounting | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Flux métier désormais couvert ====== | ||
| + | |||
| + | < | ||
| + | Owner | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Property | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Customer | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Reservation | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Contract | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Signature | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Payment | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Invoice | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Accounting | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== 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 ===== | ||
| + | |||
| + | < | ||
| + | Lead | ||
| + | |||
| + | Opportunity | ||
| + | |||
| + | Pipeline | ||
| + | |||
| + | PipelineStage | ||
| + | |||
| + | Activity | ||
| + | |||
| + | Task | ||
| + | |||
| + | CustomerNote | ||
| + | |||
| + | Tag | ||
| + | |||
| + | Segment | ||
| + | |||
| + | CustomerTag | ||
| + | |||
| + | LeadSource | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Vue d' | ||
| + | |||
| + | < | ||
| + | Lead | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Qualification | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Opportunity | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Reservation | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Customer | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Lead ====== | ||
| + | |||
| + | ===== Prospect ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Lead { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | leadNumber | ||
| + | |||
| + | firstName | ||
| + | |||
| + | lastName | ||
| + | |||
| + | email | ||
| + | |||
| + | phone | ||
| + | |||
| + | company | ||
| + | |||
| + | sourceId | ||
| + | |||
| + | status | ||
| + | |||
| + | score Int @default(0) | ||
| + | |||
| + | estimatedBudget | ||
| + | |||
| + | expectedCheckIn | ||
| + | |||
| + | expectedCheckOut | ||
| + | |||
| + | notes | ||
| + | |||
| + | assignedToUserId | ||
| + | |||
| + | convertedAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | source | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | opportunities | ||
| + | |||
| + | activities | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== LeadStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum LeadStatus { | ||
| + | |||
| + | NEW | ||
| + | |||
| + | QUALIFIED | ||
| + | |||
| + | CONTACTED | ||
| + | |||
| + | PROPOSAL | ||
| + | |||
| + | WON | ||
| + | |||
| + | LOST | ||
| + | |||
| + | ARCHIVED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== LeadSource ====== | ||
| + | |||
| + | ===== Origine du prospect ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model LeadSource { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | code String @unique | ||
| + | |||
| + | name String | ||
| + | |||
| + | leads | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Valeurs ===== | ||
| + | |||
| + | < | ||
| + | WEBSITE | ||
| + | |||
| + | PHONE | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | AIRBNB | ||
| + | |||
| + | BOOKING | ||
| + | |||
| + | REFERRAL | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Pipeline ====== | ||
| + | |||
| + | ===== Pipeline commercial ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Pipeline { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | name String | ||
| + | |||
| + | active | ||
| + | |||
| + | stages | ||
| + | |||
| + | opportunities | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== PipelineStage ====== | ||
| + | |||
| + | <code prisma> | ||
| + | model PipelineStage { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | pipelineId | ||
| + | |||
| + | name String | ||
| + | |||
| + | position | ||
| + | |||
| + | probability | ||
| + | |||
| + | pipeline | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemple ===== | ||
| + | |||
| + | < | ||
| + | Nouveau | ||
| + | |||
| + | Qualification | ||
| + | |||
| + | Proposition | ||
| + | |||
| + | Négociation | ||
| + | |||
| + | Gagné | ||
| + | |||
| + | Perdu | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Opportunity ====== | ||
| + | |||
| + | ===== Opportunité commerciale ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Opportunity { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | leadId | ||
| + | |||
| + | pipelineId | ||
| + | |||
| + | stageId | ||
| + | |||
| + | title | ||
| + | |||
| + | amount | ||
| + | |||
| + | probability | ||
| + | |||
| + | expectedCloseDate | ||
| + | |||
| + | status | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | lead Lead @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | pipeline | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== OpportunityStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum OpportunityStatus { | ||
| + | |||
| + | OPEN | ||
| + | |||
| + | WON | ||
| + | |||
| + | LOST | ||
| + | |||
| + | CANCELLED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Activity ====== | ||
| + | |||
| + | ===== Historique des interactions ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Activity { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | leadId | ||
| + | |||
| + | customerId | ||
| + | |||
| + | activityType | ||
| + | |||
| + | subject | ||
| + | |||
| + | description | ||
| + | |||
| + | occurredAt | ||
| + | |||
| + | createdByUserId | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | lead Lead? @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | customer | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== ActivityType ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum ActivityType { | ||
| + | |||
| + | CALL | ||
| + | |||
| + | |||
| + | |||
| + | MEETING | ||
| + | |||
| + | SMS | ||
| + | |||
| + | NOTE | ||
| + | |||
| + | TASK | ||
| + | |||
| + | SYSTEM | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Task ====== | ||
| + | |||
| + | ===== Tâches CRM ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Task { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | title | ||
| + | |||
| + | description | ||
| + | |||
| + | assignedToUserId | ||
| + | |||
| + | dueDate | ||
| + | |||
| + | completedAt | ||
| + | |||
| + | priority | ||
| + | |||
| + | status | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== TaskPriority ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum TaskPriority { | ||
| + | |||
| + | LOW | ||
| + | |||
| + | MEDIUM | ||
| + | |||
| + | HIGH | ||
| + | |||
| + | URGENT | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== TaskStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum TaskStatus { | ||
| + | |||
| + | OPEN | ||
| + | |||
| + | IN_PROGRESS | ||
| + | |||
| + | DONE | ||
| + | |||
| + | CANCELLED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== CustomerNote ====== | ||
| + | |||
| + | ===== Notes internes ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model CustomerNote { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | customerId | ||
| + | |||
| + | authorUserId | ||
| + | |||
| + | content | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | customer | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Tag ====== | ||
| + | |||
| + | ===== Classification ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Tag { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String @unique | ||
| + | |||
| + | name String | ||
| + | |||
| + | color | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | customerTags | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== CustomerTag ====== | ||
| + | |||
| + | ===== Relation N:N ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model CustomerTag { | ||
| + | |||
| + | customerId | ||
| + | |||
| + | tagId | ||
| + | |||
| + | customer | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | tag Tag @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@id([customerId, | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Segment ====== | ||
| + | |||
| + | ===== Segmentation marketing ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Segment { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String @unique | ||
| + | |||
| + | name String | ||
| + | |||
| + | description | ||
| + | |||
| + | rules | ||
| + | |||
| + | active | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Relations à ajouter ====== | ||
| + | |||
| + | ===== Customer ===== | ||
| + | |||
| + | Ajouter : | ||
| + | |||
| + | <code prisma> | ||
| + | activities Activity[] | ||
| + | |||
| + | notes CustomerNote[] | ||
| + | |||
| + | tags CustomerTag[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Tenant ===== | ||
| + | |||
| + | Ajouter : | ||
| + | |||
| + | <code prisma> | ||
| + | leads Lead[] | ||
| + | |||
| + | opportunities Opportunity[] | ||
| + | |||
| + | pipelines Pipeline[] | ||
| + | |||
| + | tasks Task[] | ||
| + | |||
| + | segments Segment[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Indexes ====== | ||
| + | |||
| + | ===== Lead ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | |||
| + | @@index([email]) | ||
| + | |||
| + | @@index([assignedToUserId]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Opportunity ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | |||
| + | @@index([expectedCloseDate]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Task ===== | ||
| + | |||
| + | <code prisma> | ||
| + | @@index([assignedToUserId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | |||
| + | @@index([dueDate]) | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Validation ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma format | ||
| + | |||
| + | npx prisma validate | ||
| + | |||
| + | npx prisma generate | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Migration ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma migrate dev \ | ||
| + | --name crm_and_customer_relationship | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Fonctionnalités désormais couvertes ====== | ||
| + | |||
| + | ===== Sprint 8 ===== | ||
| + | |||
| + | < | ||
| + | Prospects | ||
| + | |||
| + | Pipeline | ||
| + | |||
| + | Relances | ||
| + | |||
| + | Activités | ||
| + | |||
| + | Tâches | ||
| + | |||
| + | Segmentation | ||
| + | |||
| + | Historique client | ||
| + | |||
| + | Vue 360° | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Nouveau flux métier ====== | ||
| + | |||
| + | < | ||
| + | Lead | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Qualification | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Opportunity | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Reservation | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Contract | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Payment | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Customer Loyalty | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== État global du schéma ====== | ||
| + | |||
| + | Le noyau métier couvre désormais : | ||
| + | |||
| + | < | ||
| + | RBAC | ||
| + | |||
| + | Utilisateurs | ||
| + | |||
| + | Propriétaires | ||
| + | |||
| + | Catalogue | ||
| + | |||
| + | Réservations | ||
| + | |||
| + | Contrats | ||
| + | |||
| + | Paiements | ||
| + | |||
| + | Facturation | ||
| + | |||
| + | CRM | ||
| + | </ | ||
| + | |||
| + | soit environ : | ||
| + | |||
| + | < | ||
| + | 35 à 40 modèles Prisma | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Phase 2-G — Notifications, | ||
| + | |||
| + | ===== Objectif ===== | ||
| + | |||
| + | Mettre en place le centre de communication unifié de la plateforme. | ||
| + | |||
| + | Ce domaine | ||
| + | |||
| + | * 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 : | ||
| + | |||
| + | < | ||
| + | Reservations | ||
| + | |||
| + | Contracts | ||
| + | |||
| + | Payments | ||
| + | |||
| + | CRM | ||
| + | |||
| + | Owner Portal | ||
| + | |||
| + | Administration | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Architecture ====== | ||
| + | |||
| + | ===== Modèles ===== | ||
| + | |||
| + | < | ||
| + | Notification | ||
| + | |||
| + | NotificationTemplate | ||
| + | |||
| + | NotificationPreference | ||
| + | |||
| + | Conversation | ||
| + | |||
| + | ConversationParticipant | ||
| + | |||
| + | Message | ||
| + | |||
| + | EmailLog | ||
| + | |||
| + | SmsLog | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Notification ====== | ||
| + | |||
| + | ===== Centre de notifications ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Notification { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | userId | ||
| + | |||
| + | type NotificationType | ||
| + | |||
| + | title | ||
| + | |||
| + | content | ||
| + | |||
| + | status | ||
| + | |||
| + | entityType | ||
| + | |||
| + | entityId | ||
| + | |||
| + | readAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | user User @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([userId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | |||
| + | @@index([createdAt]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== NotificationType ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum NotificationType { | ||
| + | |||
| + | SYSTEM | ||
| + | |||
| + | RESERVATION | ||
| + | |||
| + | CONTRACT | ||
| + | |||
| + | PAYMENT | ||
| + | |||
| + | CRM | ||
| + | |||
| + | OWNER | ||
| + | |||
| + | SECURITY | ||
| + | |||
| + | MARKETING | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== NotificationStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum NotificationStatus { | ||
| + | |||
| + | UNREAD | ||
| + | |||
| + | READ | ||
| + | |||
| + | ARCHIVED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== NotificationTemplate ====== | ||
| + | |||
| + | ===== Modèles de notification ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model NotificationTemplate { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String | ||
| + | |||
| + | name String | ||
| + | |||
| + | subject | ||
| + | |||
| + | content | ||
| + | |||
| + | channel | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([tenantId, | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== NotificationChannel ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum NotificationChannel { | ||
| + | |||
| + | IN_APP | ||
| + | |||
| + | |||
| + | |||
| + | SMS | ||
| + | |||
| + | PUSH | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== NotificationPreference ====== | ||
| + | |||
| + | ===== Préférences utilisateur ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model NotificationPreference { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | userId | ||
| + | |||
| + | notificationType | ||
| + | |||
| + | emailEnabled | ||
| + | |||
| + | smsEnabled | ||
| + | |||
| + | pushEnabled | ||
| + | |||
| + | inAppEnabled | ||
| + | |||
| + | user User @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([userId, | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Conversation ====== | ||
| + | |||
| + | ===== Fil de discussion ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Conversation { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | reservationId | ||
| + | |||
| + | subject | ||
| + | |||
| + | status | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | reservation | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | participants | ||
| + | |||
| + | messages | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([reservationId]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== ConversationStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum ConversationStatus { | ||
| + | |||
| + | OPEN | ||
| + | |||
| + | CLOSED | ||
| + | |||
| + | ARCHIVED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== ConversationParticipant ====== | ||
| + | |||
| + | ===== Participants ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model ConversationParticipant { | ||
| + | |||
| + | conversationId | ||
| + | |||
| + | userId | ||
| + | |||
| + | customerId | ||
| + | |||
| + | ownerId | ||
| + | |||
| + | joinedAt | ||
| + | |||
| + | conversation | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | user User? @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | customer | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | owner | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@id([ | ||
| + | conversationId, | ||
| + | userId, | ||
| + | customerId, | ||
| + | ownerId | ||
| + | ]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Message ====== | ||
| + | |||
| + | ===== Message ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Message { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | conversationId | ||
| + | |||
| + | senderUserId | ||
| + | |||
| + | senderCustomerId | ||
| + | |||
| + | senderOwnerId | ||
| + | |||
| + | content | ||
| + | |||
| + | sentAt | ||
| + | |||
| + | readAt | ||
| + | |||
| + | conversation | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | senderUser | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | senderCustomer | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | senderOwner | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([conversationId]) | ||
| + | |||
| + | @@index([sentAt]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== EmailLog ====== | ||
| + | |||
| + | ===== Historique Emails ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model EmailLog { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | templateId | ||
| + | |||
| + | recipientEmail | ||
| + | |||
| + | subject | ||
| + | |||
| + | provider | ||
| + | |||
| + | providerMessageId | ||
| + | |||
| + | status | ||
| + | |||
| + | errorMessage | ||
| + | |||
| + | sentAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | template | ||
| + | @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([recipientEmail]) | ||
| + | |||
| + | @@index([status]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== EmailStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum EmailStatus { | ||
| + | |||
| + | PENDING | ||
| + | |||
| + | SENT | ||
| + | |||
| + | DELIVERED | ||
| + | |||
| + | OPENED | ||
| + | |||
| + | FAILED | ||
| + | |||
| + | BOUNCED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== SmsLog ====== | ||
| + | |||
| + | ===== Historique SMS ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model SmsLog { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | recipientPhone | ||
| + | |||
| + | content | ||
| + | |||
| + | provider | ||
| + | |||
| + | providerMessageId | ||
| + | |||
| + | status | ||
| + | |||
| + | errorMessage | ||
| + | |||
| + | sentAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([recipientPhone]) | ||
| + | |||
| + | @@index([status]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== SmsStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum SmsStatus { | ||
| + | |||
| + | PENDING | ||
| + | |||
| + | SENT | ||
| + | |||
| + | DELIVERED | ||
| + | |||
| + | FAILED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Relations à ajouter ====== | ||
| + | |||
| + | ===== User ===== | ||
| + | |||
| + | <code prisma> | ||
| + | notifications Notification[] | ||
| + | |||
| + | notificationPreferences NotificationPreference[] | ||
| + | |||
| + | conversationParticipants | ||
| + | ConversationParticipant[] | ||
| + | |||
| + | messages Message[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Customer ===== | ||
| + | |||
| + | <code prisma> | ||
| + | conversationParticipants | ||
| + | ConversationParticipant[] | ||
| + | |||
| + | messages Message[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Owner ===== | ||
| + | |||
| + | <code prisma> | ||
| + | conversationParticipants | ||
| + | ConversationParticipant[] | ||
| + | |||
| + | messages Message[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Reservation ===== | ||
| + | |||
| + | <code prisma> | ||
| + | conversations Conversation[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Tenant ===== | ||
| + | |||
| + | <code prisma> | ||
| + | notifications Notification[] | ||
| + | |||
| + | notificationTemplates NotificationTemplate[] | ||
| + | |||
| + | conversations Conversation[] | ||
| + | |||
| + | emailLogs EmailLog[] | ||
| + | |||
| + | smsLogs SmsLog[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Validation ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma format | ||
| + | |||
| + | npx prisma validate | ||
| + | |||
| + | npx prisma generate | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Migration ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma migrate dev \ | ||
| + | --name notifications_messaging | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Fonctionnalités couvertes ====== | ||
| + | |||
| + | ===== Sprint 9 ===== | ||
| + | |||
| + | < | ||
| + | Notifications temps réel | ||
| + | |||
| + | Centre de notifications | ||
| + | |||
| + | Messagerie propriétaire | ||
| + | |||
| + | Messagerie client | ||
| + | |||
| + | Messagerie réservation | ||
| + | |||
| + | Emails transactionnels | ||
| + | |||
| + | SMS transactionnels | ||
| + | |||
| + | Préférences utilisateur | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== État du schéma ====== | ||
| + | |||
| + | Après Phase 2-G : | ||
| + | |||
| + | < | ||
| + | ≈ 60 modèles Prisma | ||
| + | </ | ||
| + | |||
| + | avec les domaines : | ||
| + | |||
| + | < | ||
| + | Core | ||
| + | |||
| + | Security | ||
| + | |||
| + | Properties | ||
| + | |||
| + | Owners | ||
| + | |||
| + | Customers | ||
| + | |||
| + | Reservations | ||
| + | |||
| + | Contracts | ||
| + | |||
| + | Payments | ||
| + | |||
| + | CRM | ||
| + | |||
| + | Notifications | ||
| + | |||
| + | Messaging | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== 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 : | ||
| + | |||
| + | < | ||
| + | Sprint 8 CRM | ||
| + | |||
| + | Sprint 9 Communication | ||
| + | |||
| + | Sprint 13 Automatisation & IA | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Architecture ====== | ||
| + | |||
| + | ===== Modèles ===== | ||
| + | |||
| + | < | ||
| + | Campaign | ||
| + | |||
| + | CampaignRecipient | ||
| + | |||
| + | CampaignExecution | ||
| + | |||
| + | MarketingSegment | ||
| + | |||
| + | MarketingEvent | ||
| + | |||
| + | AutomationRule | ||
| + | |||
| + | AutomationExecution | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Campaign ====== | ||
| + | |||
| + | ===== Campagne Marketing ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Campaign { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String | ||
| + | |||
| + | name String | ||
| + | |||
| + | description | ||
| + | |||
| + | campaignType | ||
| + | |||
| + | status | ||
| + | |||
| + | startDate | ||
| + | |||
| + | endDate | ||
| + | |||
| + | createdByUserId | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | createdByUser | ||
| + | " | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | recipients | ||
| + | |||
| + | executions | ||
| + | |||
| + | @@unique([tenantId, | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== CampaignType ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum CampaignType { | ||
| + | |||
| + | |||
| + | |||
| + | SMS | ||
| + | |||
| + | MIXED | ||
| + | |||
| + | PUSH | ||
| + | |||
| + | WORKFLOW | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== CampaignStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum CampaignStatus { | ||
| + | |||
| + | DRAFT | ||
| + | |||
| + | SCHEDULED | ||
| + | |||
| + | RUNNING | ||
| + | |||
| + | COMPLETED | ||
| + | |||
| + | PAUSED | ||
| + | |||
| + | CANCELLED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== CampaignRecipient ====== | ||
| + | |||
| + | ===== Destinataires ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model CampaignRecipient { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | campaignId | ||
| + | |||
| + | customerId | ||
| + | |||
| + | leadId | ||
| + | |||
| + | email | ||
| + | |||
| + | phone | ||
| + | |||
| + | status | ||
| + | |||
| + | sentAt | ||
| + | |||
| + | openedAt | ||
| + | |||
| + | clickedAt | ||
| + | |||
| + | unsubscribedAt | ||
| + | |||
| + | campaign | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | customer | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | lead Lead? @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([campaignId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== CampaignRecipientStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum CampaignRecipientStatus { | ||
| + | |||
| + | PENDING | ||
| + | |||
| + | SENT | ||
| + | |||
| + | OPENED | ||
| + | |||
| + | CLICKED | ||
| + | |||
| + | FAILED | ||
| + | |||
| + | UNSUBSCRIBED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== CampaignExecution ====== | ||
| + | |||
| + | ===== Exécution ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model CampaignExecution { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | campaignId | ||
| + | |||
| + | startedAt | ||
| + | |||
| + | completedAt | ||
| + | |||
| + | recipientsCount | ||
| + | |||
| + | successCount | ||
| + | |||
| + | failedCount | ||
| + | |||
| + | status | ||
| + | |||
| + | campaign | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([campaignId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== ExecutionStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum ExecutionStatus { | ||
| + | |||
| + | PENDING | ||
| + | |||
| + | RUNNING | ||
| + | |||
| + | COMPLETED | ||
| + | |||
| + | FAILED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== MarketingSegment ====== | ||
| + | |||
| + | ===== Segmentation avancée ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model MarketingSegment { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String | ||
| + | |||
| + | name String | ||
| + | |||
| + | description | ||
| + | |||
| + | rules | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([tenantId, | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | CLIENTS_FIDELES | ||
| + | |||
| + | CLIENTS_INACTIFS | ||
| + | |||
| + | PROPRIETAIRES_ACTIFS | ||
| + | |||
| + | PROSPECTS_CHAUDS | ||
| + | |||
| + | RESERVATIONS_30J | ||
| + | |||
| + | ANNIVERSAIRES | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== MarketingEvent ====== | ||
| + | |||
| + | ===== Événements Marketing ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model MarketingEvent { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | customerId | ||
| + | |||
| + | leadId | ||
| + | |||
| + | eventType | ||
| + | |||
| + | payload | ||
| + | |||
| + | occurredAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | customer | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | lead Lead? @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([eventType]) | ||
| + | |||
| + | @@index([occurredAt]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== MarketingEventType ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum MarketingEventType { | ||
| + | |||
| + | EMAIL_OPEN | ||
| + | |||
| + | EMAIL_CLICK | ||
| + | |||
| + | SMS_SENT | ||
| + | |||
| + | PAGE_VISIT | ||
| + | |||
| + | FORM_SUBMIT | ||
| + | |||
| + | LEAD_CREATED | ||
| + | |||
| + | RESERVATION_CREATED | ||
| + | |||
| + | CONTRACT_SIGNED | ||
| + | |||
| + | PAYMENT_COMPLETED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== AutomationRule ====== | ||
| + | |||
| + | ===== Règle | ||
| + | |||
| + | <code prisma> | ||
| + | model AutomationRule { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String | ||
| + | |||
| + | name String | ||
| + | |||
| + | description | ||
| + | |||
| + | triggerEvent | ||
| + | |||
| + | conditions | ||
| + | |||
| + | actions | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | executions | ||
| + | |||
| + | @@unique([tenantId, | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([active]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | ReservationConfirmed | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | SendEmail | ||
| + | |||
| + | ---------------- | ||
| + | |||
| + | PaymentReceived | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | GenerateInvoice | ||
| + | |||
| + | ---------------- | ||
| + | |||
| + | LeadCreated | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | AssignSalesAgent | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== AutomationExecution ====== | ||
| + | |||
| + | ===== Historique ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model AutomationExecution { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | automationRuleId | ||
| + | |||
| + | status | ||
| + | |||
| + | entityType | ||
| + | |||
| + | entityId | ||
| + | |||
| + | startedAt | ||
| + | |||
| + | completedAt | ||
| + | |||
| + | errorMessage | ||
| + | |||
| + | automationRule | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([automationRuleId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Relations à ajouter ====== | ||
| + | |||
| + | ===== Tenant ===== | ||
| + | |||
| + | <code prisma> | ||
| + | campaigns Campaign[] | ||
| + | |||
| + | marketingSegments MarketingSegment[] | ||
| + | |||
| + | marketingEvents MarketingEvent[] | ||
| + | |||
| + | automationRules AutomationRule[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Customer ===== | ||
| + | |||
| + | <code prisma> | ||
| + | campaignRecipients CampaignRecipient[] | ||
| + | |||
| + | marketingEvents MarketingEvent[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Lead ===== | ||
| + | |||
| + | <code prisma> | ||
| + | campaignRecipients CampaignRecipient[] | ||
| + | |||
| + | marketingEvents MarketingEvent[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== User ===== | ||
| + | |||
| + | <code prisma> | ||
| + | createdCampaigns Campaign[] | ||
| + | @relation(" | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Validation ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma format | ||
| + | |||
| + | npx prisma validate | ||
| + | |||
| + | npx prisma generate | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Migration ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma migrate dev \ | ||
| + | --name marketing_automation | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Fonctionnalités couvertes ====== | ||
| + | |||
| + | ===== CRM ===== | ||
| + | |||
| + | < | ||
| + | Lead Nurturing | ||
| + | |||
| + | Relances | ||
| + | |||
| + | Segmentation | ||
| + | |||
| + | Scoring | ||
| + | |||
| + | Qualification | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Communication ===== | ||
| + | |||
| + | < | ||
| + | Campagnes Email | ||
| + | |||
| + | Campagnes SMS | ||
| + | |||
| + | Suivi Ouvertures | ||
| + | |||
| + | Suivi Clics | ||
| + | |||
| + | Désabonnement | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Automatisation ===== | ||
| + | |||
| + | < | ||
| + | Déclencheurs | ||
| + | |||
| + | Workflows | ||
| + | |||
| + | Actions Automatiques | ||
| + | |||
| + | Historisation | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== État du schéma ====== | ||
| + | |||
| + | Après Phase 2-H : | ||
| + | |||
| + | < | ||
| + | ≈ 67 modèles Prisma | ||
| + | </ | ||
| + | |||
| + | avec les domaines : | ||
| + | |||
| + | < | ||
| + | Core | ||
| + | |||
| + | Security | ||
| + | |||
| + | Properties | ||
| + | |||
| + | Owners | ||
| + | |||
| + | Customers | ||
| + | |||
| + | Reservations | ||
| + | |||
| + | Contracts | ||
| + | |||
| + | Payments | ||
| + | |||
| + | CRM | ||
| + | |||
| + | Messaging | ||
| + | |||
| + | Marketing | ||
| + | |||
| + | Automation | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Phase 2-I — Administration, | ||
| + | |||
| + | ===== 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 : | ||
| + | |||
| + | < | ||
| + | Sprint 10 — Reporting | ||
| + | |||
| + | Sprint 11 — Administration | ||
| + | |||
| + | Sprint 19 — Gouvernance & Conformité | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Architecture ====== | ||
| + | |||
| + | ===== Modèles ===== | ||
| + | |||
| + | < | ||
| + | AuditLog | ||
| + | |||
| + | EntityHistory | ||
| + | |||
| + | FeatureFlag | ||
| + | |||
| + | Workflow | ||
| + | |||
| + | WorkflowStep | ||
| + | |||
| + | WorkflowInstance | ||
| + | |||
| + | WorkflowExecution | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== AuditLog ====== | ||
| + | |||
| + | ===== Journal d' | ||
| + | |||
| + | Toutes les actions sensibles doivent être tracées. | ||
| + | |||
| + | <code prisma> | ||
| + | model AuditLog { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | userId | ||
| + | |||
| + | entityType | ||
| + | |||
| + | entityId | ||
| + | |||
| + | action | ||
| + | |||
| + | oldValues | ||
| + | |||
| + | newValues | ||
| + | |||
| + | ipAddress | ||
| + | |||
| + | userAgent | ||
| + | |||
| + | correlationId | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | user User? @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([entityType]) | ||
| + | |||
| + | @@index([entityId]) | ||
| + | |||
| + | @@index([action]) | ||
| + | |||
| + | @@index([createdAt]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== AuditAction ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum AuditAction { | ||
| + | |||
| + | CREATE | ||
| + | |||
| + | UPDATE | ||
| + | |||
| + | DELETE | ||
| + | |||
| + | RESTORE | ||
| + | |||
| + | LOGIN | ||
| + | |||
| + | LOGOUT | ||
| + | |||
| + | EXPORT | ||
| + | |||
| + | IMPORT | ||
| + | |||
| + | EXECUTE | ||
| + | |||
| + | APPROVE | ||
| + | |||
| + | REJECT | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== EntityHistory ====== | ||
| + | |||
| + | ===== Historisation métier ===== | ||
| + | |||
| + | Permet de reconstruire l' | ||
| + | |||
| + | <code prisma> | ||
| + | model EntityHistory { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | entityType | ||
| + | |||
| + | entityId | ||
| + | |||
| + | version | ||
| + | |||
| + | snapshot | ||
| + | |||
| + | createdByUserId | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | createdByUser | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([ | ||
| + | entityType, | ||
| + | entityId, | ||
| + | version | ||
| + | ]) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([entityType]) | ||
| + | |||
| + | @@index([entityId]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== FeatureFlag ====== | ||
| + | |||
| + | ===== Activation dynamique ===== | ||
| + | |||
| + | Permet de déployer progressivement des fonctionnalités. | ||
| + | |||
| + | <code prisma> | ||
| + | model FeatureFlag { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String @unique | ||
| + | |||
| + | name String | ||
| + | |||
| + | description | ||
| + | |||
| + | enabled | ||
| + | |||
| + | configuration | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([enabled]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | AI_ASSISTANT | ||
| + | |||
| + | OWNER_PORTAL_V2 | ||
| + | |||
| + | OTA_SYNC | ||
| + | |||
| + | REVENUE_MANAGEMENT | ||
| + | |||
| + | ADVANCED_REPORTING | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Workflow ====== | ||
| + | |||
| + | ===== Définition d'un workflow ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Workflow { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String | ||
| + | |||
| + | name String | ||
| + | |||
| + | description | ||
| + | |||
| + | entityType | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | steps | ||
| + | |||
| + | instances | ||
| + | |||
| + | @@unique([tenantId, | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([entityType]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== WorkflowStep ====== | ||
| + | |||
| + | ===== Étapes du workflow ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model WorkflowStep { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | workflowId | ||
| + | |||
| + | code String | ||
| + | |||
| + | name String | ||
| + | |||
| + | position | ||
| + | |||
| + | approverRoleCode | ||
| + | |||
| + | automatic | ||
| + | |||
| + | configuration | ||
| + | |||
| + | workflow | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([ | ||
| + | workflowId, | ||
| + | code | ||
| + | ]) | ||
| + | |||
| + | @@index([workflowId]) | ||
| + | |||
| + | @@index([position]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemple ===== | ||
| + | |||
| + | < | ||
| + | ReservationApproval | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | ManagerApproval | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | ContractGeneration | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | PaymentValidation | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Completed | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== WorkflowInstance ====== | ||
| + | |||
| + | ===== Exécution métier ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model WorkflowInstance { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | workflowId | ||
| + | |||
| + | entityType | ||
| + | |||
| + | entityId | ||
| + | |||
| + | currentStepId | ||
| + | |||
| + | status | ||
| + | |||
| + | startedAt | ||
| + | |||
| + | completedAt | ||
| + | |||
| + | workflow | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | currentStep | ||
| + | @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | executions | ||
| + | |||
| + | @@index([workflowId]) | ||
| + | |||
| + | @@index([entityType]) | ||
| + | |||
| + | @@index([entityId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== WorkflowInstanceStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum WorkflowInstanceStatus { | ||
| + | |||
| + | RUNNING | ||
| + | |||
| + | WAITING | ||
| + | |||
| + | APPROVED | ||
| + | |||
| + | REJECTED | ||
| + | |||
| + | COMPLETED | ||
| + | |||
| + | CANCELLED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== WorkflowExecution ====== | ||
| + | |||
| + | ===== Historique des étapes ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model WorkflowExecution { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | workflowInstanceId | ||
| + | |||
| + | workflowStepId | ||
| + | |||
| + | executedByUserId | ||
| + | |||
| + | status | ||
| + | |||
| + | comments | ||
| + | |||
| + | executedAt | ||
| + | |||
| + | workflowInstance | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | workflowStep | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | executedByUser | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([workflowInstanceId]) | ||
| + | |||
| + | @@index([workflowStepId]) | ||
| + | |||
| + | @@index([executedAt]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== WorkflowExecutionStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum WorkflowExecutionStatus { | ||
| + | |||
| + | PENDING | ||
| + | |||
| + | APPROVED | ||
| + | |||
| + | REJECTED | ||
| + | |||
| + | SKIPPED | ||
| + | |||
| + | COMPLETED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Relations à ajouter ====== | ||
| + | |||
| + | ===== Tenant ===== | ||
| + | |||
| + | <code prisma> | ||
| + | auditLogs AuditLog[] | ||
| + | |||
| + | entityHistories EntityHistory[] | ||
| + | |||
| + | featureFlags FeatureFlag[] | ||
| + | |||
| + | workflows Workflow[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== User ===== | ||
| + | |||
| + | <code prisma> | ||
| + | auditLogs AuditLog[] | ||
| + | |||
| + | entityHistories EntityHistory[] | ||
| + | |||
| + | workflowExecutions WorkflowExecution[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Cas d' | ||
| + | |||
| + | ===== Réservation ===== | ||
| + | |||
| + | < | ||
| + | Reservation Created | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | AuditLog | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Workflow Instance | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Manager Approval | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Contract Generation | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Paiement ===== | ||
| + | |||
| + | < | ||
| + | Payment Refunded | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | AuditLog | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | History Snapshot | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Compliance Trace | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Administration ===== | ||
| + | |||
| + | < | ||
| + | Feature Enabled | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | AuditLog | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | History | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Reporting | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Validation ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma format | ||
| + | |||
| + | npx prisma validate | ||
| + | |||
| + | npx prisma generate | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Migration ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma migrate dev \ | ||
| + | --name administration_audit_governance | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Fonctionnalités couvertes ====== | ||
| + | |||
| + | ===== Administration ===== | ||
| + | |||
| + | < | ||
| + | Feature Flags | ||
| + | |||
| + | Workflows | ||
| + | |||
| + | Validation | ||
| + | |||
| + | Approbation | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Audit ===== | ||
| + | |||
| + | < | ||
| + | Journalisation | ||
| + | |||
| + | Traçabilité | ||
| + | |||
| + | Historisation | ||
| + | |||
| + | Conformité | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Gouvernance ===== | ||
| + | |||
| + | < | ||
| + | Contrôle | ||
| + | |||
| + | Supervision | ||
| + | |||
| + | Rétention | ||
| + | |||
| + | Preuve d' | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== État du schéma ====== | ||
| + | |||
| + | Après Phase 2-I : | ||
| + | |||
| + | < | ||
| + | ≈ 74 modèles Prisma | ||
| + | </ | ||
| + | |||
| + | avec les domaines : | ||
| + | |||
| + | < | ||
| + | Core | ||
| + | |||
| + | Security | ||
| + | |||
| + | Properties | ||
| + | |||
| + | Owners | ||
| + | |||
| + | Customers | ||
| + | |||
| + | Reservations | ||
| + | |||
| + | Contracts | ||
| + | |||
| + | Payments | ||
| + | |||
| + | CRM | ||
| + | |||
| + | Messaging | ||
| + | |||
| + | Marketing | ||
| + | |||
| + | Automation | ||
| + | |||
| + | Governance | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Phase 2-J — OTA & Channel Manager ====== | ||
| + | |||
| + | ===== Objectif ===== | ||
| + | |||
| + | Construire le moteur de distribution multicanal de la plateforme. | ||
| + | |||
| + | Ce domaine permettra : | ||
| + | |||
| + | * Synchronisation Airbnb | ||
| + | * Synchronisation Booking.com | ||
| + | * Synchronisation Vrbo | ||
| + | * Synchronisation Abritel | ||
| + | * Publication automatique des biens | ||
| + | * Synchronisation des disponibilités | ||
| + | * Synchronisation des tarifs | ||
| + | * Synchronisation des réservations | ||
| + | * Gestion des erreurs de synchronisation | ||
| + | |||
| + | Cette phase couvre : | ||
| + | |||
| + | < | ||
| + | Sprint 12 — OTA & Distribution | ||
| + | |||
| + | Sprint 14 — API & Partenaires | ||
| + | |||
| + | Sprint 18 — Channel Manager Enterprise | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Architecture ====== | ||
| + | |||
| + | ===== Modèles ===== | ||
| + | |||
| + | < | ||
| + | Channel | ||
| + | |||
| + | ChannelConnection | ||
| + | |||
| + | PropertyDistribution | ||
| + | |||
| + | ChannelReservation | ||
| + | |||
| + | SyncExecution | ||
| + | |||
| + | SyncError | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Channel ====== | ||
| + | |||
| + | ===== Catalogue OTA ===== | ||
| + | |||
| + | Référentiel des plateformes connectables. | ||
| + | |||
| + | <code prisma> | ||
| + | model Channel { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | code String @unique | ||
| + | |||
| + | name String | ||
| + | |||
| + | channelType | ||
| + | |||
| + | active | ||
| + | |||
| + | apiDocumentationUrl | ||
| + | |||
| + | logoUrl | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | connections | ||
| + | |||
| + | distributions | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== ChannelType ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum ChannelType { | ||
| + | |||
| + | OTA | ||
| + | |||
| + | DIRECT | ||
| + | |||
| + | PARTNER | ||
| + | |||
| + | API | ||
| + | |||
| + | MARKETPLACE | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Valeurs initiales ===== | ||
| + | |||
| + | < | ||
| + | AIRBNB | ||
| + | |||
| + | BOOKING | ||
| + | |||
| + | VRBO | ||
| + | |||
| + | ABRITEL | ||
| + | |||
| + | EXPEDIA | ||
| + | |||
| + | DIRECT_WEBSITE | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== ChannelConnection ====== | ||
| + | |||
| + | ===== Connexion OTA ===== | ||
| + | |||
| + | Une agence peut posséder plusieurs connexions. | ||
| + | |||
| + | <code prisma> | ||
| + | model ChannelConnection { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | channelId | ||
| + | |||
| + | connectionName | ||
| + | |||
| + | accountIdentifier | ||
| + | |||
| + | apiKey | ||
| + | |||
| + | apiSecret | ||
| + | |||
| + | refreshToken | ||
| + | |||
| + | configuration | ||
| + | |||
| + | active | ||
| + | |||
| + | lastSyncAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | channel | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | propertyDistributions PropertyDistribution[] | ||
| + | |||
| + | syncExecutions | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([channelId]) | ||
| + | |||
| + | @@index([active]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== PropertyDistribution ====== | ||
| + | |||
| + | ===== Publication d'un bien ===== | ||
| + | |||
| + | Permet d' | ||
| + | |||
| + | <code prisma> | ||
| + | model PropertyDistribution { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | propertyId | ||
| + | |||
| + | channelId | ||
| + | |||
| + | channelConnectionId | ||
| + | |||
| + | externalPropertyId | ||
| + | |||
| + | externalListingId | ||
| + | |||
| + | published | ||
| + | |||
| + | publicationStatus | ||
| + | |||
| + | publishedAt | ||
| + | |||
| + | lastSyncAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | property | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | channel | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | channelConnection | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | reservations | ||
| + | |||
| + | @@unique([ | ||
| + | propertyId, | ||
| + | channelConnectionId | ||
| + | ]) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([propertyId]) | ||
| + | |||
| + | @@index([channelId]) | ||
| + | |||
| + | @@index([publicationStatus]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== DistributionStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum DistributionStatus { | ||
| + | |||
| + | DRAFT | ||
| + | |||
| + | PENDING | ||
| + | |||
| + | PUBLISHED | ||
| + | |||
| + | SUSPENDED | ||
| + | |||
| + | ERROR | ||
| + | |||
| + | ARCHIVED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== 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 | ||
| + | |||
| + | reservationId | ||
| + | |||
| + | propertyDistributionId String | ||
| + | |||
| + | externalReservationId String | ||
| + | |||
| + | externalStatus | ||
| + | |||
| + | importedAt | ||
| + | |||
| + | lastSyncAt | ||
| + | |||
| + | reservation | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | propertyDistribution | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([ | ||
| + | propertyDistributionId, | ||
| + | externalReservationId | ||
| + | ]) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([reservationId]) | ||
| + | |||
| + | @@index([importedAt]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== SyncExecution ====== | ||
| + | |||
| + | ===== Historique des synchronisations ===== | ||
| + | |||
| + | Chaque synchronisation OTA doit être historisée. | ||
| + | |||
| + | <code prisma> | ||
| + | model SyncExecution { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | channelConnectionId | ||
| + | |||
| + | syncType | ||
| + | |||
| + | status | ||
| + | |||
| + | startedAt | ||
| + | |||
| + | completedAt | ||
| + | |||
| + | processedCount | ||
| + | |||
| + | successCount | ||
| + | |||
| + | errorCount | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | channelConnection | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | errors | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([channelConnectionId]) | ||
| + | |||
| + | @@index([syncType]) | ||
| + | |||
| + | @@index([status]) | ||
| + | |||
| + | @@index([startedAt]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== SyncType ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum SyncType { | ||
| + | |||
| + | PROPERTY_EXPORT | ||
| + | |||
| + | AVAILABILITY_EXPORT | ||
| + | |||
| + | RATE_EXPORT | ||
| + | |||
| + | RESERVATION_IMPORT | ||
| + | |||
| + | FULL_SYNC | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== SyncStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum SyncStatus { | ||
| + | |||
| + | PENDING | ||
| + | |||
| + | RUNNING | ||
| + | |||
| + | COMPLETED | ||
| + | |||
| + | PARTIAL_SUCCESS | ||
| + | |||
| + | FAILED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== SyncError ====== | ||
| + | |||
| + | ===== Gestion des erreurs ===== | ||
| + | |||
| + | Permet d' | ||
| + | |||
| + | <code prisma> | ||
| + | model SyncError { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | syncExecutionId | ||
| + | |||
| + | errorCode | ||
| + | |||
| + | errorMessage | ||
| + | |||
| + | entityType | ||
| + | |||
| + | entityId | ||
| + | |||
| + | payload | ||
| + | |||
| + | occurredAt | ||
| + | |||
| + | syncExecution | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([syncExecutionId]) | ||
| + | |||
| + | @@index([errorCode]) | ||
| + | |||
| + | @@index([occurredAt]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Relations à ajouter ====== | ||
| + | |||
| + | ===== Tenant ===== | ||
| + | |||
| + | <code prisma> | ||
| + | channelConnections ChannelConnection[] | ||
| + | |||
| + | propertyDistributions PropertyDistribution[] | ||
| + | |||
| + | channelReservations ChannelReservation[] | ||
| + | |||
| + | syncExecutions SyncExecution[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Property ===== | ||
| + | |||
| + | <code prisma> | ||
| + | propertyDistributions PropertyDistribution[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Reservation ===== | ||
| + | |||
| + | <code prisma> | ||
| + | channelReservations ChannelReservation[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Synchronisations couvertes ====== | ||
| + | |||
| + | ===== Disponibilités ===== | ||
| + | |||
| + | < | ||
| + | PropertyAvailability | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | OTA | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Tarifs ===== | ||
| + | |||
| + | < | ||
| + | PropertyRate | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | OTA | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Réservations ===== | ||
| + | |||
| + | < | ||
| + | OTA | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | ChannelReservation | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Reservation | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Publication ===== | ||
| + | |||
| + | < | ||
| + | Property | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | PropertyDistribution | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Airbnb | ||
| + | |||
| + | Booking | ||
| + | |||
| + | Vrbo | ||
| + | |||
| + | Abritel | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Validation ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma format | ||
| + | |||
| + | npx prisma validate | ||
| + | |||
| + | npx prisma generate | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Migration ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma migrate dev \ | ||
| + | --name ota_channel_manager | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Fonctionnalités couvertes ====== | ||
| + | |||
| + | ===== Sprint 12 ===== | ||
| + | |||
| + | < | ||
| + | Publication OTA | ||
| + | |||
| + | Synchronisation calendrier | ||
| + | |||
| + | Synchronisation tarifs | ||
| + | |||
| + | Import réservations | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Sprint 14 ===== | ||
| + | |||
| + | < | ||
| + | Partenaires | ||
| + | |||
| + | API externes | ||
| + | |||
| + | Marketplace | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Sprint 18 ===== | ||
| + | |||
| + | < | ||
| + | Channel Manager Enterprise | ||
| + | |||
| + | Multi-OTA | ||
| + | |||
| + | Monitoring synchronisations | ||
| + | |||
| + | Gestion erreurs | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== État du schéma ====== | ||
| + | |||
| + | Après Phase 2-J : | ||
| + | |||
| + | < | ||
| + | ≈ 80 modèles Prisma | ||
| + | </ | ||
| + | |||
| + | avec les domaines : | ||
| + | |||
| + | < | ||
| + | Core | ||
| + | |||
| + | Security | ||
| + | |||
| + | Properties | ||
| + | |||
| + | Owners | ||
| + | |||
| + | Customers | ||
| + | |||
| + | Reservations | ||
| + | |||
| + | Contracts | ||
| + | |||
| + | Payments | ||
| + | |||
| + | CRM | ||
| + | |||
| + | Messaging | ||
| + | |||
| + | Marketing | ||
| + | |||
| + | Automation | ||
| + | |||
| + | Governance | ||
| + | |||
| + | OTA | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== 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 : | ||
| + | |||
| + | < | ||
| + | Sprint 10 — Reporting | ||
| + | |||
| + | Sprint 13 — IA & Prévisions | ||
| + | |||
| + | Sprint 17 — Revenue Management | ||
| + | |||
| + | Sprint 20 — Enterprise Analytics | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Architecture ====== | ||
| + | |||
| + | ===== Modèles ===== | ||
| + | |||
| + | < | ||
| + | PricingRule | ||
| + | |||
| + | DynamicPrice | ||
| + | |||
| + | RevenueForecast | ||
| + | |||
| + | RevenueSimulation | ||
| + | |||
| + | CompetitorSnapshot | ||
| + | |||
| + | MarketDemand | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== PricingRule ====== | ||
| + | |||
| + | ===== Règle tarifaire ===== | ||
| + | |||
| + | Définit les règles d' | ||
| + | |||
| + | <code prisma> | ||
| + | model PricingRule { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | propertyId | ||
| + | |||
| + | code String | ||
| + | |||
| + | name String | ||
| + | |||
| + | description | ||
| + | |||
| + | priority | ||
| + | |||
| + | active | ||
| + | |||
| + | conditions | ||
| + | |||
| + | actions | ||
| + | |||
| + | validFrom | ||
| + | |||
| + | validTo | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | property | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([tenantId, | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([propertyId]) | ||
| + | |||
| + | @@index([active]) | ||
| + | |||
| + | @@index([priority]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | Occupation > 80% | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | +15% | ||
| + | |||
| + | ---------------- | ||
| + | |||
| + | Weekend | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | +10% | ||
| + | |||
| + | ---------------- | ||
| + | |||
| + | Haute saison | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | +25% | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== DynamicPrice ====== | ||
| + | |||
| + | ===== Prix calculé ===== | ||
| + | |||
| + | Prix final appliqué à une date donnée. | ||
| + | |||
| + | <code prisma> | ||
| + | model DynamicPrice { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | propertyId | ||
| + | |||
| + | pricingDate | ||
| + | |||
| + | basePrice | ||
| + | |||
| + | adjustedPrice | ||
| + | |||
| + | occupancyFactor | ||
| + | |||
| + | seasonalityFactor | ||
| + | |||
| + | demandFactor | ||
| + | |||
| + | competitorFactor | ||
| + | |||
| + | generatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | property | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([ | ||
| + | propertyId, | ||
| + | pricingDate | ||
| + | ]) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([propertyId]) | ||
| + | |||
| + | @@index([pricingDate]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== RevenueForecast ====== | ||
| + | |||
| + | ===== Prévisions ===== | ||
| + | |||
| + | Prévision de revenus futurs. | ||
| + | |||
| + | <code prisma> | ||
| + | model RevenueForecast { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | propertyId | ||
| + | |||
| + | forecastDate | ||
| + | |||
| + | forecastPeriodStart | ||
| + | |||
| + | forecastPeriodEnd | ||
| + | |||
| + | expectedRevenue | ||
| + | |||
| + | expectedOccupancy | ||
| + | |||
| + | confidenceLevel | ||
| + | |||
| + | modelVersion | ||
| + | |||
| + | generatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | property | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([propertyId]) | ||
| + | |||
| + | @@index([forecastDate]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== RevenueSimulation ====== | ||
| + | |||
| + | ===== Simulation ===== | ||
| + | |||
| + | Analyse de scénarios. | ||
| + | |||
| + | <code prisma> | ||
| + | model RevenueSimulation { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | propertyId | ||
| + | |||
| + | name String | ||
| + | |||
| + | assumptions | ||
| + | |||
| + | projectedRevenue | ||
| + | |||
| + | projectedOccupancy | ||
| + | |||
| + | createdByUserId | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | property | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | createdByUser | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([propertyId]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemple ===== | ||
| + | |||
| + | < | ||
| + | Prix +10% | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Occupation -3% | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | CA +6% | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== CompetitorSnapshot ====== | ||
| + | |||
| + | ===== Veille concurrentielle ===== | ||
| + | |||
| + | Capture des prix concurrents. | ||
| + | |||
| + | <code prisma> | ||
| + | model CompetitorSnapshot { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | propertyId | ||
| + | |||
| + | competitorName | ||
| + | |||
| + | competitorPropertyId | ||
| + | |||
| + | snapshotDate | ||
| + | |||
| + | nightlyRate | ||
| + | |||
| + | occupancy | ||
| + | |||
| + | source | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | property | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([propertyId]) | ||
| + | |||
| + | @@index([snapshotDate]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== MarketDemand ====== | ||
| + | |||
| + | ===== Indicateurs marché ===== | ||
| + | |||
| + | Mesure de la demande. | ||
| + | |||
| + | <code prisma> | ||
| + | model MarketDemand { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | regionCode | ||
| + | |||
| + | demandDate | ||
| + | |||
| + | demandIndex | ||
| + | |||
| + | occupancyIndex | ||
| + | |||
| + | averageDailyRate | ||
| + | |||
| + | source | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([regionCode]) | ||
| + | |||
| + | @@index([demandDate]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Relations à ajouter ====== | ||
| + | |||
| + | ===== Property ===== | ||
| + | |||
| + | <code prisma> | ||
| + | pricingRules PricingRule[] | ||
| + | |||
| + | dynamicPrices DynamicPrice[] | ||
| + | |||
| + | revenueForecasts RevenueForecast[] | ||
| + | |||
| + | revenueSimulations RevenueSimulation[] | ||
| + | |||
| + | competitorSnapshots CompetitorSnapshot[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Tenant ===== | ||
| + | |||
| + | <code prisma> | ||
| + | pricingRules PricingRule[] | ||
| + | |||
| + | dynamicPrices DynamicPrice[] | ||
| + | |||
| + | revenueForecasts RevenueForecast[] | ||
| + | |||
| + | revenueSimulations RevenueSimulation[] | ||
| + | |||
| + | marketDemands MarketDemand[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Cas d' | ||
| + | |||
| + | ===== Tarification dynamique ===== | ||
| + | |||
| + | < | ||
| + | Occupation | ||
| + | |||
| + | + | ||
| + | |||
| + | Saisonnalité | ||
| + | |||
| + | + | ||
| + | |||
| + | Concurrence | ||
| + | |||
| + | + | ||
| + | |||
| + | Demande | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Prix optimal | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Prévision ===== | ||
| + | |||
| + | < | ||
| + | Historique réservations | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Forecast IA | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Revenus prévus | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Simulation ===== | ||
| + | |||
| + | < | ||
| + | Nouveau tarif | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Simulation | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Impact CA | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Validation ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma format | ||
| + | |||
| + | npx prisma validate | ||
| + | |||
| + | npx prisma generate | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Migration ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma migrate dev \ | ||
| + | --name revenue_management | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Fonctionnalités couvertes ====== | ||
| + | |||
| + | ===== Revenue Management ===== | ||
| + | |||
| + | < | ||
| + | Yield Management | ||
| + | |||
| + | Dynamic Pricing | ||
| + | |||
| + | Optimisation tarifaire | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Analytics ===== | ||
| + | |||
| + | < | ||
| + | Forecast | ||
| + | |||
| + | Simulation | ||
| + | |||
| + | Benchmark concurrence | ||
| + | |||
| + | Demand Analytics | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== IA ===== | ||
| + | |||
| + | < | ||
| + | Aide à la décision | ||
| + | |||
| + | Prévisions | ||
| + | |||
| + | Recommandations | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== État du schéma ====== | ||
| + | |||
| + | Après Phase 2-K : | ||
| + | |||
| + | < | ||
| + | ≈ 86 modèles Prisma | ||
| + | </ | ||
| + | |||
| + | avec les domaines : | ||
| + | |||
| + | < | ||
| + | Core | ||
| + | |||
| + | Security | ||
| + | |||
| + | Properties | ||
| + | |||
| + | Owners | ||
| + | |||
| + | Customers | ||
| + | |||
| + | Reservations | ||
| + | |||
| + | Contracts | ||
| + | |||
| + | Payments | ||
| + | |||
| + | CRM | ||
| + | |||
| + | Messaging | ||
| + | |||
| + | Marketing | ||
| + | |||
| + | Automation | ||
| + | |||
| + | Governance | ||
| + | |||
| + | OTA | ||
| + | |||
| + | Revenue Management | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== 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 : | ||
| + | |||
| + | < | ||
| + | Sprint 19 | ||
| + | |||
| + | Governance | ||
| + | |||
| + | Compliance | ||
| + | |||
| + | Enterprise Security | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Architecture ====== | ||
| + | |||
| + | ===== Modèles ===== | ||
| + | |||
| + | < | ||
| + | Consent | ||
| + | |||
| + | SecurityPolicy | ||
| + | |||
| + | Risk | ||
| + | |||
| + | ComplianceAudit | ||
| + | |||
| + | SecurityIncident | ||
| + | |||
| + | DataClassification | ||
| + | |||
| + | RetentionPolicy | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Consent ====== | ||
| + | |||
| + | ===== Gestion des consentements ===== | ||
| + | |||
| + | Traçabilité complète des consentements utilisateurs. | ||
| + | |||
| + | <code prisma> | ||
| + | model Consent { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | customerId | ||
| + | |||
| + | userId | ||
| + | |||
| + | consentType | ||
| + | |||
| + | granted | ||
| + | |||
| + | version | ||
| + | |||
| + | source | ||
| + | |||
| + | ipAddress | ||
| + | |||
| + | userAgent | ||
| + | |||
| + | grantedAt | ||
| + | |||
| + | revokedAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | customer | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | user User? @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([customerId]) | ||
| + | |||
| + | @@index([userId]) | ||
| + | |||
| + | @@index([consentType]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== ConsentType ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum ConsentType { | ||
| + | |||
| + | GDPR | ||
| + | |||
| + | COOKIES | ||
| + | |||
| + | MARKETING_EMAIL | ||
| + | |||
| + | MARKETING_SMS | ||
| + | |||
| + | PROFILING | ||
| + | |||
| + | THIRD_PARTY_SHARING | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== SecurityPolicy ====== | ||
| + | |||
| + | ===== Politiques de sécurité ===== | ||
| + | |||
| + | Configuration centralisée. | ||
| + | |||
| + | <code prisma> | ||
| + | model SecurityPolicy { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String @unique | ||
| + | |||
| + | name String | ||
| + | |||
| + | description | ||
| + | |||
| + | configuration | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([active]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | PASSWORD_POLICY | ||
| + | |||
| + | SESSION_POLICY | ||
| + | |||
| + | MFA_POLICY | ||
| + | |||
| + | RETENTION_POLICY | ||
| + | |||
| + | ACCESS_CONTROL_POLICY | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Risk ====== | ||
| + | |||
| + | ===== Registre des risques ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Risk { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String | ||
| + | |||
| + | title | ||
| + | |||
| + | description | ||
| + | |||
| + | category | ||
| + | |||
| + | probability | ||
| + | |||
| + | impact | ||
| + | |||
| + | score Int | ||
| + | |||
| + | mitigationPlan | ||
| + | |||
| + | ownerUserId | ||
| + | |||
| + | status | ||
| + | |||
| + | identifiedAt | ||
| + | |||
| + | reviewedAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | ownerUser | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([tenantId, | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | |||
| + | @@index([score]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== RiskCategory ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum RiskCategory { | ||
| + | |||
| + | SECURITY | ||
| + | |||
| + | COMPLIANCE | ||
| + | |||
| + | OPERATIONAL | ||
| + | |||
| + | FINANCIAL | ||
| + | |||
| + | LEGAL | ||
| + | |||
| + | TECHNICAL | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== RiskStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum RiskStatus { | ||
| + | |||
| + | IDENTIFIED | ||
| + | |||
| + | ASSESSED | ||
| + | |||
| + | MITIGATED | ||
| + | |||
| + | ACCEPTED | ||
| + | |||
| + | CLOSED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== ComplianceAudit ====== | ||
| + | |||
| + | ===== Audits réglementaires ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model ComplianceAudit { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | auditType | ||
| + | |||
| + | scope | ||
| + | |||
| + | status | ||
| + | |||
| + | auditor | ||
| + | |||
| + | findings | ||
| + | |||
| + | recommendations | ||
| + | |||
| + | startedAt | ||
| + | |||
| + | completedAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([auditType]) | ||
| + | |||
| + | @@index([status]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== ComplianceAuditType ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum ComplianceAuditType { | ||
| + | |||
| + | GDPR | ||
| + | |||
| + | ISO27001 | ||
| + | |||
| + | SOC2 | ||
| + | |||
| + | NIS2 | ||
| + | |||
| + | INTERNAL | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== ComplianceAuditStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum ComplianceAuditStatus { | ||
| + | |||
| + | PLANNED | ||
| + | |||
| + | RUNNING | ||
| + | |||
| + | COMPLETED | ||
| + | |||
| + | CLOSED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== SecurityIncident ====== | ||
| + | |||
| + | ===== Gestion des incidents ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model SecurityIncident { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String | ||
| + | |||
| + | title | ||
| + | |||
| + | description | ||
| + | |||
| + | severity | ||
| + | |||
| + | status | ||
| + | |||
| + | detectedAt | ||
| + | |||
| + | resolvedAt | ||
| + | |||
| + | reportedByUserId | ||
| + | |||
| + | rootCause | ||
| + | |||
| + | correctiveActions | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | reportedByUser | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([tenantId, | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([severity]) | ||
| + | |||
| + | @@index([status]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== IncidentSeverity ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum IncidentSeverity { | ||
| + | |||
| + | LOW | ||
| + | |||
| + | MEDIUM | ||
| + | |||
| + | HIGH | ||
| + | |||
| + | CRITICAL | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== IncidentStatus ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum IncidentStatus { | ||
| + | |||
| + | OPEN | ||
| + | |||
| + | INVESTIGATING | ||
| + | |||
| + | MITIGATED | ||
| + | |||
| + | RESOLVED | ||
| + | |||
| + | CLOSED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== DataClassification ====== | ||
| + | |||
| + | ===== Classification des données ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model DataClassification { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | code String @unique | ||
| + | |||
| + | name String | ||
| + | |||
| + | description | ||
| + | |||
| + | level | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== ClassificationLevel ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum ClassificationLevel { | ||
| + | |||
| + | PUBLIC | ||
| + | |||
| + | INTERNAL | ||
| + | |||
| + | CONFIDENTIAL | ||
| + | |||
| + | RESTRICTED | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | Client | ||
| + | |||
| + | → CONFIDENTIAL | ||
| + | |||
| + | ---------------- | ||
| + | |||
| + | Paiement | ||
| + | |||
| + | → RESTRICTED | ||
| + | |||
| + | ---------------- | ||
| + | |||
| + | Catalogue public | ||
| + | |||
| + | → PUBLIC | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== RetentionPolicy ====== | ||
| + | |||
| + | ===== Politique de conservation ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model RetentionPolicy { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String @unique | ||
| + | |||
| + | entityType | ||
| + | |||
| + | retentionDays | ||
| + | |||
| + | archiveBeforeDelete | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([entityType]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | AuditLog | ||
| + | |||
| + | 3650 jours | ||
| + | |||
| + | ---------------- | ||
| + | |||
| + | LoginHistory | ||
| + | |||
| + | 365 jours | ||
| + | |||
| + | ---------------- | ||
| + | |||
| + | MarketingEvent | ||
| + | |||
| + | 1095 jours | ||
| + | |||
| + | ---------------- | ||
| + | |||
| + | Consent | ||
| + | |||
| + | 1825 jours | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Relations à ajouter ====== | ||
| + | |||
| + | ===== Tenant ===== | ||
| + | |||
| + | <code prisma> | ||
| + | consents Consent[] | ||
| + | |||
| + | securityPolicies SecurityPolicy[] | ||
| + | |||
| + | risks Risk[] | ||
| + | |||
| + | complianceAudits ComplianceAudit[] | ||
| + | |||
| + | securityIncidents SecurityIncident[] | ||
| + | |||
| + | retentionPolicies RetentionPolicy[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== User ===== | ||
| + | |||
| + | <code prisma> | ||
| + | consents Consent[] | ||
| + | |||
| + | ownedRisks Risk[] | ||
| + | |||
| + | reportedIncidents SecurityIncident[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Customer ===== | ||
| + | |||
| + | <code prisma> | ||
| + | consents Consent[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Validation ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma format | ||
| + | |||
| + | npx prisma validate | ||
| + | |||
| + | npx prisma generate | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Migration ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma migrate dev \ | ||
| + | --name enterprise_security_compliance | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Fonctionnalités couvertes ====== | ||
| + | |||
| + | ===== RGPD ===== | ||
| + | |||
| + | < | ||
| + | Consentements | ||
| + | |||
| + | Traçabilité | ||
| + | |||
| + | Conservation | ||
| + | |||
| + | Export | ||
| + | |||
| + | Suppression | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Sécurité ===== | ||
| + | |||
| + | < | ||
| + | Politiques | ||
| + | |||
| + | Incidents | ||
| + | |||
| + | MFA | ||
| + | |||
| + | Gestion des risques | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Gouvernance ===== | ||
| + | |||
| + | < | ||
| + | Classification | ||
| + | |||
| + | Rétention | ||
| + | |||
| + | Audit | ||
| + | |||
| + | Conformité | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== État du schéma ====== | ||
| + | |||
| + | Après Phase 2-L : | ||
| + | |||
| + | < | ||
| + | ≈ 93 modèles Prisma | ||
| + | </ | ||
| + | |||
| + | avec les domaines : | ||
| + | |||
| + | < | ||
| + | Core | ||
| + | |||
| + | Security | ||
| + | |||
| + | Properties | ||
| + | |||
| + | Owners | ||
| + | |||
| + | Customers | ||
| + | |||
| + | Reservations | ||
| + | |||
| + | Contracts | ||
| + | |||
| + | Payments | ||
| + | |||
| + | CRM | ||
| + | |||
| + | Messaging | ||
| + | |||
| + | Marketing | ||
| + | |||
| + | Automation | ||
| + | |||
| + | Governance | ||
| + | |||
| + | OTA | ||
| + | |||
| + | Revenue Management | ||
| + | |||
| + | Enterprise Security | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== 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' | ||
| + | * Plusieurs marques | ||
| + | * Plusieurs réseaux d' | ||
| + | * Plusieurs juridictions | ||
| + | |||
| + | Cette phase couvre : | ||
| + | |||
| + | < | ||
| + | Sprint 15 — Réseau d' | ||
| + | |||
| + | Sprint 20 — Internationalisation | ||
| + | |||
| + | Enterprise SaaS | ||
| + | |||
| + | Commercialisation internationale | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Architecture ====== | ||
| + | |||
| + | ===== Modèles ===== | ||
| + | |||
| + | < | ||
| + | Country | ||
| + | |||
| + | Currency | ||
| + | |||
| + | Language | ||
| + | |||
| + | Timezone | ||
| + | |||
| + | CurrencyRate | ||
| + | |||
| + | Translation | ||
| + | |||
| + | Region | ||
| + | |||
| + | EnterpriseLicense | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Country ====== | ||
| + | |||
| + | ===== Référentiel pays ===== | ||
| + | |||
| + | Norme ISO 3166. | ||
| + | |||
| + | <code prisma> | ||
| + | model Country { | ||
| + | |||
| + | code String @id | ||
| + | |||
| + | iso3 String @unique | ||
| + | |||
| + | name String | ||
| + | |||
| + | nativeName | ||
| + | |||
| + | phonePrefix | ||
| + | |||
| + | euMember | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | regions | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | FR | ||
| + | |||
| + | BE | ||
| + | |||
| + | CH | ||
| + | |||
| + | ES | ||
| + | |||
| + | IT | ||
| + | |||
| + | DE | ||
| + | |||
| + | UK | ||
| + | |||
| + | US | ||
| + | |||
| + | CA | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Currency ====== | ||
| + | |||
| + | ===== Référentiel devises ===== | ||
| + | |||
| + | Norme ISO 4217. | ||
| + | |||
| + | <code prisma> | ||
| + | model Currency { | ||
| + | |||
| + | code String @id | ||
| + | |||
| + | numericCode | ||
| + | |||
| + | name String | ||
| + | |||
| + | symbol | ||
| + | |||
| + | decimalPlaces | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | rates | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | EUR | ||
| + | |||
| + | USD | ||
| + | |||
| + | GBP | ||
| + | |||
| + | CHF | ||
| + | |||
| + | CAD | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Language ====== | ||
| + | |||
| + | ===== Référentiel langues ===== | ||
| + | |||
| + | Norme ISO 639. | ||
| + | |||
| + | <code prisma> | ||
| + | model Language { | ||
| + | |||
| + | code String @id | ||
| + | |||
| + | name String | ||
| + | |||
| + | nativeName | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | translations | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | fr | ||
| + | |||
| + | en | ||
| + | |||
| + | de | ||
| + | |||
| + | es | ||
| + | |||
| + | it | ||
| + | |||
| + | nl | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Timezone ====== | ||
| + | |||
| + | ===== Fuseaux horaires ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Timezone { | ||
| + | |||
| + | id String @id | ||
| + | |||
| + | displayName | ||
| + | |||
| + | utcOffset | ||
| + | |||
| + | active | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | Europe/ | ||
| + | |||
| + | Europe/ | ||
| + | |||
| + | America/ | ||
| + | |||
| + | America/ | ||
| + | |||
| + | Asia/ | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== CurrencyRate ====== | ||
| + | |||
| + | ===== Taux de change ===== | ||
| + | |||
| + | Historisation des taux. | ||
| + | |||
| + | <code prisma> | ||
| + | model CurrencyRate { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | fromCurrencyCode | ||
| + | |||
| + | toCurrencyCode | ||
| + | |||
| + | rate Decimal @db.Decimal(18, | ||
| + | |||
| + | rateDate | ||
| + | |||
| + | source | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | fromCurrency | ||
| + | @relation( | ||
| + | " | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | toCurrency | ||
| + | @relation( | ||
| + | " | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([ | ||
| + | fromCurrencyCode, | ||
| + | toCurrencyCode, | ||
| + | rateDate | ||
| + | ]) | ||
| + | |||
| + | @@index([rateDate]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Translation ====== | ||
| + | |||
| + | ===== Traductions ===== | ||
| + | |||
| + | Permet l' | ||
| + | |||
| + | <code prisma> | ||
| + | model Translation { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | languageCode | ||
| + | |||
| + | namespace | ||
| + | |||
| + | translationKey | ||
| + | |||
| + | translationValue | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | language | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([ | ||
| + | languageCode, | ||
| + | namespace, | ||
| + | translationKey | ||
| + | ]) | ||
| + | |||
| + | @@index([namespace]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | property.title | ||
| + | |||
| + | reservation.confirm | ||
| + | |||
| + | payment.invoice | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Region ====== | ||
| + | |||
| + | ===== Régions d' | ||
| + | |||
| + | Permet la gestion géographique. | ||
| + | |||
| + | <code prisma> | ||
| + | model Region { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | countryCode | ||
| + | |||
| + | code String | ||
| + | |||
| + | name String | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | country | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([ | ||
| + | countryCode, | ||
| + | code | ||
| + | ]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | FR_OCCITANIE | ||
| + | |||
| + | FR_PACA | ||
| + | |||
| + | FR_IDF | ||
| + | |||
| + | ES_CATALUNYA | ||
| + | |||
| + | US_FLORIDA | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== EnterpriseLicense ====== | ||
| + | |||
| + | ===== Licence SaaS Enterprise ===== | ||
| + | |||
| + | Gestion des déploiements internationaux. | ||
| + | |||
| + | <code prisma> | ||
| + | model EnterpriseLicense { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | licenseKey | ||
| + | |||
| + | edition | ||
| + | |||
| + | maxUsers | ||
| + | |||
| + | maxProperties | ||
| + | |||
| + | maxAgencies | ||
| + | |||
| + | validFrom | ||
| + | |||
| + | validTo | ||
| + | |||
| + | active | ||
| + | |||
| + | features | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([active]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== EnterpriseEdition ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum EnterpriseEdition { | ||
| + | |||
| + | COMMUNITY | ||
| + | |||
| + | PROFESSIONAL | ||
| + | |||
| + | BUSINESS | ||
| + | |||
| + | ENTERPRISE | ||
| + | |||
| + | ENTERPRISE_PLUS | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Évolutions du modèle Tenant ====== | ||
| + | |||
| + | ===== Tenant ===== | ||
| + | |||
| + | Ajouter : | ||
| + | |||
| + | <code prisma> | ||
| + | countryCode String? | ||
| + | |||
| + | currencyCode String? | ||
| + | |||
| + | languageCode String? | ||
| + | |||
| + | timezoneId String? | ||
| + | |||
| + | enterpriseLicense EnterpriseLicense? | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Relations ===== | ||
| + | |||
| + | <code prisma> | ||
| + | country Country? | ||
| + | |||
| + | currency Currency? | ||
| + | |||
| + | language Language? | ||
| + | |||
| + | timezone Timezone? | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Évolutions du modèle Property ====== | ||
| + | |||
| + | ===== Property ===== | ||
| + | |||
| + | Ajouter : | ||
| + | |||
| + | <code prisma> | ||
| + | currencyCode String? | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Relation ===== | ||
| + | |||
| + | <code prisma> | ||
| + | currency Currency? | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Évolutions du modèle Reservation ====== | ||
| + | |||
| + | ===== Reservation ===== | ||
| + | |||
| + | Ajouter : | ||
| + | |||
| + | <code prisma> | ||
| + | currencyCode String? | ||
| + | exchangeRate Decimal? | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Cas d' | ||
| + | |||
| + | ===== Multi-langues ===== | ||
| + | |||
| + | < | ||
| + | FR | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | EN | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | DE | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | ES | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Multi-devises ===== | ||
| + | |||
| + | < | ||
| + | EUR | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | USD | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | GBP | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | CHF | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Multi-régions ===== | ||
| + | |||
| + | < | ||
| + | France | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Occitanie | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Agence | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Biens | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Réseau international ===== | ||
| + | |||
| + | < | ||
| + | Tenant | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Multi-marques | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Multi-pays | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Multi-régions | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Validation ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma format | ||
| + | |||
| + | npx prisma validate | ||
| + | |||
| + | npx prisma generate | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Migration ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma migrate dev \ | ||
| + | --name internationalization_multiregion | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Fonctionnalités couvertes ====== | ||
| + | |||
| + | ===== Internationalisation ===== | ||
| + | |||
| + | < | ||
| + | Multi-langues | ||
| + | |||
| + | Multi-devises | ||
| + | |||
| + | Multi-fuseaux | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Réseau ===== | ||
| + | |||
| + | < | ||
| + | Multi-pays | ||
| + | |||
| + | Multi-régions | ||
| + | |||
| + | Multi-agences | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Enterprise ===== | ||
| + | |||
| + | < | ||
| + | Licensing | ||
| + | |||
| + | Commercialisation | ||
| + | |||
| + | SaaS mondial | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== État du schéma ====== | ||
| + | |||
| + | Après Phase 2-M : | ||
| + | |||
| + | < | ||
| + | ≈ 101 modèles Prisma | ||
| + | </ | ||
| + | |||
| + | avec les domaines : | ||
| + | |||
| + | < | ||
| + | Core | ||
| + | |||
| + | Security | ||
| + | |||
| + | Properties | ||
| + | |||
| + | Owners | ||
| + | |||
| + | Customers | ||
| + | |||
| + | Reservations | ||
| + | |||
| + | Contracts | ||
| + | |||
| + | Payments | ||
| + | |||
| + | CRM | ||
| + | |||
| + | Messaging | ||
| + | |||
| + | Marketing | ||
| + | |||
| + | Automation | ||
| + | |||
| + | Governance | ||
| + | |||
| + | OTA | ||
| + | |||
| + | Revenue Management | ||
| + | |||
| + | Enterprise Security | ||
| + | |||
| + | Internationalization | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== 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' | ||
| + | * Plusieurs marques | ||
| + | * Plusieurs réseaux d' | ||
| + | * Plusieurs juridictions | ||
| + | |||
| + | Cette phase couvre : | ||
| + | |||
| + | < | ||
| + | Sprint 15 — Réseau d' | ||
| + | |||
| + | Sprint 20 — Internationalisation | ||
| + | |||
| + | Enterprise SaaS | ||
| + | |||
| + | Commercialisation internationale | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Architecture ====== | ||
| + | |||
| + | ===== Modèles ===== | ||
| + | |||
| + | < | ||
| + | Country | ||
| + | |||
| + | Currency | ||
| + | |||
| + | Language | ||
| + | |||
| + | Timezone | ||
| + | |||
| + | CurrencyRate | ||
| + | |||
| + | Translation | ||
| + | |||
| + | Region | ||
| + | |||
| + | EnterpriseLicense | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Country ====== | ||
| + | |||
| + | ===== Référentiel pays ===== | ||
| + | |||
| + | Norme ISO 3166. | ||
| + | |||
| + | <code prisma> | ||
| + | model Country { | ||
| + | |||
| + | code String @id | ||
| + | |||
| + | iso3 String @unique | ||
| + | |||
| + | name String | ||
| + | |||
| + | nativeName | ||
| + | |||
| + | phonePrefix | ||
| + | |||
| + | euMember | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | regions | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | FR | ||
| + | |||
| + | BE | ||
| + | |||
| + | CH | ||
| + | |||
| + | ES | ||
| + | |||
| + | IT | ||
| + | |||
| + | DE | ||
| + | |||
| + | UK | ||
| + | |||
| + | US | ||
| + | |||
| + | CA | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Currency ====== | ||
| + | |||
| + | ===== Référentiel devises ===== | ||
| + | |||
| + | Norme ISO 4217. | ||
| + | |||
| + | <code prisma> | ||
| + | model Currency { | ||
| + | |||
| + | code String @id | ||
| + | |||
| + | numericCode | ||
| + | |||
| + | name String | ||
| + | |||
| + | symbol | ||
| + | |||
| + | decimalPlaces | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | rates | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | EUR | ||
| + | |||
| + | USD | ||
| + | |||
| + | GBP | ||
| + | |||
| + | CHF | ||
| + | |||
| + | CAD | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Language ====== | ||
| + | |||
| + | ===== Référentiel langues ===== | ||
| + | |||
| + | Norme ISO 639. | ||
| + | |||
| + | <code prisma> | ||
| + | model Language { | ||
| + | |||
| + | code String @id | ||
| + | |||
| + | name String | ||
| + | |||
| + | nativeName | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | translations | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | fr | ||
| + | |||
| + | en | ||
| + | |||
| + | de | ||
| + | |||
| + | es | ||
| + | |||
| + | it | ||
| + | |||
| + | nl | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Timezone ====== | ||
| + | |||
| + | ===== Fuseaux horaires ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model Timezone { | ||
| + | |||
| + | id String @id | ||
| + | |||
| + | displayName | ||
| + | |||
| + | utcOffset | ||
| + | |||
| + | active | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | Europe/ | ||
| + | |||
| + | Europe/ | ||
| + | |||
| + | America/ | ||
| + | |||
| + | America/ | ||
| + | |||
| + | Asia/ | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== CurrencyRate ====== | ||
| + | |||
| + | ===== Taux de change ===== | ||
| + | |||
| + | Historisation des taux. | ||
| + | |||
| + | <code prisma> | ||
| + | model CurrencyRate { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | fromCurrencyCode | ||
| + | |||
| + | toCurrencyCode | ||
| + | |||
| + | rate Decimal @db.Decimal(18, | ||
| + | |||
| + | rateDate | ||
| + | |||
| + | source | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | fromCurrency | ||
| + | @relation( | ||
| + | " | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | toCurrency | ||
| + | @relation( | ||
| + | " | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([ | ||
| + | fromCurrencyCode, | ||
| + | toCurrencyCode, | ||
| + | rateDate | ||
| + | ]) | ||
| + | |||
| + | @@index([rateDate]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Translation ====== | ||
| + | |||
| + | ===== Traductions ===== | ||
| + | |||
| + | Permet l' | ||
| + | |||
| + | <code prisma> | ||
| + | model Translation { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | languageCode | ||
| + | |||
| + | namespace | ||
| + | |||
| + | translationKey | ||
| + | |||
| + | translationValue | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | language | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([ | ||
| + | languageCode, | ||
| + | namespace, | ||
| + | translationKey | ||
| + | ]) | ||
| + | |||
| + | @@index([namespace]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | property.title | ||
| + | |||
| + | reservation.confirm | ||
| + | |||
| + | payment.invoice | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Region ====== | ||
| + | |||
| + | ===== Régions d' | ||
| + | |||
| + | Permet la gestion géographique. | ||
| + | |||
| + | <code prisma> | ||
| + | model Region { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | countryCode | ||
| + | |||
| + | code String | ||
| + | |||
| + | name String | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | country | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([ | ||
| + | countryCode, | ||
| + | code | ||
| + | ]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | FR_OCCITANIE | ||
| + | |||
| + | FR_PACA | ||
| + | |||
| + | FR_IDF | ||
| + | |||
| + | ES_CATALUNYA | ||
| + | |||
| + | US_FLORIDA | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== EnterpriseLicense ====== | ||
| + | |||
| + | ===== Licence SaaS Enterprise ===== | ||
| + | |||
| + | Gestion des déploiements internationaux. | ||
| + | |||
| + | <code prisma> | ||
| + | model EnterpriseLicense { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | licenseKey | ||
| + | |||
| + | edition | ||
| + | |||
| + | maxUsers | ||
| + | |||
| + | maxProperties | ||
| + | |||
| + | maxAgencies | ||
| + | |||
| + | validFrom | ||
| + | |||
| + | validTo | ||
| + | |||
| + | active | ||
| + | |||
| + | features | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([active]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== EnterpriseEdition ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum EnterpriseEdition { | ||
| + | |||
| + | COMMUNITY | ||
| + | |||
| + | PROFESSIONAL | ||
| + | |||
| + | BUSINESS | ||
| + | |||
| + | ENTERPRISE | ||
| + | |||
| + | ENTERPRISE_PLUS | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Évolutions du modèle Tenant ====== | ||
| + | |||
| + | ===== Tenant ===== | ||
| + | |||
| + | Ajouter : | ||
| + | |||
| + | <code prisma> | ||
| + | countryCode String? | ||
| + | |||
| + | currencyCode String? | ||
| + | |||
| + | languageCode String? | ||
| + | |||
| + | timezoneId String? | ||
| + | |||
| + | enterpriseLicense EnterpriseLicense? | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Relations ===== | ||
| + | |||
| + | <code prisma> | ||
| + | country Country? | ||
| + | |||
| + | currency Currency? | ||
| + | |||
| + | language Language? | ||
| + | |||
| + | timezone Timezone? | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Évolutions du modèle Property ====== | ||
| + | |||
| + | ===== Property ===== | ||
| + | |||
| + | Ajouter : | ||
| + | |||
| + | <code prisma> | ||
| + | currencyCode String? | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Relation ===== | ||
| + | |||
| + | <code prisma> | ||
| + | currency Currency? | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Évolutions du modèle Reservation ====== | ||
| + | |||
| + | ===== Reservation ===== | ||
| + | |||
| + | Ajouter : | ||
| + | |||
| + | <code prisma> | ||
| + | currencyCode String? | ||
| + | exchangeRate Decimal? | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Cas d' | ||
| + | |||
| + | ===== Multi-langues ===== | ||
| + | |||
| + | < | ||
| + | FR | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | EN | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | DE | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | ES | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Multi-devises ===== | ||
| + | |||
| + | < | ||
| + | EUR | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | USD | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | GBP | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | CHF | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Multi-régions ===== | ||
| + | |||
| + | < | ||
| + | France | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Occitanie | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Agence | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Biens | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Réseau international ===== | ||
| + | |||
| + | < | ||
| + | Tenant | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Multi-marques | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Multi-pays | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Multi-régions | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Validation ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma format | ||
| + | |||
| + | npx prisma validate | ||
| + | |||
| + | npx prisma generate | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Migration ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma migrate dev \ | ||
| + | --name internationalization_multiregion | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Fonctionnalités couvertes ====== | ||
| + | |||
| + | ===== Internationalisation ===== | ||
| + | |||
| + | < | ||
| + | Multi-langues | ||
| + | |||
| + | Multi-devises | ||
| + | |||
| + | Multi-fuseaux | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Réseau ===== | ||
| + | |||
| + | < | ||
| + | Multi-pays | ||
| + | |||
| + | Multi-régions | ||
| + | |||
| + | Multi-agences | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Enterprise ===== | ||
| + | |||
| + | < | ||
| + | Licensing | ||
| + | |||
| + | Commercialisation | ||
| + | |||
| + | SaaS mondial | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== État du schéma ====== | ||
| + | |||
| + | Après Phase 2-M : | ||
| + | |||
| + | < | ||
| + | ≈ 101 modèles Prisma | ||
| + | </ | ||
| + | |||
| + | avec les domaines : | ||
| + | |||
| + | < | ||
| + | Core | ||
| + | |||
| + | Security | ||
| + | |||
| + | Properties | ||
| + | |||
| + | Owners | ||
| + | |||
| + | Customers | ||
| + | |||
| + | Reservations | ||
| + | |||
| + | Contracts | ||
| + | |||
| + | Payments | ||
| + | |||
| + | CRM | ||
| + | |||
| + | Messaging | ||
| + | |||
| + | Marketing | ||
| + | |||
| + | Automation | ||
| + | |||
| + | Governance | ||
| + | |||
| + | OTA | ||
| + | |||
| + | Revenue Management | ||
| + | |||
| + | Enterprise Security | ||
| + | |||
| + | Internationalization | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Phase 2-N — IA, Knowledge Base & Automatisation Avancée ====== | ||
| + | |||
| + | ===== Objectif ===== | ||
| + | |||
| + | Construire la couche d' | ||
| + | |||
| + | 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 : | ||
| + | |||
| + | < | ||
| + | Sprint 13 — IA & Automatisation | ||
| + | |||
| + | Sprint 20 — Enterprise Analytics | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Architecture ====== | ||
| + | |||
| + | ===== Modèles ===== | ||
| + | |||
| + | < | ||
| + | AiConversation | ||
| + | |||
| + | AiMessage | ||
| + | |||
| + | KnowledgeDocument | ||
| + | |||
| + | KnowledgeChunk | ||
| + | |||
| + | AutomationScenario | ||
| + | |||
| + | AutomationExecution | ||
| + | |||
| + | Recommendation | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== AiConversation ====== | ||
| + | |||
| + | ===== Conversations IA ===== | ||
| + | |||
| + | Historisation des échanges avec l' | ||
| + | |||
| + | <code prisma> | ||
| + | model AiConversation { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | userId | ||
| + | |||
| + | title | ||
| + | |||
| + | modelName | ||
| + | |||
| + | contextType | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | user User @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | messages | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([userId]) | ||
| + | |||
| + | @@index([createdAt]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | Analyse réservations | ||
| + | |||
| + | Prévision revenus | ||
| + | |||
| + | Recherche client | ||
| + | |||
| + | Analyse contrat | ||
| + | |||
| + | Support utilisateur | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== AiMessage ====== | ||
| + | |||
| + | ===== Messages IA ===== | ||
| + | |||
| + | <code prisma> | ||
| + | model AiMessage { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | conversationId | ||
| + | |||
| + | role AiRole | ||
| + | |||
| + | content | ||
| + | |||
| + | tokenCount | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | conversation | ||
| + | @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([conversationId]) | ||
| + | |||
| + | @@index([createdAt]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== AiRole ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum AiRole { | ||
| + | |||
| + | SYSTEM | ||
| + | |||
| + | USER | ||
| + | |||
| + | ASSISTANT | ||
| + | |||
| + | TOOL | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== KnowledgeDocument ====== | ||
| + | |||
| + | ===== Base documentaire ===== | ||
| + | |||
| + | Documents utilisés par l' | ||
| + | |||
| + | <code prisma> | ||
| + | model KnowledgeDocument { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | documentId | ||
| + | |||
| + | title | ||
| + | |||
| + | sourceType | ||
| + | |||
| + | sourceReference | ||
| + | |||
| + | content | ||
| + | |||
| + | metadata | ||
| + | |||
| + | indexed | ||
| + | |||
| + | indexedAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | document | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | chunks | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([indexed]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== KnowledgeSourceType ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum KnowledgeSourceType { | ||
| + | |||
| + | DOCUMENT | ||
| + | |||
| + | CONTRACT | ||
| + | |||
| + | FAQ | ||
| + | |||
| + | WEBSITE | ||
| + | |||
| + | POLICY | ||
| + | |||
| + | PROCEDURE | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== KnowledgeChunk ====== | ||
| + | |||
| + | ===== Découpage vectoriel ===== | ||
| + | |||
| + | Préparation RAG. | ||
| + | |||
| + | <code prisma> | ||
| + | model KnowledgeChunk { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | knowledgeDocumentId | ||
| + | |||
| + | chunkIndex | ||
| + | |||
| + | content | ||
| + | |||
| + | embeddingId | ||
| + | |||
| + | metadata | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | knowledgeDocument | ||
| + | @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@unique([ | ||
| + | knowledgeDocumentId, | ||
| + | chunkIndex | ||
| + | ]) | ||
| + | |||
| + | @@index([knowledgeDocumentId]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== AutomationScenario ====== | ||
| + | |||
| + | ===== Automatisations avancées ===== | ||
| + | |||
| + | Version métier évoluée de : | ||
| + | |||
| + | < | ||
| + | AutomationRule | ||
| + | </ | ||
| + | |||
| + | <code prisma> | ||
| + | model AutomationScenario { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | code String | ||
| + | |||
| + | name String | ||
| + | |||
| + | description | ||
| + | |||
| + | triggerType | ||
| + | |||
| + | configuration | ||
| + | |||
| + | active | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | updatedAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | executions | ||
| + | |||
| + | @@unique([tenantId, | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([active]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Exemples ===== | ||
| + | |||
| + | < | ||
| + | ReservationConfirmed | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | SendContract | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | CreateTask | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | NotifyOwner | ||
| + | |||
| + | ---------------- | ||
| + | |||
| + | PaymentReceived | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | GenerateInvoice | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | NotifyCustomer | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== AutomationExecution ====== | ||
| + | |||
| + | ===== Historique d' | ||
| + | |||
| + | Extension du modèle existant. | ||
| + | |||
| + | <code prisma> | ||
| + | model AutomationExecution { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | automationScenarioId | ||
| + | |||
| + | automationRuleId | ||
| + | |||
| + | status | ||
| + | |||
| + | entityType | ||
| + | |||
| + | entityId | ||
| + | |||
| + | executionContext | ||
| + | |||
| + | startedAt | ||
| + | |||
| + | completedAt | ||
| + | |||
| + | errorMessage | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | automationScenario | ||
| + | @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | automationRule | ||
| + | @relation( | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([automationScenarioId]) | ||
| + | |||
| + | @@index([automationRuleId]) | ||
| + | |||
| + | @@index([status]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Recommendation ====== | ||
| + | |||
| + | ===== Recommandations IA ===== | ||
| + | |||
| + | Aide à la décision. | ||
| + | |||
| + | <code prisma> | ||
| + | model Recommendation { | ||
| + | |||
| + | id String @id @default(uuid()) | ||
| + | |||
| + | tenantId | ||
| + | |||
| + | entityType | ||
| + | |||
| + | entityId | ||
| + | |||
| + | recommendationType | ||
| + | |||
| + | title | ||
| + | |||
| + | description | ||
| + | |||
| + | confidenceScore | ||
| + | |||
| + | accepted | ||
| + | |||
| + | acceptedAt | ||
| + | |||
| + | createdAt | ||
| + | |||
| + | tenant | ||
| + | fields: | ||
| + | references: | ||
| + | ) | ||
| + | |||
| + | @@index([tenantId]) | ||
| + | |||
| + | @@index([entityType]) | ||
| + | |||
| + | @@index([recommendationType]) | ||
| + | |||
| + | @@index([confidenceScore]) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== RecommendationType ===== | ||
| + | |||
| + | <code prisma> | ||
| + | enum RecommendationType { | ||
| + | |||
| + | PRICE_OPTIMIZATION | ||
| + | |||
| + | CUSTOMER_RETENTION | ||
| + | |||
| + | LEAD_CONVERSION | ||
| + | |||
| + | REVENUE_FORECAST | ||
| + | |||
| + | PROPERTY_IMPROVEMENT | ||
| + | |||
| + | RISK_ALERT | ||
| + | |||
| + | AUTOMATION | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Relations à ajouter ====== | ||
| + | |||
| + | ===== Tenant ===== | ||
| + | |||
| + | <code prisma> | ||
| + | aiConversations AiConversation[] | ||
| + | |||
| + | knowledgeDocuments KnowledgeDocument[] | ||
| + | |||
| + | automationScenarios AutomationScenario[] | ||
| + | |||
| + | recommendations Recommendation[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== User ===== | ||
| + | |||
| + | <code prisma> | ||
| + | aiConversations AiConversation[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Document ===== | ||
| + | |||
| + | <code prisma> | ||
| + | knowledgeDocuments KnowledgeDocument[] | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Cas d' | ||
| + | |||
| + | ===== Assistant Agence ===== | ||
| + | |||
| + | < | ||
| + | "Quels biens sont sous-performants ?" | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Analyse IA | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Recommandations | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Assistant Commercial ===== | ||
| + | |||
| + | < | ||
| + | " | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Scoring | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Liste qualifiée | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Assistant Revenue ===== | ||
| + | |||
| + | < | ||
| + | " | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Forecast | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Recommandations | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Recherche documentaire ===== | ||
| + | |||
| + | < | ||
| + | Question | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | RAG | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | KnowledgeDocument | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | KnowledgeChunk | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Réponse | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Validation ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma format | ||
| + | |||
| + | npx prisma validate | ||
| + | |||
| + | npx prisma generate | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Migration ====== | ||
| + | |||
| + | <code bash> | ||
| + | npx prisma migrate dev \ | ||
| + | --name ai_knowledge_automation | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Fonctionnalités couvertes ====== | ||
| + | |||
| + | ===== IA ===== | ||
| + | |||
| + | < | ||
| + | Assistant conversationnel | ||
| + | |||
| + | Recherche sémantique | ||
| + | |||
| + | Analyse métier | ||
| + | |||
| + | Aide à la décision | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Knowledge Base ===== | ||
| + | |||
| + | < | ||
| + | FAQ | ||
| + | |||
| + | Procédures | ||
| + | |||
| + | Contrats | ||
| + | |||
| + | Documentation | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Automatisation ===== | ||
| + | |||
| + | < | ||
| + | Workflows avancés | ||
| + | |||
| + | Scénarios | ||
| + | |||
| + | Actions automatiques | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== État final du schéma ====== | ||
| + | |||
| + | Après Phase 2-N : | ||
| + | |||
| + | < | ||
| + | ≈ 108 à 112 modèles Prisma | ||
| + | </ | ||
| + | |||
| + | répartis sur : | ||
| + | |||
| + | < | ||
| + | Core | ||
| + | |||
| + | Security | ||
| + | |||
| + | RBAC | ||
| + | |||
| + | Properties | ||
| + | |||
| + | Owners | ||
| + | |||
| + | Customers | ||
| + | |||
| + | Reservations | ||
| + | |||
| + | Contracts | ||
| + | |||
| + | Payments | ||
| + | |||
| + | Accounting | ||
| + | |||
| + | CRM | ||
| + | |||
| + | Messaging | ||
| + | |||
| + | Marketing | ||
| + | |||
| + | Automation | ||
| + | |||
| + | Governance | ||
| + | |||
| + | OTA | ||
| + | |||
| + | Revenue Management | ||
| + | |||
| + | Enterprise Security | ||
| + | |||
| + | Internationalization | ||
| + | |||
| + | Artificial Intelligence | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ====== Fin de la Phase 2 ====== | ||
| + | |||
| + | Le schéma Prisma couvre désormais l' | ||
| + | |||
| + | < | ||
| + | Sprint 1 → Sprint 20 | ||
| + | </ | ||
| + | |||
| + | et constitue la base pour : | ||
| + | |||
| + | < | ||
| + | Phase 3 | ||
| + | |||
| + | OpenAPI 3.1 complet | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | DTO NestJS | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | SDK TypeScript | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Génération Backend NestJS | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Génération Frontend NextJS | ||
| + | |||
| + | ↓ | ||
| + | |||
| + | Monorepo Enterprise 4.0 | ||
| + | </ | ||
ujusum/3-codage/1-repository/2-prisma-schema.1780800273.txt.gz · Dernière modification : 2026/06/07 04:44 de 91.170.108.99