Outils pour utilisateurs

Outils du site


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

Ceci est une ancienne révision du document !


Table des matières

Phase 2 — Prisma Schema

Objectif

Construire le schéma Prisma qui deviendra la source de vérité unique du système.

À partir de ce schéma seront générés :

  • PostgreSQL
  • Prisma Client
  • DTO
  • Entités NestJS
  • OpenAPI
  • SDK TypeScript
  • Migrations SQL

Le schéma doit refléter l'intégralité des domaines définis dans les 20 sprints.


Objectifs techniques

Le schéma Prisma doit supporter :

Multi-tenant

Audit

Historisation

Soft Delete

RBAC

CRM

Catalogue

Réservations

Paiements

Contrats

OTA

IA

Revenue Management

Internationalisation

Sécurité Enterprise

Ordre de construction recommandé

Ne jamais commencer par les 80 tables.

Construire par couches.


Couche 1 — Fondations

Construire en premier :

Tenant

User

Role

Permission

UserRole

RolePermission

Ces tables sont nécessaires partout.


Couche 2 — Référentiels

Créer :

Address

Country

Language

Currency

Timezone

Couche 3 — Catalogue

Créer :

Property

PropertyType

PropertyMedia

PropertyFeature

PropertyAvailability

PropertyRate

Couche 4 — Réservations

Créer :

Reservation

ReservationGuest

ReservationStatus

ReservationEvent

Couche 5 — Contrats

Créer :

Contract

ContractTemplate

ContractSignature

Document

Couche 6 — Paiements

Créer :

Payment

Invoice

Refund

AccountingEntry

Couche 7 — CRM

Créer :

Lead

Customer

Activity

Task

Pipeline

Couche 8 — Propriétaires

Créer :

Owner

OwnerProperty

OwnerDocument

Couche 9 — Notifications

Créer :

Notification

NotificationTemplate

Message

Campaign

Couche 10 — Administration

Créer :

AuditLog

FeatureFlag

CustomField

Workflow

Couche 11 — IA

Créer :

AiConversation

AiMessage

KnowledgeDocument

AutomationRule

Couche 12 — OTA

Créer :

Channel

ChannelConnection

PropertyDistribution

ChannelReservation

Couche 13 — Revenue Management

Créer :

PricingRule

DynamicPrice

RevenueSimulation

CompetitorSnapshot

Couche 14 — Sécurité

Créer :

Consent

SecurityPolicy

Risk

ComplianceAudit

Couche 15 — Internationalisation

Créer :

Translation

CurrencyRate

Region

EnterpriseLicense

Organisation du dossier Prisma

Au lieu d'un unique fichier géant :

prisma/

├── schema.prisma
│
├── models/
│
│   ├── tenant.prisma
│   ├── user.prisma
│   ├── property.prisma
│   ├── reservation.prisma
│   ├── contract.prisma
│   ├── payment.prisma
│   ├── crm.prisma
│   ├── owner.prisma
│   ├── notification.prisma
│   ├── audit.prisma
│   ├── ai.prisma
│   ├── channel.prisma
│   ├── revenue.prisma
│   ├── security.prisma
│   └── localization.prisma

Configuration initiale

schema.prisma

Version minimale :

generator client {
  provider = "prisma-client-js"
}
 
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

Première implémentation

Étape 1

Créer :

prisma/models/tenant.prisma

Tenant

model Tenant {
 
  id            String   @id @default(uuid())
 
  code          String   @unique
 
  name          String
 
  status        TenantStatus
 
  createdAt     DateTime @default(now())
 
  updatedAt     DateTime @updatedAt
 
  users         User[]
 
  properties    Property[]
 
}

Enum

enum TenantStatus {
 
  ACTIVE
 
  SUSPENDED
 
  TRIAL
 
  ARCHIVED
}

Étape 2

Créer :

prisma/models/user.prisma

User

model User {
 
  id              String @id @default(uuid())
 
  tenantId        String
 
  email           String @unique
 
  passwordHash    String
 
  firstName       String
 
  lastName        String
 
  active          Boolean @default(true)
 
  createdAt       DateTime @default(now())
 
  updatedAt       DateTime @updatedAt
 
  tenant          Tenant @relation(
                    fields:[tenantId],
                    references:[id]
                  )
 
  roles           UserRole[]
 
}

