====== Sprint 6 — Multi-Propriétés & Gestion du Parc ======
===== Objectif =====
Faire évoluer la plateforme d'un modèle mono-propriété vers une plateforme Enterprise multi-sites.
Cette couche permet de gérer :
Portefeuilles
Groupes de propriétés
Propriétaires
Exploitants
Actifs
Performance globale
sur plusieurs centaines ou milliers de propriétés.
À l'issue du Sprint 6 :
✓ Portfolio Management
✓ Property Groups
✓ Owners
✓ Operators
✓ Asset Management
✓ Portfolio Analytics
✓ Enterprise Multi-Property Platform
----
====== Architecture cible ======
Tenant
↓
Portfolio
├── Property Groups
├── Properties
├── Owners
├── Operators
├── Assets
└── Portfolio Analytics
↓
Reservations
↓
Finance
↓
Operations
----
====== Domaines métier ======
Le Sprint 6 introduit :
Portfolio
PropertyGroup
Owner
Operator
Asset
AssetAssignment
PortfolioAnalytics
PortfolioKPI
----
====== Sous-sprints ======
===== Sprint 6-A =====
Fondation Multi-Propriétés
Portfolio
Property Groups
Owners
Operators
----
===== Sprint 6-B =====
Asset Management
Assets
Lifecycle
Assignments
Maintenance Integration
----
===== Sprint 6-C =====
Portfolio Analytics
Portfolio KPIs
Revenue
Occupancy
Benchmarking
Forecasting
----
===== Sprint 6-D =====
Enterprise Governance
Multi-Site RBAC
Approvals
Compliance
Delegation
----
====== Livrables fin Sprint 6 ======
Portfolio Engine
Property Group Management
Owner Management
Operator Management
Asset Platform
Portfolio Analytics
Enterprise Multi-Site Platform
----
====== Sprint 6-A.1 — Implémentation Prisma Portfolio Core ======
===== Objectif =====
Créer la fondation Multi-Propriétés Enterprise.
Cette couche permet de regrouper plusieurs propriétés dans des structures hiérarchiques :
Tenant
↓
Portfolio
↓
Property Group
↓
Properties
avec gestion des :
Propriétaires
Exploitants
Groupes
Portefeuilles
À l'issue de cette étape :
✓ Portfolio
✓ PropertyGroup
✓ Owner
✓ Operator
✓ Multi-Property Ready
✓ Finance Ready
✓ Reservation Ready
✓ Analytics Ready
----
====== Architecture cible ======
Tenant
↓
Portfolio
├── Property Groups
│
├── Owners
│
├── Operators
│
└── Properties
↓
Reservations
↓
Finance
↓
Analytics
----
====== Sprint 6-A.1-A ======
===== Extension Prisma =====
----
====== Étape 1 — Portfolio ======
===== Ajouter dans schema.prisma =====
model Portfolio {
id String
@id
@default(uuid())
tenantId String
name String
code String
@unique
description String?
active Boolean
@default(true)
createdAt DateTime
@default(now())
updatedAt DateTime
@updatedAt
tenant Tenant
@relation(
fields:[tenantId],
references:[id]
)
propertyGroups PropertyGroup[]
properties Property[]
@@index([tenantId])
@@index([active])
@@index([code])
}
----
====== Étape 2 — PropertyGroup ======
===== Ajouter =====
model PropertyGroup {
id String
@id
@default(uuid())
tenantId String
portfolioId String
name String
code String
description String?
active Boolean
@default(true)
createdAt DateTime
@default(now())
updatedAt DateTime
@updatedAt
portfolio Portfolio
@relation(
fields:[portfolioId],
references:[id],
onDelete:Cascade
)
properties Property[]
@@unique([
portfolioId,
code
])
@@index([tenantId])
@@index([portfolioId])
@@index([active])
}
----
====== Étape 3 — Owner ======
===== Ajouter =====
model Owner {
id String
@id
@default(uuid())
tenantId String
ownerCode String
@unique
type OwnerType
companyName String?
firstName String?
lastName String?
email String?
phone String?
taxIdentifier String?
active Boolean
@default(true)
createdAt DateTime
@default(now())
updatedAt DateTime
@updatedAt
properties Property[]
@@index([tenantId])
@@index([ownerCode])
@@index([active])
}
----
====== Étape 4 — Operator ======
===== Ajouter =====
model Operator {
id String
@id
@default(uuid())
tenantId String
operatorCode String
@unique
companyName String
email String?
phone String?
active Boolean
@default(true)
createdAt DateTime
@default(now())
updatedAt DateTime
@updatedAt
properties Property[]
@@index([tenantId])
@@index([operatorCode])
@@index([active])
}
----
====== Étape 5 — OwnerType ======
===== Ajouter =====
enum OwnerType {
INDIVIDUAL
COMPANY
INVESTMENT_FUND
REIT
GOVERNMENT
}
----
====== Sprint 6-A.1-B ======
===== Extension du modèle Property =====
----
====== Étape 6 — Ajouter Portfolio ======
===== Dans Property =====
portfolioId String?
portfolio Portfolio?
@relation(
fields:[portfolioId],
references:[id]
)
----
====== Étape 7 — Ajouter Property Group ======
===== Dans Property =====
propertyGroupId String?
propertyGroup PropertyGroup?
@relation(
fields:[propertyGroupId],
references:[id]
)
----
====== Étape 8 — Ajouter Owner ======
===== Dans Property =====
ownerId String?
owner Owner?
@relation(
fields:[ownerId],
references:[id]
)
----
====== Étape 9 — Ajouter Operator ======
===== Dans Property =====
operatorId String?
operator Operator?
@relation(
fields:[operatorId],
references:[id]
)
----
====== Étape 10 — Ajouter Index ======
@@index([portfolioId])
@@index([propertyGroupId])
@@index([ownerId])
@@index([operatorId])
----
====== Sprint 6-A.1-C ======
===== Relations Tenant =====
----
====== Étape 11 — Ajouter ======
===== Dans Tenant =====
portfolios Portfolio[]
owners Owner[]
operators Operator[]
----
====== Étape 12 — Multi-Tenant ======
===== Garantir =====
que :
Portfolio
PropertyGroup
Owner
Operator
appartiennent toujours au même :
tenantId
----
====== Sprint 6-A.1-D ======
===== Contraintes Métier =====
----
====== Étape 13 — Portfolio ======
===== Supporter =====
1 Tenant
↓
N Portfolios
----
====== Étape 14 — Property Group ======
===== Supporter =====
1 Portfolio
↓
N Property Groups
----
====== Étape 15 — Owner ======
===== Supporter =====
1 Owner
↓
N Properties
----
====== Étape 16 — Operator ======
===== Supporter =====
1 Operator
↓
N Properties
----
====== Sprint 6-A.1-E ======
===== Finance Ready =====
----
====== Étape 17 — Préparer =====
Compatible avec :
Revenue Sharing
Owner Statements
Commission Engine
Asset Accounting
----
====== Étape 18 — Préparer =====
Compatible avec :
Multi-Owner Properties
Operator Contracts
Portfolio Finance
----
====== Sprint 6-A.1-F ======
===== Reservation Ready =====
----
====== Étape 19 — Préparer =====
Compatible avec :
Portfolio Occupancy
Group Reservations
Multi-Site Reporting
----
====== Étape 20 — Préparer =====
Compatible avec :
Cross Property Search
Portfolio Analytics
Enterprise Reporting
----
====== Sprint 6-A.1-G ======
===== Analytics Ready =====
----
====== Étape 21 — Préparer =====
Compatible avec :
Portfolio Revenue
Portfolio Occupancy
Benchmarking
Forecasting
Asset Performance
----
====== Étape 22 — Préparer =====
Compatible avec :
Executive Dashboard
Owner Dashboard
Operator Dashboard
----
====== Sprint 6-A.1-H ======
===== Migration =====
----
====== Étape 23 — Générer =====
npx prisma migrate dev \
--name portfolio_core
----
====== Étape 24 — Générer =====
npx prisma generate
----
====== Étape 25 — Vérifier =====
npx prisma studio
Présence de :
Portfolio
PropertyGroup
Owner
Operator
----
====== Définition de terminé ======
Le Sprint 6-A.1 est terminé lorsque :
✓ Portfolio créé
✓ PropertyGroup créé
✓ Owner créé
✓ Operator créé
✓ Relations Property créées
✓ Relations Tenant créées
✓ Multi-Tenant Ready
✓ Finance Ready
✓ Analytics Ready
✓ Migration exécutée
----
====== Livrables ======
Portfolio
PropertyGroup
Owner
Operator
OwnerType
Portfolio Core Schema
----
====== Sprint 6-A.2 — Gestion Multi-Propriétés Enterprise ======
===== Objectif =====
Construire la couche métier Multi-Propriétés Enterprise.
Cette couche permet de gérer :
Portefeuilles
Groupes de propriétés
Propriétaires
Exploitants
Hiérarchie multi-sites
Sécurité multi-niveaux
à partir d'une interface unique.
À l'issue de cette étape :
✓ PortfolioModule
✓ PropertyGroupModule
✓ OwnerModule
✓ OperatorModule
✓ Portfolio Hierarchy
✓ Portfolio Security
✓ Portfolio Dashboard
✓ Enterprise Multi-Site Management
----
====== Architecture cible ======
Portfolio
├── Property Groups
│
├── Properties
│
├── Owners
│
├── Operators
│
└── Portfolio Dashboard
↓
Reservations
↓
Finance
↓
Analytics
----
====== Sprint 6-A.2-A ======
===== Modules Métier =====
----
====== Étape 1 — Création ======
src/modules/portfolio
├── portfolio
│
├── property-groups
│
├── owners
│
├── operators
│
├── dashboard
│
└── portfolio.module.ts
----
====== Étape 2 — Services ======
===== Créer =====
PortfolioService
PropertyGroupService
OwnerService
OperatorService
PortfolioHierarchyService
PortfolioDashboardService
----
====== Étape 3 — Controllers ======
===== Créer =====
PortfolioController
PropertyGroupController
OwnerController
OperatorController
PortfolioDashboardController
----
====== Sprint 6-A.2-B ======
===== Gestion des Portefeuilles =====
----
====== Étape 4 — PortfolioService ======
===== Créer =====
portfolio.service.ts
----
===== Méthodes =====
createPortfolio()
updatePortfolio()
archivePortfolio()
getPortfolio()
getPortfolioSummary()
----
====== Étape 5 — Endpoints ======
===== Ajouter =====
GET /portfolios
GET /portfolios/{id}
POST /portfolios
PUT /portfolios/{id}
DELETE /portfolios/{id}
----
====== Étape 6 — Validation ======
===== Vérifier =====
tenantId
unicité code
ownership
sur chaque opération.
----
====== Sprint 6-A.2-C ======
===== Gestion des Groupes =====
----
====== Étape 7 — PropertyGroupService ======
===== Créer =====
property-group.service.ts
----
===== Méthodes =====
createGroup()
assignProperty()
removeProperty()
moveProperty()
----
====== Étape 8 — Structure ======
===== Supporter =====
Portfolio
↓
Region
↓
City
↓
Properties
----
====== Étape 9 — Endpoints ======
===== Ajouter =====
GET /property-groups
POST /property-groups
PUT /property-groups/{id}
DELETE /property-groups/{id}
POST /property-groups/{id}/properties
----
====== Sprint 6-A.2-D ======
===== Gestion des Propriétaires =====
----
====== Étape 10 — OwnerService ======
===== Créer =====
owner.service.ts
----
===== Méthodes =====
createOwner()
updateOwner()
assignProperty()
getOwnerPortfolio()
----
====== Étape 11 — Informations ======
===== Gérer =====
Personne physique
Société
Coordonnées
Fiscalité
Contrats
----
====== Étape 12 — Endpoints ======
===== Ajouter =====
GET /owners
GET /owners/{id}
POST /owners
PUT /owners/{id}
DELETE /owners/{id}
----
====== Sprint 6-A.2-E ======
===== Gestion des Exploitants =====
----
====== Étape 13 — OperatorService ======
===== Créer =====
operator.service.ts
----
===== Méthodes =====
createOperator()
updateOperator()
assignProperty()
getOperatorPerformance()
----
====== Étape 14 — Endpoints ======
===== Ajouter =====
GET /operators
GET /operators/{id}
POST /operators
PUT /operators/{id}
DELETE /operators/{id}
----
====== Sprint 6-A.2-F ======
===== Hiérarchie Enterprise =====
----
====== Étape 15 — PortfolioHierarchyService ======
===== Créer =====
portfolio-hierarchy.service.ts
----
===== Construire =====
Portfolio
↓
PropertyGroup
↓
Property
----
====== Étape 16 — Fonctions ======
===== Supporter =====
getTree()
getChildren()
getAncestors()
calculateAggregates()
----
====== Étape 17 — Agrégations ======
===== Calculer =====
Properties Count
Revenue
Occupancy
Reservations
Reviews
par niveau.
----
====== Sprint 6-A.2-G ======
===== Portfolio Security =====
----
====== Étape 18 — Portfolio Scope ======
===== Ajouter =====
portfolioId
propertyGroupId
propertyId
comme scopes de sécurité.
----
====== Étape 19 — RBAC ======
===== Supporter =====
Portfolio Admin
Portfolio Manager
Group Manager
Property Manager
Owner Viewer
----
====== Étape 20 — Filtrage ======
===== Imposer =====
sur toutes les requêtes :
tenantId
portfolioId
afin d'éviter toute fuite de données.
----
====== Étape 21 — Decorators ======
===== Créer =====
@PortfolioScope()
@PropertyGroupScope()
pour les futurs modules.
----
====== Sprint 6-A.2-H ======
===== Dashboard Portfolio =====
----
====== Étape 22 — PortfolioDashboardService ======
===== Créer =====
portfolio-dashboard.service.ts
----
===== Agréger =====
Properties
Reservations
Revenue
Occupancy
Reviews
Incidents
----
====== Étape 23 — Endpoint ======
===== Ajouter =====
GET /portfolios/{id}/dashboard
----
====== Étape 24 — Exemple ======
===== Réponse =====
{
"properties":124,
"occupancy":81.4,
"revenue":2450000,
"reservations":8421,
"rating":4.7
}
----
====== Étape 25 — KPIs ======
===== Mesurer =====
Revenue
Occupancy
ADR
RevPAR
Reservations
Guest Satisfaction
----
====== Sprint 6-A.2-I ======
===== API Enterprise =====
----
====== Étape 26 — Recherche ======
===== Ajouter =====
GET /portfolios/search
GET /owners/search
GET /operators/search
----
====== Étape 27 — Pagination ======
===== Supporter =====
Page
Limit
Sort
Filters
sur tous les endpoints.
----
====== Étape 28 — Export ======
===== Ajouter =====
GET /portfolios/{id}/export
Formats :
CSV
Excel
PDF
----
====== Sprint 6-A.2-J ======
===== Gouvernance =====
----
====== Étape 29 — Permissions ======
===== Ajouter =====
portfolio.read
portfolio.create
portfolio.update
portfolio.delete
portfolio.dashboard
owner.manage
operator.manage
----
====== Étape 30 — Audit ======
===== Journaliser =====
PORTFOLIO_CREATED
PORTFOLIO_UPDATED
PROPERTY_ASSIGNED
OWNER_ASSIGNED
OPERATOR_ASSIGNED
PORTFOLIO_DASHBOARD_VIEWED
----
====== Étape 31 — Préparation Sprint 6-B =====
Compatible avec :
Assets
Equipment
Lifecycle
Depreciation
Capital Expenditure
----
====== Définition de terminé ======
Le Sprint 6-A.2 est terminé lorsque :
✓ PortfolioModule créé
✓ PropertyGroupModule créé
✓ OwnerModule créé
✓ OperatorModule créé
✓ Portfolio Hierarchy créée
✓ Portfolio Security créée
✓ Portfolio Dashboard créé
✓ Audit intégré
----
====== Livrables ======
PortfolioModule
PropertyGroupModule
OwnerModule
OperatorModule
PortfolioHierarchyService
PortfolioDashboardService
Portfolio Security Layer
Enterprise Multi-Property Platform
----
====== Sprint 6-B.1 — Asset Management Core ======
===== Objectif =====
Mettre en place le moteur de gestion des actifs physiques du parc immobilier.
Cette couche permet de gérer :
Mobilier
Équipements
Électroménager
Matériel technique
Inventaire
Cycle de vie
sur l'ensemble du portefeuille immobilier.
À l'issue de cette étape :
✓ Asset
✓ AssetCategory
✓ AssetAssignment
✓ AssetLifecycle
✓ AssetInventory
✓ AssetTracking
✓ Enterprise Asset Management
----
====== Architecture cible ======
Portfolio
↓
Properties
↓
Asset Management
├── Asset Catalog
├── Asset Assignment
├── Lifecycle
├── Inventory
├── Tracking
└── Maintenance Integration
↓
Operations
↓
Finance
----
====== Sprint 6-B.1-A ======
===== Extension Prisma =====
----
====== Étape 1 — AssetCategory ======
===== Ajouter dans schema.prisma =====
model AssetCategory {
id String
@id
@default(uuid())
tenantId String
name String
code String
description String?
depreciationYears Int?
createdAt DateTime
@default(now())
updatedAt DateTime
@updatedAt
assets Asset[]
@@unique([
tenantId,
code
])
@@index([tenantId])
}
----
====== Étape 2 — Asset ======
===== Ajouter =====
model Asset {
id String
@id
@default(uuid())
tenantId String
assetCode String
@unique
categoryId String
propertyId String?
name String
description String?
serialNumber String?
manufacturer String?
model String?
purchaseDate DateTime?
purchasePrice Decimal?
@db.Decimal(14,2)
currentValue Decimal?
@db.Decimal(14,2)
status AssetStatus
condition AssetCondition
warrantyUntil DateTime?
qrCode String?
barcode String?
createdAt DateTime
@default(now())
updatedAt DateTime
@updatedAt
category AssetCategory
@relation(
fields:[categoryId],
references:[id]
)
assignments AssetAssignment[]
lifecycleEvents AssetLifecycle[]
@@index([tenantId])
@@index([categoryId])
@@index([propertyId])
@@index([status])
}
----
====== Étape 3 — AssetAssignment ======
===== Ajouter =====
model AssetAssignment {
id String
@id
@default(uuid())
assetId String
propertyId String
assignedAt DateTime
@default(now())
unassignedAt DateTime?
assignedBy String?
notes String?
asset Asset
@relation(
fields:[assetId],
references:[id],
onDelete:Cascade
)
@@index([assetId])
@@index([propertyId])
}
----
====== Étape 4 — AssetLifecycle ======
===== Ajouter =====
model AssetLifecycle {
id String
@id
@default(uuid())
assetId String
eventType AssetLifecycleEvent
eventDate DateTime
@default(now())
description String?
cost Decimal?
@db.Decimal(14,2)
metadata Json?
asset Asset
@relation(
fields:[assetId],
references:[id],
onDelete:Cascade
)
@@index([assetId])
@@index([eventType])
@@index([eventDate])
}
----
====== Étape 5 — AssetInventory ======
===== Ajouter =====
model AssetInventory {
id String
@id
@default(uuid())
tenantId String
propertyId String?
inventoryDate DateTime
totalAssets Int
verifiedAssets Int
missingAssets Int
notes String?
createdAt DateTime
@default(now())
@@index([tenantId])
@@index([propertyId])
@@index([inventoryDate])
}
----
====== Étape 6 — AssetTracking ======
===== Ajouter =====
model AssetTracking {
id String
@id
@default(uuid())
assetId String
propertyId String?
locationDescription String?
trackedAt DateTime
@default(now())
source TrackingSource
metadata Json?
@@index([assetId])
@@index([trackedAt])
}
----
====== Étape 7 — Enums ======
===== Ajouter =====
enum AssetStatus {
ACTIVE
IN_STOCK
IN_MAINTENANCE
RETIRED
LOST
DISPOSED
}
enum AssetCondition {
EXCELLENT
GOOD
FAIR
POOR
DAMAGED
}
enum AssetLifecycleEvent {
PURCHASED
ASSIGNED
MOVED
INSPECTED
MAINTAINED
REPAIRED
RETIRED
DISPOSED
}
enum TrackingSource {
MANUAL
QR_CODE
BARCODE
RFID
NFC
IOT
}
----
====== Étape 8 — Migration ======
===== Générer =====
npx prisma migrate dev \
--name asset_management_core
----
====== Sprint 6-B.1-B ======
===== Asset Management Module =====
----
====== Étape 9 — Création ======
src/modules/assets
├── assets
│
├── categories
│
├── assignments
│
├── lifecycle
│
├── inventory
│
├── tracking
│
└── assets.module.ts
----
====== Étape 10 — Services ======
===== Créer =====
AssetService
AssetCategoryService
AssetAssignmentService
AssetLifecycleService
AssetInventoryService
AssetTrackingService
----
====== Sprint 6-B.1-C ======
===== Gestion des Actifs =====
----
====== Étape 11 — AssetService ======
===== Créer =====
asset.service.ts
----
===== Méthodes =====
createAsset()
updateAsset()
retireAsset()
searchAssets()
calculateCurrentValue()
----
====== Étape 12 — Types d'actifs ======
===== Supporter =====
Mobilier
TV
Climatisation
Électroménager
Literie
Sécurité
Équipements extérieurs
----
====== Étape 13 — Codes ======
===== Générer =====
AST-2027-000001
pour chaque actif.
----
====== Sprint 6-B.1-D ======
===== Affectation =====
----
====== Étape 14 — AssetAssignmentService ======
===== Créer =====
asset-assignment.service.ts
----
===== Méthodes =====
assignAsset()
moveAsset()
unassignAsset()
getAssetHistory()
----
====== Étape 15 — Historiser ======
===== Conserver =====
Date
Property
Utilisateur
Action
pour chaque mouvement.
----
====== Sprint 6-B.1-E ======
===== Cycle de Vie =====
----
====== Étape 16 — AssetLifecycleService ======
===== Créer =====
asset-lifecycle.service.ts
----
===== Journaliser =====
Achat
Affectation
Déplacement
Réparation
Retrait
----
====== Étape 17 — Méthodes ======
recordEvent()
getTimeline()
calculateLifecycleCost()
----
====== Étape 18 — Finance ======
===== Préparer =====
Amortissement
CAPEX
OPEX
pour Sprint 6-B.2.
----
====== Sprint 6-B.1-F ======
===== Inventaire =====
----
====== Étape 19 — AssetInventoryService ======
===== Créer =====
asset-inventory.service.ts
----
===== Méthodes =====
createInventory()
verifyAsset()
closeInventory()
generateVarianceReport()
----
====== Étape 20 — Contrôles ======
===== Identifier =====
Actifs présents
Actifs manquants
Actifs déplacés
----
====== Sprint 6-B.1-G ======
===== Tracking =====
----
====== Étape 21 — AssetTrackingService ======
===== Créer =====
asset-tracking.service.ts
----
===== Méthodes =====
trackAsset()
scanQrCode()
scanBarcode()
getLastLocation()
----
====== Étape 22 — Technologies ======
===== Préparer =====
QR Code
Barcode
RFID
NFC
IoT
----
====== Étape 23 — Temps réel ======
===== Supporter =====
Position
Historique
Mouvements
des actifs.
----
====== Sprint 6-B.1-H ======
===== API Asset Management =====
----
====== Étape 24 — Endpoints ======
===== Ajouter =====
GET /assets
GET /assets/{id}
POST /assets
PUT /assets/{id}
DELETE /assets/{id}
POST /assets/{id}/assign
POST /assets/{id}/move
GET /assets/{id}/timeline
GET /assets/inventory
----
====== Étape 25 — Recherche ======
===== Supporter =====
Catégorie
Statut
Property
Condition
Valeur
----
====== Étape 26 — Export ======
===== Ajouter =====
GET /assets/export
Formats :
CSV
Excel
PDF
----
====== Sprint 6-B.1-I ======
===== Sécurité =====
----
====== Étape 27 — Permissions ======
===== Ajouter =====
asset.read
asset.create
asset.update
asset.assign
asset.inventory
asset.dispose
asset.admin
----
====== Étape 28 — Multi-Propriété ======
===== Filtrer =====
par :
Portfolio
PropertyGroup
Property
sur toutes les requêtes.
----
====== Étape 29 — Audit ======
===== Journaliser =====
ASSET_CREATED
ASSET_ASSIGNED
ASSET_MOVED
ASSET_RETIRED
INVENTORY_COMPLETED
TRACKING_SCAN
----
====== Sprint 6-B.1-J ======
===== Préparation Sprint 6-B.2 =====
----
====== Étape 30 — Compatible ======
Préparer :
Depreciation Engine
Asset Valuation
Capital Planning
Lifecycle Forecasting
----
====== Définition de terminé ======
Le Sprint 6-B.1 est terminé lorsque :
✓ Asset créé
✓ AssetCategory créé
✓ AssetAssignment créé
✓ AssetLifecycle créé
✓ AssetInventory créé
✓ AssetTracking créé
✓ Audit intégré
✓ Multi-Property Ready
----
====== Livrables ======
Asset
AssetCategory
AssetAssignment
AssetLifecycle
AssetInventory
AssetTracking
AssetService
AssetAssignmentService
AssetLifecycleService
AssetInventoryService
AssetTrackingService
Enterprise Asset Management Platform
----
====== Sprint 6-B.2 — Asset Intelligence & Lifecycle Management ======
===== Objectif =====
Transformer le registre d'actifs en plateforme patrimoniale Enterprise.
Cette couche permet :
Valorisation
Amortissement
Prévision de cycle de vie
Planification CAPEX
Optimisation maintenance
Pilotage patrimonial
À l'issue de cette étape :
✓ Depreciation Engine
✓ Asset Valuation
✓ Lifecycle Forecasting
✓ Replacement Planning
✓ Maintenance Cost Analytics
✓ Asset Health Score
✓ Asset Intelligence Platform
----
====== Architecture cible ======
Assets
↓
Asset Intelligence Engine
├── Depreciation Engine
├── Asset Valuation
├── Lifecycle Forecasting
├── Replacement Planning
├── Maintenance Analytics
├── Asset Health Scoring
└── AI Recommendations
↓
Portfolio Analytics
↓
Capital Planning
----
====== Sprint 6-B.2-A ======
===== Extension Prisma =====
----
====== Étape 1 — AssetDepreciation ======
===== Ajouter dans schema.prisma =====
model AssetDepreciation {
assetId String
@id
acquisitionValue Decimal
@db.Decimal(14,2)
residualValue Decimal
@db.Decimal(14,2)
usefulLifeYears Int
annualDepreciation Decimal
@db.Decimal(14,2)
accumulatedDepreciation Decimal
@db.Decimal(14,2)
bookValue Decimal
@db.Decimal(14,2)
calculatedAt DateTime
@updatedAt
asset Asset
@relation(
fields:[assetId],
references:[id],
onDelete:Cascade
)
}
----
====== Étape 2 — AssetValuation ======
===== Ajouter =====
model AssetValuation {
id String
@id
@default(uuid())
assetId String
valuationDate DateTime
estimatedValue Decimal
@db.Decimal(14,2)
valuationMethod AssetValuationMethod
confidenceScore Float?
createdAt DateTime
@default(now())
asset Asset
@relation(
fields:[assetId],
references:[id],
onDelete:Cascade
)
@@index([assetId])
@@index([valuationDate])
}
----
====== Étape 3 — AssetForecast ======
===== Ajouter =====
model AssetForecast {
id String
@id
@default(uuid())
assetId String
forecastType AssetForecastType
forecastDate DateTime
predictedValue Float
confidenceScore Float?
createdAt DateTime
@default(now())
@@index([assetId])
@@index([forecastType])
@@index([forecastDate])
}
----
====== Étape 4 — AssetHealthScore ======
===== Ajouter =====
model AssetHealthScore {
assetId String
@id
overallScore Float
conditionScore Float
maintenanceScore Float
utilizationScore Float
ageScore Float
riskScore Float
calculatedAt DateTime
@updatedAt
}
----
====== Étape 5 — AssetRecommendation ======
===== Ajouter =====
model AssetRecommendation {
id String
@id
@default(uuid())
assetId String
recommendationType AssetRecommendationType
priority RecommendationPriority
title String
description String
estimatedCost Decimal?
@db.Decimal(14,2)
estimatedSavings Decimal?
@db.Decimal(14,2)
implemented Boolean
@default(false)
createdAt DateTime
@default(now())
@@index([assetId])
@@index([recommendationType])
@@index([priority])
}
----
====== Étape 6 — Enums ======
===== Ajouter =====
enum AssetValuationMethod {
BOOK_VALUE
MARKET_VALUE
REPLACEMENT_COST
AI_ESTIMATION
}
enum AssetForecastType {
REPLACEMENT
FAILURE_RISK
MAINTENANCE_COST
VALUE_EVOLUTION
}
enum AssetRecommendationType {
REPAIR
REPLACE
UPGRADE
INSPECT
RETIRE
}
enum RecommendationPriority {
LOW
MEDIUM
HIGH
CRITICAL
}
----
====== Étape 7 — Migration ======
===== Générer =====
npx prisma migrate dev \
--name asset_intelligence
----
====== Sprint 6-B.2-B ======
===== Asset Intelligence Module =====
----
====== Étape 8 — Création ======
src/modules/asset-intelligence
├── depreciation
│
├── valuation
│
├── forecasting
│
├── planning
│
├── health
│
├── recommendations
│
└── asset-intelligence.module.ts
----
====== Étape 9 — Services ======
===== Créer =====
DepreciationEngineService
AssetValuationService
LifecycleForecastService
ReplacementPlanningService
MaintenanceCostAnalyticsService
AssetHealthScoreService
AssetRecommendationService
----
====== Sprint 6-B.2-C ======
===== Depreciation Engine =====
----
====== Étape 10 — DepreciationEngineService ======
===== Créer =====
depreciation-engine.service.ts
----
===== Méthodes =====
calculateStraightLine()
calculateBookValue()
calculateAccumulatedDepreciation()
generateDepreciationSchedule()
----
====== Étape 11 — Méthodes comptables ======
===== Supporter =====
Linéaire
Dégressif
Personnalisé
----
====== Étape 12 — Exemple ======
Actif
10 000 €
Durée
5 ans
↓
2 000 €/an
----
====== Sprint 6-B.2-D ======
===== Asset Valuation =====
----
====== Étape 13 — AssetValuationService ======
===== Créer =====
asset-valuation.service.ts
----
===== Méthodes =====
estimateCurrentValue()
estimateReplacementCost()
estimateResidualValue()
----
====== Étape 14 — Facteurs ======
===== Utiliser =====
Âge
État
Maintenance
Utilisation
Marché
----
====== Étape 15 — Valorisation ======
===== Produire =====
Valeur brute
Valeur nette
Valeur marché
Valeur remplacement
----
====== Sprint 6-B.2-E ======
===== Lifecycle Forecasting =====
----
====== Étape 16 — LifecycleForecastService ======
===== Créer =====
lifecycle-forecast.service.ts
----
===== Prévoir =====
Fin de vie
Risque panne
Coût futur
Maintenance future
----
====== Étape 17 — Méthodes ======
forecastReplacement()
forecastFailureRisk()
forecastMaintenanceCost()
----
====== Étape 18 — Exemple ======
Climatisation
Fin de vie estimée
14 mois
----
====== Sprint 6-B.2-F ======
===== Replacement Planning =====
----
====== Étape 19 — ReplacementPlanningService ======
===== Créer =====
replacement-planning.service.ts
----
===== Générer =====
CAPEX Forecast
Replacement Calendar
Investment Plan
----
====== Étape 20 — Priorisation ======
===== Classer =====
selon :
Health Score
Coût maintenance
Criticité
ROI remplacement
----
====== Étape 21 — Exemple ======
2028
12 climatiseurs
↓
CAPEX 42 000 €
----
====== Sprint 6-B.2-G ======
===== Maintenance Cost Analytics =====
----
====== Étape 22 — MaintenanceCostAnalyticsService ======
===== Créer =====
maintenance-cost-analytics.service.ts
----
===== Analyser =====
Coûts maintenance
Coût possession
Coût panne
ROI réparation
----
====== Étape 23 — Sources ======
===== Utiliser =====
MaintenanceWorkOrder
AssetLifecycle
AssetValuation
----
====== Étape 24 — KPI ======
===== Mesurer =====
Maintenance Cost Ratio
Cost Per Asset
Failure Cost
Replacement ROI
----
====== Sprint 6-B.2-H ======
===== Asset Health Score =====
----
====== Étape 25 — AssetHealthScoreService ======
===== Créer =====
asset-health-score.service.ts
----
===== Calcul =====
Condition 30%
Maintenance 25%
Age 20%
Utilization 15%
Risk 10%
----
====== Étape 26 — Classification ======
90-100 Excellent
75-89 Healthy
50-74 Warning
0-49 Critical
----
====== Étape 27 — Exemple ======
Asset Health
92
Excellent
----
====== Sprint 6-B.2-I ======
===== Recommandations IA =====
----
====== Étape 28 — AssetRecommendationService ======
===== Créer =====
asset-recommendation.service.ts
----
===== Générer =====
Remplacement
Réparation
Inspection
Upgrade
Retrait
----
====== Étape 29 — Exemple ======
Climatisation
Health Score 41
↓
Remplacement recommandé
----
====== Étape 30 — Exemple ======
TV
Health Score 82
↓
Maintenance préventive
----
====== Sprint 6-B.2-J ======
===== Dashboard Intelligence =====
----
====== Étape 31 — Endpoints ======
===== Ajouter =====
GET /assets/intelligence
GET /assets/{id}/health
GET /assets/{id}/valuation
GET /assets/{id}/forecast
GET /assets/recommendations
GET /assets/capex-plan
----
====== Étape 32 — Exemple ======
===== Réponse =====
{
"healthScore":92,
"currentValue":8400,
"replacementRisk":"LOW",
"recommendations":[]
}
----
====== Étape 33 — Analytics ======
===== Mesurer =====
Forecast Accuracy
Maintenance Savings
Asset Lifespan
CAPEX Accuracy
Health Score Trends
----
====== Gouvernance ======
----
====== Étape 34 — Permissions ======
===== Ajouter =====
asset.intelligence.read
asset.intelligence.forecast
asset.intelligence.health
asset.intelligence.capex
asset.intelligence.admin
----
====== Étape 35 — Audit ======
===== Journaliser =====
ASSET_HEALTH_UPDATED
ASSET_FORECAST_GENERATED
ASSET_VALUATION_UPDATED
ASSET_RECOMMENDATION_CREATED
CAPEX_PLAN_GENERATED
----
====== Étape 36 — Jobs ======
===== Ajouter =====
Toutes les nuits
Health Score Refresh
Forecast Generation
Valuation Refresh
Recommendation Generation
----
====== Clôture Domaine Asset ======
À la fin du Sprint 6-B.2 :
✓ Asset Registry
✓ Asset Tracking
✓ Asset Lifecycle
✓ Depreciation Engine
✓ Asset Valuation
✓ Forecasting
✓ CAPEX Planning
✓ Asset Intelligence
sont entièrement opérationnels.
----
====== Sprint 6-C.1 — Portfolio Analytics & Multi-Site KPIs ======
===== Objectif =====
Construire le cockpit décisionnel consolidé du parc immobilier.
Cette couche permet d'obtenir une vue globale :
Portefeuilles
Groupes
Propriétés
Revenus
Occupation
Performance
afin de piloter des dizaines, centaines ou milliers de propriétés depuis une interface unique.
À l'issue de cette étape :
✓ Portfolio Dashboard
✓ Portfolio Revenue
✓ Portfolio Occupancy
✓ Portfolio Benchmarking
✓ Multi-Site KPIs
✓ Executive Reporting
✓ Enterprise Portfolio Analytics
----
====== Architecture cible ======
Portfolio
↓
Portfolio Analytics Engine
├── Revenue Analytics
├── Occupancy Analytics
├── Reservation Analytics
├── Property Performance
├── Benchmarking
├── Executive KPIs
└── Reporting
↓
Executive Dashboard
↓
Portfolio Intelligence
----
====== Sprint 6-C.1-A ======
===== Extension Prisma =====
----
====== Étape 1 — PortfolioAnalyticsSnapshot ======
===== Ajouter dans schema.prisma =====
model PortfolioAnalyticsSnapshot {
id String
@id
@default(uuid())
tenantId String
portfolioId String
snapshotDate DateTime
propertiesCount Int
@default(0)
reservationsCount Int
@default(0)
revenue Decimal
@db.Decimal(14,2)
occupancyRate Float?
averageRating Float?
adr Decimal?
@db.Decimal(14,2)
revPar Decimal?
@db.Decimal(14,2)
createdAt DateTime
@default(now())
@@index([tenantId])
@@index([portfolioId])
@@index([snapshotDate])
}
----
====== Étape 2 — PortfolioKPI ======
===== Ajouter =====
model PortfolioKPI {
portfolioId String
@id
occupancyRate Float?
adr Float?
revPar Float?
revenueGrowth Float?
reservationGrowth Float?
guestSatisfaction Float?
updatedAt DateTime
@updatedAt
}
----
====== Étape 3 — PortfolioBenchmark ======
===== Ajouter =====
model PortfolioBenchmark {
id String
@id
@default(uuid())
portfolioId String
metric PortfolioBenchmarkMetric
portfolioValue Float
benchmarkValue Float
variancePercent Float
createdAt DateTime
@default(now())
@@index([portfolioId])
@@index([metric])
}
----
====== Étape 4 — ExecutiveReport ======
===== Ajouter =====
model ExecutiveReport {
id String
@id
@default(uuid())
tenantId String
portfolioId String?
reportType ExecutiveReportType
periodStart DateTime
periodEnd DateTime
generatedAt DateTime
@default(now())
storagePath String?
createdBy String?
@@index([tenantId])
@@index([portfolioId])
@@index([reportType])
}
----
====== Étape 5 — Enums ======
===== Ajouter =====
enum PortfolioBenchmarkMetric {
REVENUE
OCCUPANCY
ADR
REVPAR
SATISFACTION
RESERVATIONS
}
enum ExecutiveReportType {
DAILY
WEEKLY
MONTHLY
QUARTERLY
ANNUAL
CUSTOM
}
----
====== Étape 6 — Migration ======
===== Générer =====
npx prisma migrate dev \
--name portfolio_analytics
----
====== Sprint 6-C.1-B ======
===== Portfolio Analytics Module =====
----
====== Étape 7 — Création ======
src/modules/portfolio-analytics
├── dashboard
│
├── revenue
│
├── occupancy
│
├── benchmarking
│
├── reporting
│
├── kpis
│
└── portfolio-analytics.module.ts
----
====== Étape 8 — Services ======
===== Créer =====
PortfolioDashboardService
PortfolioRevenueService
PortfolioOccupancyService
PortfolioBenchmarkingService
ExecutiveReportingService
PortfolioKPIService
----
====== Sprint 6-C.1-C ======
===== Revenue Analytics =====
----
====== Étape 9 — PortfolioRevenueService ======
===== Créer =====
portfolio-revenue.service.ts
----
===== Calculer =====
Gross Revenue
Net Revenue
Revenue Growth
Revenue By Property
Revenue By Group
----
====== Étape 10 — Sources ======
===== Utiliser =====
Reservations
Invoices
Payments
Refunds
----
====== Étape 11 — KPIs ======
===== Produire =====
ADR
RevPAR
Revenue Per Property
Revenue Per Portfolio
----
====== Sprint 6-C.1-D ======
===== Occupancy Analytics =====
----
====== Étape 12 — PortfolioOccupancyService ======
===== Créer =====
portfolio-occupancy.service.ts
----
===== Mesurer =====
Occupancy Rate
Available Nights
Booked Nights
Lost Nights
Capacity Usage
----
====== Étape 13 — Segmentation ======
===== Analyser =====
par :
Portfolio
Property Group
Property
Region
Category
----
====== Étape 14 — KPIs ======
===== Calculer =====
Occupancy %
Average Stay
Booking Window
Seasonality
----
====== Sprint 6-C.1-E ======
===== Multi-Site KPIs =====
----
====== Étape 15 — PortfolioKPIService ======
===== Créer =====
portfolio-kpi.service.ts
----
===== Agréger =====
Revenue
Occupancy
Reservations
Reviews
Operations
Assets
----
====== Étape 16 — Executive KPIs ======
===== Calculer =====
ADR
RevPAR
Occupancy
Revenue Growth
Guest Satisfaction
Asset Utilization
----
====== Étape 17 — Score Global ======
===== Construire =====
Portfolio Health Score
à partir de :
Revenue
Occupancy
Reviews
Operations
Assets
----
====== Sprint 6-C.1-F ======
===== Benchmarking =====
----
====== Étape 18 — PortfolioBenchmarkingService ======
===== Créer =====
portfolio-benchmarking.service.ts
----
===== Comparer =====
Portfolios
Property Groups
Properties
----
====== Étape 19 — Classements ======
===== Identifier =====
Top Revenue
Top Occupancy
Top Reviews
Top Growth
----
====== Étape 20 — Variances ======
===== Calculer =====
Portfolio
vs
Average Portfolio
----
====== Sprint 6-C.1-G ======
===== Executive Reporting =====
----
====== Étape 21 — ExecutiveReportingService ======
===== Créer =====
executive-reporting.service.ts
----
===== Générer =====
Daily Report
Weekly Report
Monthly Report
Board Report
----
====== Étape 22 — Formats ======
===== Supporter =====
PDF
Excel
CSV
----
====== Étape 23 — Contenu ======
===== Inclure =====
Revenue
Occupancy
Reservations
Incidents
Assets
Forecasts
----
====== Sprint 6-C.1-H ======
===== Portfolio Dashboard =====
----
====== Étape 24 — PortfolioDashboardService ======
===== Créer =====
portfolio-dashboard.service.ts
----
===== Agréger =====
Revenue
Occupancy
Reservations
Properties
Reviews
Assets
----
====== Étape 25 — Endpoint ======
===== Ajouter =====
GET /portfolio/dashboard
GET /portfolio/{id}/dashboard
----
====== Étape 26 — Exemple ======
===== Réponse =====
{
"properties":245,
"occupancy":82.4,
"revenue":8450000,
"adr":142,
"revpar":117,
"portfolioHealth":91
}
----
====== Sprint 6-C.1-I ======
===== API Analytics =====
----
====== Étape 27 — Endpoints ======
===== Ajouter =====
GET /portfolio/analytics/revenue
GET /portfolio/analytics/occupancy
GET /portfolio/analytics/kpis
GET /portfolio/analytics/benchmark
GET /portfolio/reports
POST /portfolio/reports
----
====== Étape 28 — Filtres ======
===== Supporter =====
Portfolio
Property Group
Property
Date Range
Region
Category
----
====== Étape 29 — Export ======
===== Ajouter =====
GET /portfolio/reports/{id}/download
Formats :
PDF
Excel
CSV
----
====== Sprint 6-C.1-J ======
===== Gouvernance =====
----
====== Étape 30 — Permissions ======
===== Ajouter =====
portfolio.analytics.read
portfolio.analytics.export
portfolio.analytics.benchmark
portfolio.analytics.executive
portfolio.analytics.admin
----
====== Étape 31 — Audit ======
===== Journaliser =====
PORTFOLIO_DASHBOARD_VIEWED
PORTFOLIO_KPI_CALCULATED
BENCHMARK_GENERATED
EXECUTIVE_REPORT_CREATED
REPORT_DOWNLOADED
----
====== Étape 32 — Jobs ======
===== Ajouter =====
Toutes les heures
Portfolio KPI Refresh
Toutes les nuits
Analytics Snapshot
Benchmark Refresh
Executive Report Generation
----
====== Préparation Sprint 6-C.2 ======
Compatible avec :
Forecasting
Portfolio Intelligence
Executive AI
Investment Planning
----
====== Définition de terminé ======
Le Sprint 6-C.1 est terminé lorsque :
✓ Portfolio Dashboard créé
✓ Revenue Analytics créé
✓ Occupancy Analytics créé
✓ Benchmarking créé
✓ Executive Reporting créé
✓ Multi-Site KPIs créés
✓ Audit intégré
----
====== Livrables ======
PortfolioAnalyticsSnapshot
PortfolioKPI
PortfolioBenchmark
ExecutiveReport
PortfolioDashboardService
PortfolioRevenueService
PortfolioOccupancyService
PortfolioBenchmarkingService
ExecutiveReportingService
Portfolio Analytics Platform
----
====== Sprint 6-C.2 — Portfolio Intelligence & Prévisions Multi-Sites ======
===== Objectif =====
Transformer les analytics consolidés en plateforme décisionnelle prédictive Enterprise.
Cette couche permet :
Prévisions
Planification stratégique
Détection d'opportunités
Prévisions revenus
Prévisions occupation
Pilotage d'investissement
sur l'ensemble du portefeuille immobilier.
À l'issue de cette étape :
✓ Portfolio Forecasting
✓ Revenue Forecast
✓ Occupancy Forecast
✓ Investment Insights
✓ Portfolio Health Score
✓ Executive AI Insights
✓ Portfolio Intelligence Platform
----
====== Architecture cible ======
Portfolio Analytics
↓
Portfolio Intelligence Engine
├── Revenue Forecast
├── Occupancy Forecast
├── Investment Insights
├── Risk Analysis
├── Portfolio Health Score
├── Executive AI Insights
└── Strategic Recommendations
↓
Executive Management
↓
Investment Planning
----
====== Sprint 6-C.2-A ======
===== Extension Prisma =====
----
====== Étape 1 — PortfolioForecast ======
===== Ajouter dans schema.prisma =====
model PortfolioForecast {
id String
@id
@default(uuid())
tenantId String
portfolioId String
forecastType PortfolioForecastType
forecastDate DateTime
predictedValue Float
confidenceScore Float?
generatedAt DateTime
@default(now())
@@index([tenantId])
@@index([portfolioId])
@@index([forecastType])
@@index([forecastDate])
}
----
====== Étape 2 — PortfolioInsight ======
===== Ajouter =====
model PortfolioInsight {
id String
@id
@default(uuid())
tenantId String
portfolioId String?
category PortfolioInsightCategory
severity InsightSeverity
title String
description String
recommendation String?
impactScore Float?
implemented Boolean
@default(false)
createdAt DateTime
@default(now())
@@index([tenantId])
@@index([portfolioId])
@@index([category])
}
----
====== Étape 3 — PortfolioHealthScore ======
===== Ajouter =====
model PortfolioHealthScore {
portfolioId String
@id
overallScore Float
revenueScore Float
occupancyScore Float
guestScore Float
operationsScore Float
assetScore Float
growthScore Float
calculatedAt DateTime
@updatedAt
}
----
====== Étape 4 — InvestmentRecommendation ======
===== Ajouter =====
model InvestmentRecommendation {
id String
@id
@default(uuid())
portfolioId String
recommendationType InvestmentRecommendationType
priority RecommendationPriority
title String
description String
estimatedInvestment Decimal?
@db.Decimal(14,2)
estimatedReturn Decimal?
@db.Decimal(14,2)
roiPercent Float?
createdAt DateTime
@default(now())
@@index([portfolioId])
@@index([recommendationType])
@@index([priority])
}
----
====== Étape 5 — Enums ======
===== Ajouter =====
enum PortfolioForecastType {
REVENUE
OCCUPANCY
RESERVATIONS
REVPAR
ADR
}
enum PortfolioInsightCategory {
REVENUE
OCCUPANCY
OPERATIONS
ASSETS
INVESTMENT
GROWTH
}
enum InvestmentRecommendationType {
ACQUISITION
RENOVATION
REPLACEMENT
EXPANSION
OPTIMIZATION
DIVESTMENT
}
----
====== Étape 6 — Migration ======
===== Générer =====
npx prisma migrate dev \
--name portfolio_intelligence
----
====== Sprint 6-C.2-B ======
===== Portfolio Intelligence Module =====
----
====== Étape 7 — Création ======
src/modules/portfolio-intelligence
├── forecasts
│
├── revenue
│
├── occupancy
│
├── investments
│
├── health
│
├── insights
│
└── portfolio-intelligence.module.ts
----
====== Étape 8 — Services ======
===== Créer =====
PortfolioForecastService
RevenueForecastService
OccupancyForecastService
InvestmentInsightService
PortfolioHealthScoreService
ExecutiveInsightService
InvestmentRecommendationService
----
====== Sprint 6-C.2-C ======
===== Revenue Forecast =====
----
====== Étape 9 — RevenueForecastService ======
===== Créer =====
revenue-forecast.service.ts
----
===== Méthodes =====
forecastRevenue()
forecastADR()
forecastRevPAR()
forecastGrowth()
----
====== Étape 10 — Sources ======
===== Utiliser =====
Reservations
Payments
Invoices
Portfolio Analytics
Seasonality
----
====== Étape 11 — Prévisions ======
===== Produire =====
30 jours
90 jours
12 mois
----
====== Sprint 6-C.2-D ======
===== Occupancy Forecast =====
----
====== Étape 12 — OccupancyForecastService ======
===== Créer =====
occupancy-forecast.service.ts
----
===== Prévoir =====
Occupancy
Available Nights
Demand
Booking Pace
----
====== Étape 13 — Méthodes ======
forecastOccupancy()
forecastDemand()
forecastSeasonality()
----
====== Étape 14 — Segmentation ======
===== Calculer =====
par :
Portfolio
Property Group
Property
Region
----
====== Sprint 6-C.2-E ======
===== Investment Insights =====
----
====== Étape 15 — InvestmentInsightService ======
===== Créer =====
investment-insight.service.ts
----
===== Identifier =====
Expansion
Renovation
Asset Replacement
Optimization
Divestment
----
====== Étape 16 — Analyse ======
===== Utiliser =====
Revenue
Occupancy
Assets
Maintenance
Guest Satisfaction
----
====== Étape 17 — Exemple ======
Property Group Paris
ROI potentiel
18%
↓
Rénovation recommandée
----
====== Sprint 6-C.2-F ======
===== Portfolio Health Score =====
----
====== Étape 18 — PortfolioHealthScoreService ======
===== Créer =====
portfolio-health-score.service.ts
----
===== Calcul =====
Revenue 25%
Occupancy 20%
Guest Score 15%
Operations 15%
Assets 15%
Growth 10%
----
====== Étape 19 — Classification ======
90-100 Excellent
75-89 Healthy
50-74 Warning
0-49 Critical
----
====== Étape 20 — Exemple ======
Portfolio Health
93
Excellent
----
====== Sprint 6-C.2-G ======
===== Executive AI Insights =====
----
====== Étape 21 — ExecutiveInsightService ======
===== Créer =====
executive-insight.service.ts
----
===== Générer =====
Revenue Opportunities
Occupancy Risks
Growth Opportunities
Asset Risks
Investment Priorities
----
====== Étape 22 — Exemple ======
Les propriétés côtières
↑ 22%
prévision revenus été
↓
Renforcer l'inventaire
----
====== Étape 23 — Exemple ======
Le groupe Europe Nord
↓
Occupation en baisse
-7%
↓
Action recommandée
----
====== Sprint 6-C.2-H ======
===== Recommandations d'Investissement =====
----
====== Étape 24 — InvestmentRecommendationService ======
===== Créer =====
investment-recommendation.service.ts
----
===== Générer =====
CAPEX
Expansion
Acquisition
Renovation
Cession
----
====== Étape 25 — Priorisation ======
===== Utiliser =====
ROI
Health Score
Forecast
Asset Age
Revenue Potential
----
====== Étape 26 — Exemple ======
CAPEX
250 000 €
ROI estimé
31%
----
====== Sprint 6-C.2-I ======
===== Dashboard Intelligence =====
----
====== Étape 27 — Endpoints ======
===== Ajouter =====
GET /portfolio/intelligence
GET /portfolio/forecasts
GET /portfolio/insights
GET /portfolio/health
GET /portfolio/investments
GET /portfolio/recommendations
----
====== Étape 28 — Exemple ======
===== Réponse =====
{
"revenueForecast":12450000,
"occupancyForecast":84.2,
"portfolioHealth":93,
"investmentOpportunities":12
}
----
====== Étape 29 — Analytics IA ======
===== Mesurer =====
Forecast Accuracy
Investment ROI
Health Score Trend
Revenue Prediction Accuracy
Recommendation Adoption
----
====== Sprint 6-C.2-J ======
===== Gouvernance =====
----
====== Étape 30 — Permissions ======
===== Ajouter =====
portfolio.intelligence.read
portfolio.intelligence.forecast
portfolio.intelligence.investment
portfolio.intelligence.health
portfolio.intelligence.executive
----
====== Étape 31 — Audit ======
===== Journaliser =====
PORTFOLIO_FORECAST_GENERATED
PORTFOLIO_HEALTH_UPDATED
EXECUTIVE_INSIGHT_CREATED
INVESTMENT_RECOMMENDATION_CREATED
INTELLIGENCE_DASHBOARD_VIEWED
----
====== Étape 32 — Jobs ======
===== Ajouter =====
Toutes les nuits
Portfolio Forecast Refresh
Portfolio Health Refresh
Executive Insights Generation
Investment Recommendation Refresh
----
====== Clôture Domaine Analytics ======
À la fin du Sprint 6-C.2 :
✓ Portfolio Analytics
✓ Benchmarking
✓ Forecasting
✓ Executive Reporting
✓ Portfolio Health Score
✓ Investment Intelligence
✓ Executive AI Insights
sont entièrement opérationnels.
----
====== Préparation Sprint 6-D ======
Compatible avec :
Governance
Delegation
Approvals
Compliance
Enterprise Controls
----
====== Définition de terminé ======
Le Sprint 6-C.2 est terminé lorsque :
✓ Portfolio Forecasting créé
✓ Revenue Forecast créé
✓ Occupancy Forecast créé
✓ Investment Insights créés
✓ Portfolio Health Score créé
✓ Executive AI Insights créés
✓ Audit intégré
----
====== Livrables ======
PortfolioForecast
PortfolioInsight
PortfolioHealthScore
InvestmentRecommendation
PortfolioForecastService
RevenueForecastService
OccupancyForecastService
InvestmentInsightService
PortfolioHealthScoreService
ExecutiveInsightService
InvestmentRecommendationService
Portfolio Intelligence Platform
----
====== Sprint 6-D.1 — Enterprise Governance & Multi-Site Security ======
===== Objectif =====
Mettre en place la couche de gouvernance Enterprise du parc immobilier.
Cette couche permet de contrôler :
Accès
Délégations
Validations
Conformité
Séparation des responsabilités
Traçabilité
sur l'ensemble des portefeuilles, groupes et propriétés.
À l'issue de cette étape :
✓ Portfolio RBAC
✓ Delegation
✓ Approval Workflow
✓ Compliance Controls
✓ Multi-Site Permissions
✓ Governance Dashboard
✓ Enterprise Governance Platform
----
====== Architecture cible ======
Tenant
↓
Governance Layer
├── RBAC
├── Delegation
├── Approval Workflow
├── Compliance
├── Audit
└── Governance Dashboard
↓
Portfolio
↓
Property Groups
↓
Properties
----
====== Sprint 6-D.1-A ======
===== Extension Prisma =====
----
====== Étape 1 — PortfolioRole ======
===== Ajouter dans schema.prisma =====
model PortfolioRole {
id String
@id
@default(uuid())
tenantId String
name String
code String
description String?
systemRole Boolean
@default(false)
createdAt DateTime
@default(now())
updatedAt DateTime
@updatedAt
permissions PortfolioPermission[]
assignments PortfolioRoleAssignment[]
@@unique([tenantId, code])
@@index([tenantId])
}
----
====== Étape 2 — PortfolioPermission ======
===== Ajouter =====
model PortfolioPermission {
id String
@id
@default(uuid())
roleId String
permission String
role PortfolioRole
@relation(
fields:[roleId],
references:[id],
onDelete:Cascade
)
@@index([roleId])
@@index([permission])
}
----
====== Étape 3 — PortfolioRoleAssignment ======
===== Ajouter =====
model PortfolioRoleAssignment {
id String
@id
@default(uuid())
tenantId String
userId String
roleId String
portfolioId String?
propertyGroupId String?
propertyId String?
assignedAt DateTime
@default(now())
expiresAt DateTime?
role PortfolioRole
@relation(
fields:[roleId],
references:[id]
)
@@index([tenantId])
@@index([userId])
@@index([portfolioId])
@@index([propertyId])
}
----
====== Étape 4 — Delegation ======
===== Ajouter =====
model Delegation {
id String
@id
@default(uuid())
tenantId String
delegatorUserId String
delegateUserId String
portfolioId String?
propertyGroupId String?
propertyId String?
startDate DateTime
endDate DateTime
active Boolean
@default(true)
reason String?
createdAt DateTime
@default(now())
@@index([tenantId])
@@index([delegatorUserId])
@@index([delegateUserId])
}
----
====== Étape 5 — ApprovalRequest ======
===== Ajouter =====
model ApprovalRequest {
id String
@id
@default(uuid())
tenantId String
approvalType ApprovalType
status ApprovalStatus
entityType String
entityId String
requestedBy String
approvedBy String?
requestedAt DateTime
@default(now())
approvedAt DateTime?
comment String?
@@index([tenantId])
@@index([status])
@@index([approvalType])
}
----
====== Étape 6 — ComplianceControl ======
===== Ajouter =====
model ComplianceControl {
id String
@id
@default(uuid())
tenantId String
code String
title String
category ComplianceCategory
enabled Boolean
@default(true)
severity ComplianceSeverity
createdAt DateTime
@default(now())
@@index([tenantId])
@@index([category])
}
----
====== Étape 7 — Enums ======
===== Ajouter =====
enum ApprovalType {
PROPERTY_CREATION
PROPERTY_UPDATE
OWNER_ASSIGNMENT
OPERATOR_ASSIGNMENT
CAPEX_REQUEST
CONTRACT_APPROVAL
}
enum ApprovalStatus {
PENDING
APPROVED
REJECTED
CANCELLED
}
enum ComplianceCategory {
SECURITY
FINANCIAL
LEGAL
GDPR
OPERATIONS
}
enum ComplianceSeverity {
LOW
MEDIUM
HIGH
CRITICAL
}
----
====== Étape 8 — Migration ======
===== Générer =====
npx prisma migrate dev \
--name governance_core
----
====== Sprint 6-D.1-B ======
===== Governance Module =====
----
====== Étape 9 — Création ======
src/modules/governance
├── roles
│
├── permissions
│
├── delegations
│
├── approvals
│
├── compliance
│
├── dashboard
│
└── governance.module.ts
----
====== Étape 10 — Services ======
===== Créer =====
PortfolioRBACService
DelegationService
ApprovalWorkflowService
ComplianceControlService
GovernanceDashboardService
PermissionResolverService
----
====== Sprint 6-D.1-C ======
===== Portfolio RBAC =====
----
====== Étape 11 — PortfolioRBACService ======
===== Créer =====
portfolio-rbac.service.ts
----
===== Rôles système =====
PORTFOLIO_ADMIN
PORTFOLIO_MANAGER
GROUP_MANAGER
PROPERTY_MANAGER
OWNER_VIEWER
AUDITOR
----
====== Étape 12 — Permissions ======
===== Supporter =====
Read
Create
Update
Delete
Approve
Export
Admin
par scope.
----
====== Étape 13 — Scopes ======
===== Appliquer =====
Portfolio
Property Group
Property
sur chaque permission.
----
====== Sprint 6-D.1-D ======
===== Délégations =====
----
====== Étape 14 — DelegationService ======
===== Créer =====
delegation.service.ts
----
===== Méthodes =====
createDelegation()
revokeDelegation()
validateDelegation()
getActiveDelegations()
----
====== Étape 15 — Cas d'usage ======
===== Supporter =====
Congés
Remplacement
Mission temporaire
Support régional
----
====== Étape 16 — Expiration ======
===== Désactiver =====
automatiquement à :
endDate
----
====== Sprint 6-D.1-E ======
===== Workflow d'Approbation =====
----
====== Étape 17 — ApprovalWorkflowService ======
===== Créer =====
approval-workflow.service.ts
----
===== Méthodes =====
submitApproval()
approve()
reject()
cancelApproval()
----
====== Étape 18 — Workflows ======
===== Supporter =====
Nouvelle propriété
Changement propriétaire
CAPEX
Contrat
Suppression actif
----
====== Étape 19 — Validation ======
===== Exiger =====
un approbateur différent du demandeur.
----
====== Sprint 6-D.1-F ======
===== Contrôles de Conformité =====
----
====== Étape 20 — ComplianceControlService ======
===== Créer =====
compliance-control.service.ts
----
===== Vérifier =====
RGPD
Audit
Sécurité
Finance
Exploitation
----
====== Étape 21 — Méthodes ======
runControls()
evaluateCompliance()
createViolation()
closeViolation()
----
====== Étape 22 — Scores ======
===== Calculer =====
Compliance Score
Risk Score
Violation Rate
----
====== Sprint 6-D.1-G ======
===== Dashboard Gouvernance =====
----
====== Étape 23 — GovernanceDashboardService ======
===== Créer =====
governance-dashboard.service.ts
----
===== Afficher =====
Approvals Pending
Active Delegations
Compliance Score
Open Violations
Audit Events
----
====== Étape 24 — KPI ======
===== Mesurer =====
Approval Time
Compliance Rate
Policy Violations
Delegation Usage
Audit Coverage
----
====== Étape 25 — Endpoint ======
===== Ajouter =====
GET /governance/dashboard
----
====== Sprint 6-D.1-H ======
===== API Gouvernance =====
----
====== Étape 26 — Endpoints ======
===== Ajouter =====
GET /governance/roles
POST /governance/roles
GET /governance/delegations
POST /governance/delegations
GET /governance/approvals
POST /governance/approvals
POST /governance/approvals/{id}/approve
POST /governance/approvals/{id}/reject
GET /governance/compliance
----
====== Étape 27 — Exemple ======
===== Approbation =====
{
"approvalType":"CAPEX_REQUEST",
"entityType":"Asset",
"entityId":"ast_123"
}
----
====== Sprint 6-D.1-I ======
===== Sécurité Enterprise =====
----
====== Étape 28 — Permission Resolver ======
===== Créer =====
permission-resolver.service.ts
----
===== Résoudre =====
dans l'ordre :
Role
↓
Delegation
↓
Portfolio Scope
↓
Property Scope
----
====== Étape 29 — Middleware ======
===== Ajouter =====
@RequirePortfolioPermission()
@RequireApproval()
----
====== Étape 30 — Audit ======
===== Journaliser =====
ROLE_ASSIGNED
DELEGATION_CREATED
APPROVAL_SUBMITTED
APPROVAL_APPROVED
COMPLIANCE_CHECK_EXECUTED
----
====== Sprint 6-D.1-J ======
===== Gouvernance Continue =====
----
====== Étape 31 — Jobs ======
===== Ajouter =====
Toutes les heures
Delegation Expiration
Toutes les nuits
Compliance Scan
Approval Escalation
Governance KPI Refresh
----
====== Étape 32 — Permissions ======
===== Ajouter =====
governance.read
governance.manage
governance.approve
governance.compliance
governance.audit
governance.admin
----
====== Préparation Sprint 6-D.2 ======
Compatible avec :
Enterprise Policies
Risk Management
Internal Controls
Governance Intelligence
Audit Automation
----
====== Définition de terminé ======
Le Sprint 6-D.1 est terminé lorsque :
✓ Portfolio RBAC créé
✓ Delegation créée
✓ Approval Workflow créé
✓ Compliance Controls créés
✓ Multi-Site Permissions créées
✓ Governance Dashboard créé
✓ Audit intégré
----
====== Livrables ======
PortfolioRole
PortfolioPermission
PortfolioRoleAssignment
Delegation
ApprovalRequest
ComplianceControl
PortfolioRBACService
DelegationService
ApprovalWorkflowService
ComplianceControlService
GovernanceDashboardService
Enterprise Governance Platform
----
====== Sprint 6-C.2 — Portfolio Intelligence & Prévisions Multi-Sites ======
===== Objectif =====
Transformer les analytics consolidés en plateforme décisionnelle prédictive Enterprise.
Cette couche permet :
Prévisions
Planification stratégique
Détection d'opportunités
Prévisions revenus
Prévisions occupation
Pilotage d'investissement
sur l'ensemble du portefeuille immobilier.
À l'issue de cette étape :
✓ Portfolio Forecasting
✓ Revenue Forecast
✓ Occupancy Forecast
✓ Investment Insights
✓ Portfolio Health Score
✓ Executive AI Insights
✓ Portfolio Intelligence Platform
----
====== Architecture cible ======
Portfolio Analytics
↓
Portfolio Intelligence Engine
├── Revenue Forecast
├── Occupancy Forecast
├── Investment Insights
├── Risk Analysis
├── Portfolio Health Score
├── Executive AI Insights
└── Strategic Recommendations
↓
Executive Management
↓
Investment Planning
----
====== Sprint 6-C.2-A ======
===== Extension Prisma =====
----
====== Étape 1 — PortfolioForecast ======
===== Ajouter dans schema.prisma =====
model PortfolioForecast {
id String
@id
@default(uuid())
tenantId String
portfolioId String
forecastType PortfolioForecastType
forecastDate DateTime
predictedValue Float
confidenceScore Float?
generatedAt DateTime
@default(now())
@@index([tenantId])
@@index([portfolioId])
@@index([forecastType])
@@index([forecastDate])
}
----
====== Étape 2 — PortfolioInsight ======
===== Ajouter =====
model PortfolioInsight {
id String
@id
@default(uuid())
tenantId String
portfolioId String?
category PortfolioInsightCategory
severity InsightSeverity
title String
description String
recommendation String?
impactScore Float?
implemented Boolean
@default(false)
createdAt DateTime
@default(now())
@@index([tenantId])
@@index([portfolioId])
@@index([category])
}
----
====== Étape 3 — PortfolioHealthScore ======
===== Ajouter =====
model PortfolioHealthScore {
portfolioId String
@id
overallScore Float
revenueScore Float
occupancyScore Float
guestScore Float
operationsScore Float
assetScore Float
growthScore Float
calculatedAt DateTime
@updatedAt
}
----
====== Étape 4 — InvestmentRecommendation ======
===== Ajouter =====
model InvestmentRecommendation {
id String
@id
@default(uuid())
portfolioId String
recommendationType InvestmentRecommendationType
priority RecommendationPriority
title String
description String
estimatedInvestment Decimal?
@db.Decimal(14,2)
estimatedReturn Decimal?
@db.Decimal(14,2)
roiPercent Float?
createdAt DateTime
@default(now())
@@index([portfolioId])
@@index([recommendationType])
@@index([priority])
}
----
====== Étape 5 — Enums ======
===== Ajouter =====
enum PortfolioForecastType {
REVENUE
OCCUPANCY
RESERVATIONS
REVPAR
ADR
}
enum PortfolioInsightCategory {
REVENUE
OCCUPANCY
OPERATIONS
ASSETS
INVESTMENT
GROWTH
}
enum InvestmentRecommendationType {
ACQUISITION
RENOVATION
REPLACEMENT
EXPANSION
OPTIMIZATION
DIVESTMENT
}
----
====== Étape 6 — Migration ======
===== Générer =====
npx prisma migrate dev \
--name portfolio_intelligence
----
====== Sprint 6-C.2-B ======
===== Portfolio Intelligence Module =====
----
====== Étape 7 — Création ======
src/modules/portfolio-intelligence
├── forecasts
│
├── revenue
│
├── occupancy
│
├── investments
│
├── health
│
├── insights
│
└── portfolio-intelligence.module.ts
----
====== Étape 8 — Services ======
===== Créer =====
PortfolioForecastService
RevenueForecastService
OccupancyForecastService
InvestmentInsightService
PortfolioHealthScoreService
ExecutiveInsightService
InvestmentRecommendationService
----
====== Sprint 6-C.2-C ======
===== Revenue Forecast =====
----
====== Étape 9 — RevenueForecastService ======
===== Créer =====
revenue-forecast.service.ts
----
===== Méthodes =====
forecastRevenue()
forecastADR()
forecastRevPAR()
forecastGrowth()
----
====== Étape 10 — Sources ======
===== Utiliser =====
Reservations
Payments
Invoices
Portfolio Analytics
Seasonality
----
====== Étape 11 — Prévisions ======
===== Produire =====
30 jours
90 jours
12 mois
----
====== Sprint 6-C.2-D ======
===== Occupancy Forecast =====
----
====== Étape 12 — OccupancyForecastService ======
===== Créer =====
occupancy-forecast.service.ts
----
===== Prévoir =====
Occupancy
Available Nights
Demand
Booking Pace
----
====== Étape 13 — Méthodes ======
forecastOccupancy()
forecastDemand()
forecastSeasonality()
----
====== Étape 14 — Segmentation ======
===== Calculer =====
par :
Portfolio
Property Group
Property
Region
----
====== Sprint 6-C.2-E ======
===== Investment Insights =====
----
====== Étape 15 — InvestmentInsightService ======
===== Créer =====
investment-insight.service.ts
----
===== Identifier =====
Expansion
Renovation
Asset Replacement
Optimization
Divestment
----
====== Étape 16 — Analyse ======
===== Utiliser =====
Revenue
Occupancy
Assets
Maintenance
Guest Satisfaction
----
====== Étape 17 — Exemple ======
Property Group Paris
ROI potentiel
18%
↓
Rénovation recommandée
----
====== Sprint 6-C.2-F ======
===== Portfolio Health Score =====
----
====== Étape 18 — PortfolioHealthScoreService ======
===== Créer =====
portfolio-health-score.service.ts
----
===== Calcul =====
Revenue 25%
Occupancy 20%
Guest Score 15%
Operations 15%
Assets 15%
Growth 10%
----
====== Étape 19 — Classification ======
90-100 Excellent
75-89 Healthy
50-74 Warning
0-49 Critical
----
====== Étape 20 — Exemple ======
Portfolio Health
93
Excellent
----
====== Sprint 6-C.2-G ======
===== Executive AI Insights =====
----
====== Étape 21 — ExecutiveInsightService ======
===== Créer =====
executive-insight.service.ts
----
===== Générer =====
Revenue Opportunities
Occupancy Risks
Growth Opportunities
Asset Risks
Investment Priorities
----
====== Étape 22 — Exemple ======
Les propriétés côtières
↑ 22%
prévision revenus été
↓
Renforcer l'inventaire
----
====== Étape 23 — Exemple ======
Le groupe Europe Nord
↓
Occupation en baisse
-7%
↓
Action recommandée
----
====== Sprint 6-C.2-H ======
===== Recommandations d'Investissement =====
----
====== Étape 24 — InvestmentRecommendationService ======
===== Créer =====
investment-recommendation.service.ts
----
===== Générer =====
CAPEX
Expansion
Acquisition
Renovation
Cession
----
====== Étape 25 — Priorisation ======
===== Utiliser =====
ROI
Health Score
Forecast
Asset Age
Revenue Potential
----
====== Étape 26 — Exemple ======
CAPEX
250 000 €
ROI estimé
31%
----
====== Sprint 6-C.2-I ======
===== Dashboard Intelligence =====
----
====== Étape 27 — Endpoints ======
===== Ajouter =====
GET /portfolio/intelligence
GET /portfolio/forecasts
GET /portfolio/insights
GET /portfolio/health
GET /portfolio/investments
GET /portfolio/recommendations
----
====== Étape 28 — Exemple ======
===== Réponse =====
{
"revenueForecast":12450000,
"occupancyForecast":84.2,
"portfolioHealth":93,
"investmentOpportunities":12
}
----
====== Étape 29 — Analytics IA ======
===== Mesurer =====
Forecast Accuracy
Investment ROI
Health Score Trend
Revenue Prediction Accuracy
Recommendation Adoption
----
====== Sprint 6-C.2-J ======
===== Gouvernance =====
----
====== Étape 30 — Permissions ======
===== Ajouter =====
portfolio.intelligence.read
portfolio.intelligence.forecast
portfolio.intelligence.investment
portfolio.intelligence.health
portfolio.intelligence.executive
----
====== Étape 31 — Audit ======
===== Journaliser =====
PORTFOLIO_FORECAST_GENERATED
PORTFOLIO_HEALTH_UPDATED
EXECUTIVE_INSIGHT_CREATED
INVESTMENT_RECOMMENDATION_CREATED
INTELLIGENCE_DASHBOARD_VIEWED
----
====== Étape 32 — Jobs ======
===== Ajouter =====
Toutes les nuits
Portfolio Forecast Refresh
Portfolio Health Refresh
Executive Insights Generation
Investment Recommendation Refresh
----
====== Clôture Domaine Analytics ======
À la fin du Sprint 6-C.2 :
✓ Portfolio Analytics
✓ Benchmarking
✓ Forecasting
✓ Executive Reporting
✓ Portfolio Health Score
✓ Investment Intelligence
✓ Executive AI Insights
sont entièrement opérationnels.
----
====== Préparation Sprint 6-D ======
Compatible avec :
Governance
Delegation
Approvals
Compliance
Enterprise Controls
----
====== Définition de terminé ======
Le Sprint 6-C.2 est terminé lorsque :
✓ Portfolio Forecasting créé
✓ Revenue Forecast créé
✓ Occupancy Forecast créé
✓ Investment Insights créés
✓ Portfolio Health Score créé
✓ Executive AI Insights créés
✓ Audit intégré
----
====== Livrables ======
PortfolioForecast
PortfolioInsight
PortfolioHealthScore
InvestmentRecommendation
PortfolioForecastService
RevenueForecastService
OccupancyForecastService
InvestmentInsightService
PortfolioHealthScoreService
ExecutiveInsightService
InvestmentRecommendationService
Portfolio Intelligence Platform
----
====== Sprint 6-D.1 — Enterprise Governance & Multi-Site Security ======
===== Objectif =====
Mettre en place la couche de gouvernance Enterprise du parc immobilier.
Cette couche permet de contrôler :
Accès
Délégations
Validations
Conformité
Séparation des responsabilités
Traçabilité
sur l'ensemble des portefeuilles, groupes et propriétés.
À l'issue de cette étape :
✓ Portfolio RBAC
✓ Delegation
✓ Approval Workflow
✓ Compliance Controls
✓ Multi-Site Permissions
✓ Governance Dashboard
✓ Enterprise Governance Platform
----
====== Architecture cible ======
Tenant
↓
Governance Layer
├── RBAC
├── Delegation
├── Approval Workflow
├── Compliance
├── Audit
└── Governance Dashboard
↓
Portfolio
↓
Property Groups
↓
Properties
----
====== Sprint 6-D.1-A ======
===== Extension Prisma =====
----
====== Étape 1 — PortfolioRole ======
===== Ajouter dans schema.prisma =====
model PortfolioRole {
id String
@id
@default(uuid())
tenantId String
name String
code String
description String?
systemRole Boolean
@default(false)
createdAt DateTime
@default(now())
updatedAt DateTime
@updatedAt
permissions PortfolioPermission[]
assignments PortfolioRoleAssignment[]
@@unique([tenantId, code])
@@index([tenantId])
}
----
====== Étape 2 — PortfolioPermission ======
===== Ajouter =====
model PortfolioPermission {
id String
@id
@default(uuid())
roleId String
permission String
role PortfolioRole
@relation(
fields:[roleId],
references:[id],
onDelete:Cascade
)
@@index([roleId])
@@index([permission])
}
----
====== Étape 3 — PortfolioRoleAssignment ======
===== Ajouter =====
model PortfolioRoleAssignment {
id String
@id
@default(uuid())
tenantId String
userId String
roleId String
portfolioId String?
propertyGroupId String?
propertyId String?
assignedAt DateTime
@default(now())
expiresAt DateTime?
role PortfolioRole
@relation(
fields:[roleId],
references:[id]
)
@@index([tenantId])
@@index([userId])
@@index([portfolioId])
@@index([propertyId])
}
----
====== Étape 4 — Delegation ======
===== Ajouter =====
model Delegation {
id String
@id
@default(uuid())
tenantId String
delegatorUserId String
delegateUserId String
portfolioId String?
propertyGroupId String?
propertyId String?
startDate DateTime
endDate DateTime
active Boolean
@default(true)
reason String?
createdAt DateTime
@default(now())
@@index([tenantId])
@@index([delegatorUserId])
@@index([delegateUserId])
}
----
====== Étape 5 — ApprovalRequest ======
===== Ajouter =====
model ApprovalRequest {
id String
@id
@default(uuid())
tenantId String
approvalType ApprovalType
status ApprovalStatus
entityType String
entityId String
requestedBy String
approvedBy String?
requestedAt DateTime
@default(now())
approvedAt DateTime?
comment String?
@@index([tenantId])
@@index([status])
@@index([approvalType])
}
----
====== Étape 6 — ComplianceControl ======
===== Ajouter =====
model ComplianceControl {
id String
@id
@default(uuid())
tenantId String
code String
title String
category ComplianceCategory
enabled Boolean
@default(true)
severity ComplianceSeverity
createdAt DateTime
@default(now())
@@index([tenantId])
@@index([category])
}
----
====== Étape 7 — Enums ======
===== Ajouter =====
enum ApprovalType {
PROPERTY_CREATION
PROPERTY_UPDATE
OWNER_ASSIGNMENT
OPERATOR_ASSIGNMENT
CAPEX_REQUEST
CONTRACT_APPROVAL
}
enum ApprovalStatus {
PENDING
APPROVED
REJECTED
CANCELLED
}
enum ComplianceCategory {
SECURITY
FINANCIAL
LEGAL
GDPR
OPERATIONS
}
enum ComplianceSeverity {
LOW
MEDIUM
HIGH
CRITICAL
}
----
====== Étape 8 — Migration ======
===== Générer =====
npx prisma migrate dev \
--name governance_core
----
====== Sprint 6-D.1-B ======
===== Governance Module =====
----
====== Étape 9 — Création ======
src/modules/governance
├── roles
│
├── permissions
│
├── delegations
│
├── approvals
│
├── compliance
│
├── dashboard
│
└── governance.module.ts
----
====== Étape 10 — Services ======
===== Créer =====
PortfolioRBACService
DelegationService
ApprovalWorkflowService
ComplianceControlService
GovernanceDashboardService
PermissionResolverService
----
====== Sprint 6-D.1-C ======
===== Portfolio RBAC =====
----
====== Étape 11 — PortfolioRBACService ======
===== Créer =====
portfolio-rbac.service.ts
----
===== Rôles système =====
PORTFOLIO_ADMIN
PORTFOLIO_MANAGER
GROUP_MANAGER
PROPERTY_MANAGER
OWNER_VIEWER
AUDITOR
----
====== Étape 12 — Permissions ======
===== Supporter =====
Read
Create
Update
Delete
Approve
Export
Admin
par scope.
----
====== Étape 13 — Scopes ======
===== Appliquer =====
Portfolio
Property Group
Property
sur chaque permission.
----
====== Sprint 6-D.1-D ======
===== Délégations =====
----
====== Étape 14 — DelegationService ======
===== Créer =====
delegation.service.ts
----
===== Méthodes =====
createDelegation()
revokeDelegation()
validateDelegation()
getActiveDelegations()
----
====== Étape 15 — Cas d'usage ======
===== Supporter =====
Congés
Remplacement
Mission temporaire
Support régional
----
====== Étape 16 — Expiration ======
===== Désactiver =====
automatiquement à :
endDate
----
====== Sprint 6-D.1-E ======
===== Workflow d'Approbation =====
----
====== Étape 17 — ApprovalWorkflowService ======
===== Créer =====
approval-workflow.service.ts
----
===== Méthodes =====
submitApproval()
approve()
reject()
cancelApproval()
----
====== Étape 18 — Workflows ======
===== Supporter =====
Nouvelle propriété
Changement propriétaire
CAPEX
Contrat
Suppression actif
----
====== Étape 19 — Validation ======
===== Exiger =====
un approbateur différent du demandeur.
----
====== Sprint 6-D.1-F ======
===== Contrôles de Conformité =====
----
====== Étape 20 — ComplianceControlService ======
===== Créer =====
compliance-control.service.ts
----
===== Vérifier =====
RGPD
Audit
Sécurité
Finance
Exploitation
----
====== Étape 21 — Méthodes ======
runControls()
evaluateCompliance()
createViolation()
closeViolation()
----
====== Étape 22 — Scores ======
===== Calculer =====
Compliance Score
Risk Score
Violation Rate
----
====== Sprint 6-D.1-G ======
===== Dashboard Gouvernance =====
----
====== Étape 23 — GovernanceDashboardService ======
===== Créer =====
governance-dashboard.service.ts
----
===== Afficher =====
Approvals Pending
Active Delegations
Compliance Score
Open Violations
Audit Events
----
====== Étape 24 — KPI ======
===== Mesurer =====
Approval Time
Compliance Rate
Policy Violations
Delegation Usage
Audit Coverage
----
====== Étape 25 — Endpoint ======
===== Ajouter =====
GET /governance/dashboard
----
====== Sprint 6-D.1-H ======
===== API Gouvernance =====
----
====== Étape 26 — Endpoints ======
===== Ajouter =====
GET /governance/roles
POST /governance/roles
GET /governance/delegations
POST /governance/delegations
GET /governance/approvals
POST /governance/approvals
POST /governance/approvals/{id}/approve
POST /governance/approvals/{id}/reject
GET /governance/compliance
----
====== Étape 27 — Exemple ======
===== Approbation =====
{
"approvalType":"CAPEX_REQUEST",
"entityType":"Asset",
"entityId":"ast_123"
}
----
====== Sprint 6-D.1-I ======
===== Sécurité Enterprise =====
----
====== Étape 28 — Permission Resolver ======
===== Créer =====
permission-resolver.service.ts
----
===== Résoudre =====
dans l'ordre :
Role
↓
Delegation
↓
Portfolio Scope
↓
Property Scope
----
====== Étape 29 — Middleware ======
===== Ajouter =====
@RequirePortfolioPermission()
@RequireApproval()
----
====== Étape 30 — Audit ======
===== Journaliser =====
ROLE_ASSIGNED
DELEGATION_CREATED
APPROVAL_SUBMITTED
APPROVAL_APPROVED
COMPLIANCE_CHECK_EXECUTED
----
====== Sprint 6-D.1-J ======
===== Gouvernance Continue =====
----
====== Étape 31 — Jobs ======
===== Ajouter =====
Toutes les heures
Delegation Expiration
Toutes les nuits
Compliance Scan
Approval Escalation
Governance KPI Refresh
----
====== Étape 32 — Permissions ======
===== Ajouter =====
governance.read
governance.manage
governance.approve
governance.compliance
governance.audit
governance.admin
----
====== Préparation Sprint 6-D.2 ======
Compatible avec :
Enterprise Policies
Risk Management
Internal Controls
Governance Intelligence
Audit Automation
----
====== Définition de terminé ======
Le Sprint 6-D.1 est terminé lorsque :
✓ Portfolio RBAC créé
✓ Delegation créée
✓ Approval Workflow créé
✓ Compliance Controls créés
✓ Multi-Site Permissions créées
✓ Governance Dashboard créé
✓ Audit intégré
----
====== Livrables ======
PortfolioRole
PortfolioPermission
PortfolioRoleAssignment
Delegation
ApprovalRequest
ComplianceControl
PortfolioRBACService
DelegationService
ApprovalWorkflowService
ComplianceControlService
GovernanceDashboardService
Enterprise Governance Platform
----
====== Sprint 6-D.2 — Governance Intelligence & Risk Management ======
===== Objectif =====
Transformer la gouvernance opérationnelle en plateforme de pilotage des risques Enterprise.
Cette couche permet :
Gestion des risques
Politiques Enterprise
Contrôles internes
Prévision conformité
Analyse d'audit
Pilotage exécutif
sur l'ensemble des portefeuilles, groupes et propriétés.
À l'issue de cette étape :
✓ Risk Engine
✓ Policy Engine
✓ Segregation of Duties
✓ Audit Intelligence
✓ Compliance Forecasting
✓ Governance Score
✓ Governance Intelligence Platform
----
====== Architecture cible ======
Governance Layer
↓
Governance Intelligence Engine
├── Risk Engine
├── Policy Engine
├── SoD Engine
├── Audit Intelligence
├── Compliance Forecasting
├── Governance Score
└── Executive Recommendations
↓
Executive Governance
↓
Enterprise Controls
----
====== Sprint 6-D.2-A ======
===== Extension Prisma =====
----
====== Étape 1 — GovernanceRisk ======
===== Ajouter dans schema.prisma =====
model GovernanceRisk {
id String
@id
@default(uuid())
tenantId String
portfolioId String?
propertyGroupId String?
propertyId String?
category RiskCategory
severity RiskSeverity
title String
description String
riskScore Float
likelihood Float?
impact Float?
mitigationPlan String?
ownerUserId String?
status RiskStatus
detectedAt DateTime
@default(now())
resolvedAt DateTime?
createdAt DateTime
@default(now())
@@index([tenantId])
@@index([category])
@@index([severity])
@@index([status])
}
----
====== Étape 2 — GovernancePolicy ======
===== Ajouter =====
model GovernancePolicy {
id String
@id
@default(uuid())
tenantId String
code String
title String
description String?
category PolicyCategory
active Boolean
@default(true)
version String
effectiveDate DateTime?
reviewDate DateTime?
createdAt DateTime
@default(now())
updatedAt DateTime
@updatedAt
@@unique([tenantId, code])
@@index([tenantId])
@@index([category])
}
----
====== Étape 3 — SoDViolation ======
===== Ajouter =====
model SoDViolation {
id String
@id
@default(uuid())
tenantId String
userId String
ruleCode String
conflictDescription String
severity RiskSeverity
resolved Boolean
@default(false)
detectedAt DateTime
@default(now())
resolvedAt DateTime?
@@index([tenantId])
@@index([userId])
@@index([resolved])
}
----
====== Étape 4 — GovernanceForecast ======
===== Ajouter =====
model GovernanceForecast {
id String
@id
@default(uuid())
tenantId String
forecastType GovernanceForecastType
forecastDate DateTime
predictedValue Float
confidenceScore Float?
generatedAt DateTime
@default(now())
@@index([tenantId])
@@index([forecastType])
@@index([forecastDate])
}
----
====== Étape 5 — GovernanceScore ======
===== Ajouter =====
model GovernanceScore {
tenantId String
@id
overallScore Float
complianceScore Float
auditScore Float
riskScore Float
controlsScore Float
segregationScore Float
calculatedAt DateTime
@updatedAt
}
----
====== Étape 6 — Enums ======
===== Ajouter =====
enum RiskCategory {
SECURITY
FINANCIAL
OPERATIONAL
COMPLIANCE
LEGAL
GOVERNANCE
}
enum RiskSeverity {
LOW
MEDIUM
HIGH
CRITICAL
}
enum RiskStatus {
OPEN
MITIGATING
ACCEPTED
RESOLVED
}
enum PolicyCategory {
ACCESS
SECURITY
FINANCE
OPERATIONS
GDPR
AUDIT
}
enum GovernanceForecastType {
COMPLIANCE_SCORE
RISK_EXPOSURE
AUDIT_FINDINGS
POLICY_VIOLATIONS
}
----
====== Étape 7 — Migration ======
npx prisma migrate dev \
--name governance_intelligence
----
====== Sprint 6-D.2-B ======
===== Governance Intelligence Module =====
----
====== Étape 8 — Structure ======
src/modules/governance-intelligence
├── risk
├── policy
├── sod
├── audit
├── forecasting
├── scoring
├── recommendations
└── governance-intelligence.module.ts
----
====== Étape 9 — Services ======
RiskEngineService
PolicyEngineService
SegregationOfDutiesService
AuditIntelligenceService
ComplianceForecastingService
GovernanceScoreService
GovernanceRecommendationService
----
====== Sprint 6-D.2-C ======
===== Risk Engine =====
----
====== Étape 10 — RiskEngineService ======
===== Créer =====
risk-engine.service.ts
----
===== Capacités =====
Risk Registry
Risk Scoring
Risk Classification
Risk Mitigation
Risk Monitoring
----
====== Étape 11 — Détecter ======
Accès excessifs
Violations politiques
Fraudes potentielles
Conflits SoD
Défauts conformité
Anomalies d'audit
----
====== Étape 12 — Méthodes ======
detectRisks()
calculateRiskScore()
classifyRisk()
createMitigationPlan()
resolveRisk()
----
====== Sprint 6-D.2-D ======
===== Policy Engine =====
----
====== Étape 13 — PolicyEngineService ======
===== Créer =====
policy-engine.service.ts
----
===== Supporter =====
Policies
Rules
Exceptions
Escalations
Approvals
----
====== Étape 14 — Méthodes ======
evaluatePolicy()
registerException()
validateAction()
triggerEscalation()
auditExecution()
----
====== Étape 15 — Exemples ======
CAPEX > 50 000 €
↓
Double approbation
----
Suppression propriété
↓
Validation exécutive
----
====== Sprint 6-D.2-E ======
===== Segregation of Duties =====
----
====== Étape 16 — SegregationOfDutiesService ======
===== Créer =====
segregation-of-duties.service.ts
----
===== Contrôler =====
Création
Validation
Paiement
Audit
Administration
----
====== Étape 17 — Détection ======
===== Identifier =====
Demandeur + Approbateur
Créateur + Auditeur
Administrateur + Contrôleur
----
====== Étape 18 — Méthodes ======
detectConflict()
validateRoleAssignment()
createViolation()
resolveViolation()
----
====== Sprint 6-D.2-F ======
===== Audit Intelligence =====
----
====== Étape 19 — AuditIntelligenceService ======
===== Créer =====
audit-intelligence.service.ts
----
===== Analyser =====
Audit Logs
Approvals
Permissions
Violations
Incidents
----
====== Étape 20 — Détecter ======
Anomalies
Patterns
Abus potentiels
Contrôles manquants
Zones à risque
----
====== Étape 21 — Méthodes ======
analyzeAuditLogs()
detectAnomalies()
generateFindings()
identifyControlGaps()
----
====== Sprint 6-D.2-G ======
===== Compliance Forecasting =====
----
====== Étape 22 — ComplianceForecastingService ======
===== Créer =====
compliance-forecasting.service.ts
----
===== Prévoir =====
Violations
Audit Findings
Risk Exposure
Compliance Trend
----
====== Étape 23 — Sources ======
Compliance Controls
Audit Logs
Governance Risks
SoD Violations
----
====== Étape 24 — Méthodes ======
forecastCompliance()
forecastRiskExposure()
forecastAuditFindings()
----
====== Sprint 6-D.2-H ======
===== Governance Score =====
----
====== Étape 25 — GovernanceScoreService ======
===== Créer =====
governance-score.service.ts
----
===== Pondération =====
Compliance 25%
Risk 25%
Audit 20%
Controls 15%
SoD 15%
----
====== Étape 26 — Classification ======
90-100 Excellent
75-89 Healthy
50-74 Warning
0-49 Critical
----
====== Étape 27 — Exemple ======
Governance Score
94
Excellent
----
====== Sprint 6-D.2-I ======
===== Executive Intelligence =====
----
====== Étape 28 — GovernanceRecommendationService ======
===== Créer =====
governance-recommendation.service.ts
----
===== Générer =====
Réduction risques
Renforcement contrôles
Corrections conformité
Optimisation processus
Actions audit
----
====== Étape 29 — Exemples ======
18 violations SoD
↓
Séparer les rôles Finance
----
Risque conformité en hausse
↓
Audit ciblé recommandé
----
====== Sprint 6-D.2-J ======
===== Dashboard Intelligence =====
----
====== Étape 30 — Endpoints ======
GET /governance/intelligence
GET /governance/risks
GET /governance/policies
GET /governance/score
GET /governance/forecasts
GET /governance/recommendations
GET /governance/sod
----
====== Étape 31 — Exemple ======
{
"governanceScore":94,
"openRisks":7,
"criticalRisks":1,
"sodViolations":3,
"complianceForecast":91
}
----
====== Étape 32 — Permissions ======
governance.intelligence.read
governance.risk.manage
governance.policy.manage
governance.audit.intelligence
governance.executive
----
====== Étape 33 — Audit ======
RISK_DETECTED
POLICY_VIOLATION
SOD_VIOLATION_CREATED
FORECAST_GENERATED
GOVERNANCE_SCORE_UPDATED
EXECUTIVE_RECOMMENDATION_CREATED
----
====== Étape 34 — Jobs ======
Toutes les heures
Risk Detection
Toutes les nuits
Compliance Forecast Refresh
Governance Score Refresh
Audit Intelligence Refresh
Recommendation Generation
----
====== Clôture Sprint 6 ======
À la fin du Sprint 6 :
✓ Portfolio Management
✓ Asset Management
✓ Portfolio Analytics
✓ Portfolio Intelligence
✓ Enterprise Governance
✓ Risk Management
✓ Executive Controls
sont entièrement opérationnels.
----
====== Préparation Sprint 7 ======
Compatible avec :
Marketplace
OTA
Distribution
Partners
Channels
Revenue Sharing
----
====== Définition de terminé ======
Le Sprint 6-D.2 est terminé lorsque :
✓ Risk Engine créé
✓ Policy Engine créé
✓ Segregation of Duties créée
✓ Audit Intelligence créée
✓ Compliance Forecasting créé
✓ Governance Score créé
✓ Executive Intelligence créée
✓ Gouvernance Enterprise finalisée
----
====== Livrables ======
GovernanceRisk
GovernancePolicy
SoDViolation
GovernanceForecast
GovernanceScore
RiskEngineService
PolicyEngineService
SegregationOfDutiesService
AuditIntelligenceService
ComplianceForecastingService
GovernanceScoreService
GovernanceRecommendationService
Governance Intelligence Platform
----