Role

model Role {
 
  id            String @id @default(uuid())
 
  code          String @unique
 
  name          String
 
  userRoles     UserRole[]
 
  permissions   RolePermission[]
}

Permission

model Permission {
 
  id            String @id @default(uuid())
 
  code          String @unique
 
  name          String
 
  rolePermissions RolePermission[]
}

UserRole

model UserRole {
 
  userId        String
 
  roleId        String
 
  assignedAt    DateTime @default(now())
 
  user          User @relation(
                  fields:[userId],
                  references:[id]
                )
 
  role          Role @relation(
                  fields:[roleId],
                  references:[id]
                )
 
  @@id([userId, roleId])
}

RolePermission

model RolePermission {
 
  roleId        String
 
  permissionId  String
 
  role          Role @relation(
                  fields:[roleId],
                  references:[id]
                )
 
  permission    Permission @relation(
                  fields:[permissionId],
                  references:[id]
                )
 
  @@id([roleId, permissionId])
}

Génération

Après chaque bloc important :

npx prisma format

Validation

npx prisma validate

Génération Client

npx prisma generate

Migration

npx prisma migrate dev \
--name init_security

Vérification

Ouvrir :

npx prisma studio

Vérifier la présence :

Tenant

User

Role

Permission

UserRole

RolePermission

Phase 2-A — Fondation complète (Tenant + RBAC + Propriétés de sécurité)

Vous avez raison.

La version précédente contient :

  • Tenant
  • User
  • Role
  • Permission
  • UserRole
  • RolePermission

mais il manque plusieurs éléments indispensables pour un véritable système Enterprise :

  • propriétés du compte utilisateur
  • préférences utilisateur
  • sessions
  • refresh tokens
  • MFA
  • audit de connexion
  • catalogue complet des permissions

Sans ces éléments, le Sprint 1 (Authentification) et le Sprint 19 (Sécurité Enterprise) ne pourront pas être implémentés proprement.


Modèle User complet

User

model User {
 
  id                String      @id @default(uuid())
 
  tenantId          String
 
  email             String      @unique
 
  passwordHash      String
 
  firstName         String
 
  lastName          String
 
  phone             String?
 
  avatarUrl         String?
 
  languageCode      String?
 
  timezoneCode      String?
 
  active            Boolean     @default(true)
 
  emailVerified     Boolean     @default(false)
 
  lastLoginAt       DateTime?
 
  createdAt         DateTime    @default(now())
 
  updatedAt         DateTime    @updatedAt
 
  deletedAt         DateTime?
 
  tenant            Tenant      @relation(
                                  fields:[tenantId],
                                  references:[id]
                                )
 
  roles             UserRole[]
 
  sessions          UserSession[]
 
  refreshTokens     RefreshToken[]
 
  preferences       UserPreference?
 
  loginHistory      LoginHistory[]
 
  mfaMethods        UserMfaMethod[]
}

Préférences utilisateur

UserPreference

model UserPreference {
 
  id                String      @id @default(uuid())
 
  userId            String      @unique
 
  theme             String?
 
  language          String?
 
  timezone          String?
 
  notifications     Json?
 
  createdAt         DateTime    @default(now())
 
  updatedAt         DateTime    @updatedAt
 
  user              User @relation(
                        fields:[userId],
                        references:[id]
                      )
}

Gestion des sessions

UserSession

model UserSession {
 
  id                String      @id @default(uuid())
 
  userId            String
 
  ipAddress         String?
 
  userAgent         String?
 
  country           String?
 
  city              String?
 
  lastActivityAt    DateTime
 
  expiresAt         DateTime
 
  revokedAt         DateTime?
 
  createdAt         DateTime    @default(now())
 
  user              User @relation(
                        fields:[userId],
                        references:[id]
                      )
}

Refresh Tokens

RefreshToken

model RefreshToken {
 
  id                String      @id @default(uuid())
 
  userId            String
 
  tokenHash         String
 
  expiresAt         DateTime
 
  revokedAt         DateTime?
 
  createdAt         DateTime    @default(now())
 
  user              User @relation(
                        fields:[userId],
                        references:[id]
                      )
}

Historique des connexions

LoginHistory

model LoginHistory {
 
  id                String      @id @default(uuid())
 
  userId            String
 
  success           Boolean
 
  ipAddress         String?
 
  userAgent         String?
 
  country           String?
 
  city              String?
 
  createdAt         DateTime @default(now())
 
  user              User @relation(
                        fields:[userId],
                        references:[id]
                      )
}

MFA

UserMfaMethod

model UserMfaMethod {
 
  id                String      @id @default(uuid())
 
  userId            String
 
  methodType        String
 
  secret            String?
 
  enabled           Boolean     @default(true)
 
  createdAt         DateTime    @default(now())
 
  user              User @relation(
                        fields:[userId],
                        references:[id]
                      )
}

RBAC Enterprise

Role

model Role {
 
  id                String      @id @default(uuid())
 
  code              String      @unique
 
  name              String
 
  description       String?
 
  systemRole        Boolean     @default(false)
 
  createdAt         DateTime    @default(now())
 
  updatedAt         DateTime    @updatedAt
 
  userRoles         UserRole[]
 
  permissions       RolePermission[]
}

Permission

model Permission {
 
  id                String      @id @default(uuid())
 
  code              String      @unique
 
  name              String
 
  description       String?
 
  module            String
 
  createdAt         DateTime    @default(now())
 
  rolePermissions   RolePermission[]
}

Catalogue initial des permissions

Auth

AUTH_LOGIN

AUTH_REGISTER

AUTH_RESET_PASSWORD

AUTH_MANAGE_USERS

Users

USER_READ

USER_CREATE

USER_UPDATE

USER_DELETE

Properties

PROPERTY_READ

PROPERTY_CREATE

PROPERTY_UPDATE

PROPERTY_DELETE

PROPERTY_PUBLISH

Reservations

RESERVATION_READ

RESERVATION_CREATE

RESERVATION_UPDATE

RESERVATION_CANCEL

Contracts

CONTRACT_READ

CONTRACT_CREATE

CONTRACT_SIGN

Payments

PAYMENT_READ

PAYMENT_CREATE

PAYMENT_REFUND

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'agence.


AGENCY_MANAGER

Gestion opérationnelle.


OWNER

Extranet propriétaire.


AGENT

Collaborateur.


CUSTOMER

Client final.


Indexes recommandés

User

@@index([tenantId])
 
@@index([email])
 
@@index([active])

LoginHistory

@@index([userId])
 
@@index([createdAt])

UserSession

@@index([userId])
 
@@index([expiresAt])

Architecture du domaine Property

Entités

Property

PropertyType

PropertyStatus

PropertyAddress

PropertyFeature

PropertyMedia

PropertyAvailability

PropertyRate

PropertyOwner

Property

Table principale

model Property {
 
  id                    String @id @default(uuid())
 
  tenantId              String
 
  propertyTypeId        String
 
  code                  String @unique
 
  reference             String?
 
  title                 String
 
  slug                  String @unique
 
  description           String?
 
  shortDescription      String?
 
  maxGuests             Int
 
  bedrooms              Int
 
  bathrooms             Int
 
  area                  Decimal? @db.Decimal(10,2)
 
  floor                 Int?
 
  constructionYear      Int?
 
  checkInTime           String?
 
  checkOutTime          String?
 
  active                Boolean @default(true)
 
  published             Boolean @default(false)
 
  createdAt             DateTime @default(now())
 
  updatedAt             DateTime @updatedAt
 
  deletedAt             DateTime?
 
  tenant                Tenant @relation(
                            fields:[tenantId],
                            references:[id]
                         )
 
  propertyType          PropertyType @relation(
                            fields:[propertyTypeId],
                            references:[id]
                         )
 
  address               PropertyAddress?
 
  features              PropertyFeature[]
 
  media                 PropertyMedia[]
 
  availabilities        PropertyAvailability[]
 
  rates                 PropertyRate[]
 
  owners                PropertyOwner[]
 
  reservations         Reservation[]
 
}

PropertyType

Référentiel

model PropertyType {
 
  id                String @id @default(uuid())
 
  code              String @unique
 
  name              String
 
  properties        Property[]
}

Valeurs

HOUSE

APARTMENT

VILLA

STUDIO

LOFT

CHALET

COTTAGE

MOBILE_HOME

PropertyAddress

Adresse du bien

model PropertyAddress {
 
  id                String @id @default(uuid())
 
  propertyId        String @unique
 
  addressLine1      String
 
  addressLine2      String?
 
  postalCode        String
 
  city              String
 
  state             String?
 
  countryCode       String
 
  latitude          Decimal? @db.Decimal(10,7)
 
  longitude         Decimal? @db.Decimal(10,7)
 
  property          Property @relation(
                      fields:[propertyId],
                      references:[id]
                    )
}

PropertyFeature

Équipements

model PropertyFeature {
 
  id                String @id @default(uuid())
 
  propertyId        String
 
  featureCode       String
 
  featureValue      String?
 
  property          Property @relation(
                      fields:[propertyId],
                      references:[id]
                    )
}

Exemples

POOL

WIFI

PARKING

AIR_CONDITIONING

TERRACE

SEA_VIEW

PET_ALLOWED

PropertyMedia

Médias

model PropertyMedia {
 
  id                String @id @default(uuid())
 
  propertyId        String
 
  fileName          String
 
  fileUrl           String
 
  mediaType         String
 
  position          Int
 
  isCover           Boolean @default(false)
 
  createdAt         DateTime @default(now())
 
  property          Property @relation(
                      fields:[propertyId],
                      references:[id]
                    )
}

MediaType

IMAGE

VIDEO

VIRTUAL_TOUR

DOCUMENT

PropertyAvailability

Calendrier

model PropertyAvailability {
 
  id                String @id @default(uuid())
 
  propertyId        String
 
  startDate         DateTime
 
  endDate           DateTime
 
  status            AvailabilityStatus
 
  property          Property @relation(
                      fields:[propertyId],
                      references:[id]
                    )
}

Enum

enum AvailabilityStatus {
 
  AVAILABLE
 
  RESERVED
 
  BLOCKED
 
  MAINTENANCE
}

PropertyRate

Tarification

model PropertyRate {
 
  id                String @id @default(uuid())
 
  propertyId        String
 
  startDate         DateTime
 
  endDate           DateTime
 
  nightlyRate       Decimal @db.Decimal(10,2)
 
  weekendRate       Decimal? @db.Decimal(10,2)
 
  cleaningFee       Decimal? @db.Decimal(10,2)
 
  securityDeposit   Decimal? @db.Decimal(10,2)
 
  currencyCode      String
 
  property          Property @relation(
                      fields:[propertyId],
                      references:[id]
                    )
}

PropertyOwner

Association propriétaire

model PropertyOwner {
 
  propertyId        String
 
  ownerId           String
 
  ownershipRate     Decimal @db.Decimal(5,2)
 
  property          Property @relation(
                      fields:[propertyId],
                      references:[id]
                    )
 
  owner             Owner @relation(
                      fields:[ownerId],
                      references:[id]
                    )
 
  @@id([propertyId, ownerId])
}

Indexes

Property

@@index([tenantId])
 
@@index([propertyTypeId])
 
@@index([published])
 
@@index([active])
 
@@index([title])
 
@@index([slug])

PropertyAvailability

@@index([propertyId])
 
@@index([startDate])
 
@@index([endDate])

PropertyRate

@@index([propertyId])
 
@@index([startDate])
 
@@index([endDate])

Domaine Owner

Architecture

Owner

OwnerAddress

OwnerDocument

OwnerBankAccount

PropertyOwner

Owner

model Owner {
 
  id                    String @id @default(uuid())
 
  tenantId              String
 
  code                  String @unique
 
  companyName           String?
 
  firstName             String?
 
  lastName              String?
 
  email                 String
 
  phone                 String?
 
  mobile                String?
 
  taxIdentifier         String?
 
  vatNumber             String?
 
  active                Boolean @default(true)
 
  createdAt             DateTime @default(now())
 
  updatedAt             DateTime @updatedAt
 
  deletedAt             DateTime?
 
  tenant                Tenant @relation(
                            fields:[tenantId],
                            references:[id]
                         )
 
  address               OwnerAddress?
 
  documents             OwnerDocument[]
 
  bankAccounts          OwnerBankAccount[]
 
  properties            PropertyOwner[]
}

OwnerAddress

model OwnerAddress {
 
  id                    String @id @default(uuid())
 
  ownerId               String @unique
 
  addressLine1          String
 
  addressLine2          String?
 
  postalCode            String
 
  city                  String
 
  state                 String?
 
  countryCode           String
 
  owner                 Owner @relation(
                            fields:[ownerId],
                            references:[id]
                         )
}

OwnerDocument

model OwnerDocument {
 
  id                    String @id @default(uuid())
 
  ownerId               String
 
  documentType          String
 
  fileUrl               String
 
  createdAt             DateTime @default(now())
 
  owner                 Owner @relation(
                            fields:[ownerId],
                            references:[id]
                         )
}

Document Types

IDENTITY

TAX_DOCUMENT

MANDATE

BANK_DETAILS

INSURANCE

OwnerBankAccount

model OwnerBankAccount {
 
  id                    String @id @default(uuid())
 
  ownerId               String
 
  iban                  String
 
  bic                   String?
 
  accountHolder         String
 
  active                Boolean @default(true)
 
  owner                 Owner @relation(
                            fields:[ownerId],
                            references:[id]
                         )
}

Domaine Reservation

Architecture

Reservation

ReservationGuest

ReservationStatusHistory

ReservationEvent

ReservationPricing

Reservation

Table centrale

model Reservation {
 
  id                    String @id @default(uuid())
 
  tenantId              String
 
  propertyId            String
 
  customerId            String?
 
  reference             String @unique
 
  status                ReservationStatus
 
  checkInDate           DateTime
 
  checkOutDate          DateTime
 
  nights                Int
 
  adults                Int
 
  children              Int
 
  infants               Int
 
  totalGuests           Int
 
  notes                 String?
 
  source                ReservationSource
 
  createdAt             DateTime @default(now())
 
  updatedAt             DateTime @updatedAt
 
  cancelledAt           DateTime?
 
  tenant                Tenant @relation(
                            fields:[tenantId],
                            references:[id]
                         )
 
  property              Property @relation(
                            fields:[propertyId],
                            references:[id]
                         )
 
  guests                ReservationGuest[]
 
  events                ReservationEvent[]
 
  statusHistory         ReservationStatusHistory[]
 
  pricing               ReservationPricing?
}

ReservationStatus

enum ReservationStatus {
 
  DRAFT
 
  PENDING
 
  CONFIRMED
 
  SIGNED
 
  PAID
 
  CHECKED_IN
 
  COMPLETED
 
  CANCELLED
}

ReservationSource

enum ReservationSource {
 
  WEBSITE
 
  BACKOFFICE
 
  AIRBNB
 
  BOOKING
 
  VRBO
 
  API
}

ReservationGuest

model ReservationGuest {
 
  id                    String @id @default(uuid())
 
  reservationId         String
 
  firstName             String
 
  lastName              String
 
  birthDate             DateTime?
 
  email                 String?
 
  phone                 String?
 
  isPrimary             Boolean @default(false)
 
  reservation           Reservation @relation(
                            fields:[reservationId],
                            references:[id]
                         )
}

ReservationPricing

model ReservationPricing {
 
  id                    String @id @default(uuid())
 
  reservationId         String @unique
 
  nightlyAmount         Decimal @db.Decimal(10,2)
 
  cleaningFee           Decimal @db.Decimal(10,2)
 
  touristTax            Decimal @db.Decimal(10,2)
 
  discountAmount        Decimal @db.Decimal(10,2)
 
  totalAmount           Decimal @db.Decimal(10,2)
 
  currencyCode          String
 
  reservation           Reservation @relation(
                            fields:[reservationId],
                            references:[id]
                         )
}

ReservationEvent

model ReservationEvent {
 
  id                    String @id @default(uuid())
 
  reservationId         String
 
  eventType             String
 
  payload               Json?
 
  createdAt             DateTime @default(now())
 
  reservation           Reservation @relation(
                            fields:[reservationId],
                            references:[id]
                         )
}

Event Types

CREATED

CONFIRMED

SIGNED

PAID

CHECK_IN

CHECK_OUT

CANCELLED

ReservationStatusHistory

model ReservationStatusHistory {
 
  id                    String @id @default(uuid())
 
  reservationId         String
 
  previousStatus        ReservationStatus?
 
  newStatus             ReservationStatus
 
  changedAt             DateTime @default(now())
 
  reservation           Reservation @relation(
                            fields:[reservationId],
                            references:[id]
                         )
}

Relations à ajouter

Property

Ajouter :

reservations Reservation[]

Tenant

Ajouter :

owners Owner[]
 
reservations Reservation[]

Indexes

Owner

@@index([tenantId])
 
@@index([email])
 
@@index([active])

Reservation

@@index([tenantId])
 
@@index([propertyId])
 
@@index([status])
 
@@index([checkInDate])
 
@@index([checkOutDate])
 
@@index([reference])

ReservationGuest

@@index([reservationId])

Validation

npx prisma format
 
npx prisma validate
 
npx prisma generate

Migration

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 le premier flux métier complet de la plateforme :

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

model Customer {
 
  id                    String @id @default(uuid())
 
  tenantId              String
 
  customerNumber        String @unique
 
  firstName             String
 
  lastName              String
 
  email                 String
 
  phone                 String?
 
  mobile                String?
 
  birthDate             DateTime?
 
  nationality           String?
 
  languageCode          String?
 
  active                Boolean @default(true)
 
  createdAt             DateTime @default(now())
 
  updatedAt             DateTime @updatedAt
 
  deletedAt             DateTime?
 
  tenant                Tenant @relation(
                            fields:[tenantId],
                            references:[id]
                         )
 
  address               CustomerAddress?
 
  documents             CustomerDocument[]
 
  reservations          Reservation[]
}

CustomerAddress

model CustomerAddress {
 
  id                    String @id @default(uuid())
 
  customerId            String @unique
 
  addressLine1          String
 
  addressLine2          String?
 
  postalCode            String
 
  city                  String
 
  state                 String?
 
  countryCode           String
 
  customer              Customer @relation(
                            fields:[customerId],
                            references:[id]
                         )
}

CustomerDocument

model CustomerDocument {
 
  id                    String @id @default(uuid())
 
  customerId            String
 
  documentType          String
 
  fileUrl               String
 
  createdAt             DateTime @default(now())
 
  customer              Customer @relation(
                            fields:[customerId],
                            references:[id]
                         )
}

Mise à jour Reservation

Ajouter

customerId String?

Relation

customer Customer? @relation(
  fields:[customerId],
  references:[id]
)

Domaine Contrats

Architecture

Contract

ContractTemplate

ContractVersion

ContractSignature

Contract

model Contract {
 
  id                    String @id @default(uuid())
 
  tenantId              String
 
  reservationId         String
 
  templateId            String
 
  contractNumber        String @unique
 
  status                ContractStatus
 
  signedAt              DateTime?
 
  generatedAt           DateTime?
 
  pdfUrl                String?
 
  createdAt             DateTime @default(now())
 
  updatedAt             DateTime @updatedAt
 
  tenant                Tenant @relation(
                            fields:[tenantId],
                            references:[id]
                         )
 
  reservation           Reservation @relation(
                            fields:[reservationId],
                            references:[id]
                         )
 
  template              ContractTemplate @relation(
                            fields:[templateId],
                            references:[id]
                         )
 
  signatures            ContractSignature[]
 
  versions              ContractVersion[]
}

ContractStatus

enum ContractStatus {
 
  DRAFT
 
  GENERATED
 
  SENT
 
  VIEWED
 
  SIGNED
 
  CANCELLED
}

ContractTemplate

model ContractTemplate {
 
  id                    String @id @default(uuid())
 
  code                  String @unique
 
  name                  String
 
  content               String
 
  active                Boolean @default(true)
 
  createdAt             DateTime @default(now())
 
  contracts             Contract[]
}

ContractVersion

model ContractVersion {
 
  id                    String @id @default(uuid())
 
  contractId            String
 
  versionNumber         Int
 
  pdfUrl                String
 
  createdAt             DateTime @default(now())
 
  contract              Contract @relation(
                            fields:[contractId],
                            references:[id]
                         )
}

ContractSignature

model ContractSignature {
 
  id                    String @id @default(uuid())
 
  contractId            String
 
  signerName            String
 
  signerEmail           String
 
  signedAt              DateTime?
 
  providerReference     String?
 
  status                String
 
  contract              Contract @relation(
                            fields:[contractId],
                            references:[id]
                         )
}

Domaine Documents

Document

model Document {
 
  id                    String @id @default(uuid())
 
  tenantId              String
 
  documentType          String
 
  fileName              String
 
  fileUrl               String
 
  mimeType              String
 
  fileSize              Int
 
  uploadedAt            DateTime @default(now())
 
  tenant                Tenant @relation(
                            fields:[tenantId],
                            references:[id]
                         )
}

Domaine Paiements

Architecture

Payment

PaymentTransaction

Refund

PaymentMethod

Payment

model Payment {
 
  id                    String @id @default(uuid())
 
  tenantId              String
 
  reservationId         String
 
  paymentReference      String @unique
 
  status                PaymentStatus
 
  amount                Decimal @db.Decimal(10,2)
 
  currencyCode          String
 
  paidAt                DateTime?
 
  createdAt             DateTime @default(now())
 
  tenant                Tenant @relation(
                            fields:[tenantId],
                            references:[id]
                         )
 
  reservation           Reservation @relation(
                            fields:[reservationId],
                            references:[id]
                         )
 
  transactions          PaymentTransaction[]
 
  refunds               Refund[]
}

PaymentStatus

enum PaymentStatus {
 
  PENDING
 
  AUTHORIZED
 
  PAID
 
  FAILED
 
  CANCELLED
 
  REFUNDED
}

PaymentTransaction

model PaymentTransaction {
 
  id                    String @id @default(uuid())
 
  paymentId             String
 
  gateway               String
 
  gatewayReference      String
 
  status                String
 
  amount                Decimal @db.Decimal(10,2)
 
  createdAt             DateTime @default(now())
 
  payment               Payment @relation(
                            fields:[paymentId],
                            references:[id]
                         )
}

Refund

model Refund {
 
  id                    String @id @default(uuid())
 
  paymentId             String
 
  amount                Decimal @db.Decimal(10,2)
 
  reason                String?
 
  refundedAt            DateTime?
 
  payment               Payment @relation(
                            fields:[paymentId],
                            references:[id]
                         )
}

Facturation

Invoice

model Invoice {
 
  id                    String @id @default(uuid())
 
  tenantId              String
 
  reservationId         String
 
  invoiceNumber         String @unique
 
  issueDate             DateTime
 
  dueDate               DateTime
 
  amountExclTax         Decimal @db.Decimal(10,2)
 
  taxAmount             Decimal @db.Decimal(10,2)
 
  amountInclTax         Decimal @db.Decimal(10,2)
 
  status                InvoiceStatus
 
  pdfUrl                String?
 
  createdAt             DateTime @default(now())
 
  reservation           Reservation @relation(
                            fields:[reservationId],
                            references:[id]
                         )
 
  tenant                Tenant @relation(
                            fields:[tenantId],
                            references:[id]
                         )
}

InvoiceStatus

enum InvoiceStatus {
 
  DRAFT
 
  ISSUED
 
  PAID
 
  PARTIALLY_PAID
 
  CANCELLED
}

Comptabilité

AccountingEntry

model AccountingEntry {
 
  id                    String @id @default(uuid())
 
  tenantId              String
 
  entryDate             DateTime
 
  accountCode           String
 
  label                 String
 
  debit                 Decimal @db.Decimal(12,2)
 
  credit                Decimal @db.Decimal(12,2)
 
  reference             String?
 
  createdAt             DateTime @default(now())
 
  tenant                Tenant @relation(
                            fields:[tenantId],
                            references:[id]
                         )
}

Indexes

Contract

@@index([reservationId])
 
@@index([status])
 
@@index([contractNumber])

Payment

@@index([reservationId])
 
@@index([status])
 
@@index([paymentReference])

Invoice

@@index([reservationId])
 
@@index([invoiceNumber])
 
@@index([status])

Validation

npx prisma format
 
npx prisma validate
 
npx prisma generate

Migration

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

Étape suivante

Phase 2-F

CRM & Relation Client

Lead

Opportunity

Pipeline

Activity

Task

CustomerNote

Tag

Segment

Cette phase permettra d'implémenter intégralement le Sprint 8 — CRM & Relation Client.

ujusum/3-codage/1-repository/2-prisma-schema.1780830630.txt.gz · Dernière modification : 2026/06/07 13:10 de 91.170.108.99

DokuWiki Appliance - Powered by TurnKey Linux