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
Tenant ↓ Portfolio ├── Property Groups ├── Properties ├── Owners ├── Operators ├── Assets └── Portfolio Analytics ↓ Reservations ↓ Finance ↓ Operations
Le Sprint 6 introduit :
Portfolio PropertyGroup Owner Operator Asset AssetAssignment PortfolioAnalytics PortfolioKPI
Fondation Multi-Propriétés
Portfolio Property Groups Owners Operators
Asset Management
Assets Lifecycle Assignments Maintenance Integration
Portfolio Analytics
Portfolio KPIs Revenue Occupancy Benchmarking Forecasting
Enterprise Governance
Multi-Site RBAC Approvals Compliance Delegation
Portfolio Engine Property Group Management Owner Management Operator Management Asset Platform Portfolio Analytics Enterprise Multi-Site Platform
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
Tenant ↓ Portfolio ├── Property Groups │ ├── Owners │ ├── Operators │ └── Properties ↓ Reservations ↓ Finance ↓ Analytics
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])
}
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])
}
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])
}
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])
}
enum OwnerType {
INDIVIDUAL
COMPANY
INVESTMENT_FUND
REIT
GOVERNMENT
}
portfolioId String?
portfolio Portfolio?
@relation(
fields:[portfolioId],
references:[id]
)
propertyGroupId String?
propertyGroup PropertyGroup?
@relation(
fields:[propertyGroupId],
references:[id]
)
ownerId String?
owner Owner?
@relation(
fields:[ownerId],
references:[id]
)
operatorId String?
operator Operator?
@relation(
fields:[operatorId],
references:[id]
)
@@index([portfolioId]) @@index([propertyGroupId]) @@index([ownerId]) @@index([operatorId])
portfolios Portfolio[] owners Owner[] operators Operator[]
que :
Portfolio PropertyGroup Owner Operator
appartiennent toujours au même :
tenantId
1 Tenant ↓ N Portfolios
1 Portfolio ↓ N Property Groups
1 Owner ↓ N Properties
1 Operator ↓ N Properties
Compatible avec :
Revenue Sharing Owner Statements Commission Engine Asset Accounting
Compatible avec :
Multi-Owner Properties Operator Contracts Portfolio Finance
Compatible avec :
Portfolio Occupancy Group Reservations Multi-Site Reporting
Compatible avec :
Cross Property Search Portfolio Analytics Enterprise Reporting
Compatible avec :
Portfolio Revenue Portfolio Occupancy Benchmarking Forecasting Asset Performance
Compatible avec :
Executive Dashboard Owner Dashboard Operator Dashboard
npx prisma migrate dev \
--name portfolio_core
npx prisma generate
npx prisma studio
Présence de :
Portfolio PropertyGroup Owner Operator
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
Portfolio PropertyGroup Owner Operator OwnerType Portfolio Core Schema
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
Portfolio ├── Property Groups │ ├── Properties │ ├── Owners │ ├── Operators │ └── Portfolio Dashboard ↓ Reservations ↓ Finance ↓ Analytics
src/modules/portfolio ├── portfolio │ ├── property-groups │ ├── owners │ ├── operators │ ├── dashboard │ └── portfolio.module.ts
PortfolioService PropertyGroupService OwnerService OperatorService PortfolioHierarchyService PortfolioDashboardService
PortfolioController PropertyGroupController OwnerController OperatorController PortfolioDashboardController
portfolio.service.ts
createPortfolio() updatePortfolio() archivePortfolio() getPortfolio() getPortfolioSummary()
GET /portfolios
GET /portfolios/{id}
POST /portfolios
PUT /portfolios/{id}
DELETE /portfolios/{id}
tenantId unicité code ownership
sur chaque opération.
property-group.service.ts
createGroup() assignProperty() removeProperty() moveProperty()
Portfolio ↓ Region ↓ City ↓ Properties
GET /property-groups
POST /property-groups
PUT /property-groups/{id}
DELETE /property-groups/{id}
POST /property-groups/{id}/properties
owner.service.ts
createOwner() updateOwner() assignProperty() getOwnerPortfolio()
Personne physique Société Coordonnées Fiscalité Contrats
GET /owners
GET /owners/{id}
POST /owners
PUT /owners/{id}
DELETE /owners/{id}
operator.service.ts
createOperator() updateOperator() assignProperty() getOperatorPerformance()
GET /operators
GET /operators/{id}
POST /operators
PUT /operators/{id}
DELETE /operators/{id}
portfolio-hierarchy.service.ts
Portfolio ↓ PropertyGroup ↓ Property
getTree() getChildren() getAncestors() calculateAggregates()
Properties Count Revenue Occupancy Reservations Reviews
par niveau.
portfolioId propertyGroupId propertyId
comme scopes de sécurité.
Portfolio Admin Portfolio Manager Group Manager Property Manager Owner Viewer
sur toutes les requêtes :
tenantId portfolioId
afin d'éviter toute fuite de données.
@PortfolioScope() @PropertyGroupScope()
pour les futurs modules.
portfolio-dashboard.service.ts
Properties Reservations Revenue Occupancy Reviews Incidents
GET /portfolios/{id}/dashboard
{
"properties":124,
"occupancy":81.4,
"revenue":2450000,
"reservations":8421,
"rating":4.7
}
Revenue Occupancy ADR RevPAR Reservations Guest Satisfaction
GET /portfolios/search GET /owners/search GET /operators/search
Page Limit Sort Filters
sur tous les endpoints.
GET /portfolios/{id}/export
Formats :
CSV Excel PDF
portfolio.read portfolio.create portfolio.update portfolio.delete portfolio.dashboard owner.manage operator.manage
PORTFOLIO_CREATED PORTFOLIO_UPDATED PROPERTY_ASSIGNED OWNER_ASSIGNED OPERATOR_ASSIGNED PORTFOLIO_DASHBOARD_VIEWED
Compatible avec :
Assets Equipment Lifecycle Depreciation Capital Expenditure
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é
PortfolioModule PropertyGroupModule OwnerModule OperatorModule PortfolioHierarchyService PortfolioDashboardService Portfolio Security Layer Enterprise Multi-Property Platform
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
Portfolio ↓ Properties ↓ Asset Management ├── Asset Catalog ├── Asset Assignment ├── Lifecycle ├── Inventory ├── Tracking └── Maintenance Integration ↓ Operations ↓ Finance
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])
}
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])
}
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])
}
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])
}
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])
}
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])
}
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
}
npx prisma migrate dev \
--name asset_management_core
src/modules/assets ├── assets │ ├── categories │ ├── assignments │ ├── lifecycle │ ├── inventory │ ├── tracking │ └── assets.module.ts
AssetService AssetCategoryService AssetAssignmentService AssetLifecycleService AssetInventoryService AssetTrackingService
asset.service.ts
createAsset() updateAsset() retireAsset() searchAssets() calculateCurrentValue()
Mobilier TV Climatisation Électroménager Literie Sécurité Équipements extérieurs
AST-2027-000001
pour chaque actif.
asset-assignment.service.ts
assignAsset() moveAsset() unassignAsset() getAssetHistory()
Date Property Utilisateur Action
pour chaque mouvement.
asset-lifecycle.service.ts
Achat Affectation Déplacement Réparation Retrait
recordEvent() getTimeline() calculateLifecycleCost()
Amortissement CAPEX OPEX
pour Sprint 6-B.2.
asset-inventory.service.ts
createInventory() verifyAsset() closeInventory() generateVarianceReport()
Actifs présents Actifs manquants Actifs déplacés
asset-tracking.service.ts
trackAsset() scanQrCode() scanBarcode() getLastLocation()
QR Code Barcode RFID NFC IoT
Position Historique Mouvements
des actifs.
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
Catégorie Statut Property Condition Valeur
GET /assets/export
Formats :
CSV Excel PDF
asset.read asset.create asset.update asset.assign asset.inventory asset.dispose asset.admin
par :
Portfolio PropertyGroup Property
sur toutes les requêtes.
ASSET_CREATED ASSET_ASSIGNED ASSET_MOVED ASSET_RETIRED INVENTORY_COMPLETED TRACKING_SCAN
Préparer :
Depreciation Engine Asset Valuation Capital Planning Lifecycle Forecasting
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
Asset AssetCategory AssetAssignment AssetLifecycle AssetInventory AssetTracking AssetService AssetAssignmentService AssetLifecycleService AssetInventoryService AssetTrackingService Enterprise Asset Management Platform
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
Assets ↓ Asset Intelligence Engine ├── Depreciation Engine ├── Asset Valuation ├── Lifecycle Forecasting ├── Replacement Planning ├── Maintenance Analytics ├── Asset Health Scoring └── AI Recommendations ↓ Portfolio Analytics ↓ Capital Planning
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
)
}
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])
}
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])
}
model AssetHealthScore {
assetId String
@id
overallScore Float
conditionScore Float
maintenanceScore Float
utilizationScore Float
ageScore Float
riskScore Float
calculatedAt DateTime
@updatedAt
}
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])
}
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
}
npx prisma migrate dev \
--name asset_intelligence
src/modules/asset-intelligence ├── depreciation │ ├── valuation │ ├── forecasting │ ├── planning │ ├── health │ ├── recommendations │ └── asset-intelligence.module.ts
DepreciationEngineService AssetValuationService LifecycleForecastService ReplacementPlanningService MaintenanceCostAnalyticsService AssetHealthScoreService AssetRecommendationService
depreciation-engine.service.ts
calculateStraightLine() calculateBookValue() calculateAccumulatedDepreciation() generateDepreciationSchedule()
Linéaire Dégressif Personnalisé
Actif 10 000 € Durée 5 ans ↓ 2 000 €/an
asset-valuation.service.ts
estimateCurrentValue() estimateReplacementCost() estimateResidualValue()
Âge État Maintenance Utilisation Marché
Valeur brute Valeur nette Valeur marché Valeur remplacement
lifecycle-forecast.service.ts
Fin de vie Risque panne Coût futur Maintenance future
forecastReplacement() forecastFailureRisk() forecastMaintenanceCost()
Climatisation Fin de vie estimée 14 mois
replacement-planning.service.ts
CAPEX Forecast Replacement Calendar Investment Plan
selon :
Health Score Coût maintenance Criticité ROI remplacement
2028 12 climatiseurs ↓ CAPEX 42 000 €
maintenance-cost-analytics.service.ts
Coûts maintenance Coût possession Coût panne ROI réparation
MaintenanceWorkOrder AssetLifecycle AssetValuation
Maintenance Cost Ratio Cost Per Asset Failure Cost Replacement ROI
asset-health-score.service.ts
Condition 30% Maintenance 25% Age 20% Utilization 15% Risk 10%
90-100 Excellent 75-89 Healthy 50-74 Warning 0-49 Critical
Asset Health 92 Excellent
asset-recommendation.service.ts
Remplacement Réparation Inspection Upgrade Retrait
Climatisation Health Score 41 ↓ Remplacement recommandé
TV Health Score 82 ↓ Maintenance préventive
GET /assets/intelligence
GET /assets/{id}/health
GET /assets/{id}/valuation
GET /assets/{id}/forecast
GET /assets/recommendations
GET /assets/capex-plan
{
"healthScore":92,
"currentValue":8400,
"replacementRisk":"LOW",
"recommendations":[]
}
Forecast Accuracy Maintenance Savings Asset Lifespan CAPEX Accuracy Health Score Trends
asset.intelligence.read asset.intelligence.forecast asset.intelligence.health asset.intelligence.capex asset.intelligence.admin
ASSET_HEALTH_UPDATED ASSET_FORECAST_GENERATED ASSET_VALUATION_UPDATED ASSET_RECOMMENDATION_CREATED CAPEX_PLAN_GENERATED
Toutes les nuits Health Score Refresh Forecast Generation Valuation Refresh Recommendation Generation
À 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.
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
Portfolio ↓ Portfolio Analytics Engine ├── Revenue Analytics ├── Occupancy Analytics ├── Reservation Analytics ├── Property Performance ├── Benchmarking ├── Executive KPIs └── Reporting ↓ Executive Dashboard ↓ Portfolio Intelligence
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])
}
model PortfolioKPI {
portfolioId String
@id
occupancyRate Float?
adr Float?
revPar Float?
revenueGrowth Float?
reservationGrowth Float?
guestSatisfaction Float?
updatedAt DateTime
@updatedAt
}
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])
}
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])
}
enum PortfolioBenchmarkMetric {
REVENUE
OCCUPANCY
ADR
REVPAR
SATISFACTION
RESERVATIONS
}
enum ExecutiveReportType {
DAILY
WEEKLY
MONTHLY
QUARTERLY
ANNUAL
CUSTOM
}
npx prisma migrate dev \
--name portfolio_analytics
src/modules/portfolio-analytics ├── dashboard │ ├── revenue │ ├── occupancy │ ├── benchmarking │ ├── reporting │ ├── kpis │ └── portfolio-analytics.module.ts
PortfolioDashboardService PortfolioRevenueService PortfolioOccupancyService PortfolioBenchmarkingService ExecutiveReportingService PortfolioKPIService
portfolio-revenue.service.ts
Gross Revenue Net Revenue Revenue Growth Revenue By Property Revenue By Group
Reservations Invoices Payments Refunds
ADR RevPAR Revenue Per Property Revenue Per Portfolio
portfolio-occupancy.service.ts
Occupancy Rate Available Nights Booked Nights Lost Nights Capacity Usage
par :
Portfolio Property Group Property Region Category
Occupancy % Average Stay Booking Window Seasonality
portfolio-kpi.service.ts
Revenue Occupancy Reservations Reviews Operations Assets
ADR RevPAR Occupancy Revenue Growth Guest Satisfaction Asset Utilization
Portfolio Health Score
à partir de :
Revenue Occupancy Reviews Operations Assets
portfolio-benchmarking.service.ts
Portfolios Property Groups Properties
Top Revenue Top Occupancy Top Reviews Top Growth
Portfolio vs Average Portfolio
executive-reporting.service.ts
Daily Report Weekly Report Monthly Report Board Report
PDF Excel CSV
Revenue Occupancy Reservations Incidents Assets Forecasts
portfolio-dashboard.service.ts
Revenue Occupancy Reservations Properties Reviews Assets
GET /portfolio/dashboard
GET /portfolio/{id}/dashboard
{
"properties":245,
"occupancy":82.4,
"revenue":8450000,
"adr":142,
"revpar":117,
"portfolioHealth":91
}
GET /portfolio/analytics/revenue GET /portfolio/analytics/occupancy GET /portfolio/analytics/kpis GET /portfolio/analytics/benchmark GET /portfolio/reports POST /portfolio/reports
Portfolio Property Group Property Date Range Region Category
GET /portfolio/reports/{id}/download
Formats :
PDF Excel CSV
portfolio.analytics.read portfolio.analytics.export portfolio.analytics.benchmark portfolio.analytics.executive portfolio.analytics.admin
PORTFOLIO_DASHBOARD_VIEWED PORTFOLIO_KPI_CALCULATED BENCHMARK_GENERATED EXECUTIVE_REPORT_CREATED REPORT_DOWNLOADED
Toutes les heures Portfolio KPI Refresh Toutes les nuits Analytics Snapshot Benchmark Refresh Executive Report Generation
Compatible avec :
Forecasting Portfolio Intelligence Executive AI Investment Planning
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é
PortfolioAnalyticsSnapshot PortfolioKPI PortfolioBenchmark ExecutiveReport PortfolioDashboardService PortfolioRevenueService PortfolioOccupancyService PortfolioBenchmarkingService ExecutiveReportingService Portfolio Analytics Platform
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
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
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])
}
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])
}
model PortfolioHealthScore {
portfolioId String
@id
overallScore Float
revenueScore Float
occupancyScore Float
guestScore Float
operationsScore Float
assetScore Float
growthScore Float
calculatedAt DateTime
@updatedAt
}
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])
}
enum PortfolioForecastType {
REVENUE
OCCUPANCY
RESERVATIONS
REVPAR
ADR
}
enum PortfolioInsightCategory {
REVENUE
OCCUPANCY
OPERATIONS
ASSETS
INVESTMENT
GROWTH
}
enum InvestmentRecommendationType {
ACQUISITION
RENOVATION
REPLACEMENT
EXPANSION
OPTIMIZATION
DIVESTMENT
}
npx prisma migrate dev \
--name portfolio_intelligence
src/modules/portfolio-intelligence ├── forecasts │ ├── revenue │ ├── occupancy │ ├── investments │ ├── health │ ├── insights │ └── portfolio-intelligence.module.ts
PortfolioForecastService RevenueForecastService OccupancyForecastService InvestmentInsightService PortfolioHealthScoreService ExecutiveInsightService InvestmentRecommendationService
revenue-forecast.service.ts
forecastRevenue() forecastADR() forecastRevPAR() forecastGrowth()
Reservations Payments Invoices Portfolio Analytics Seasonality
30 jours 90 jours 12 mois
occupancy-forecast.service.ts
Occupancy Available Nights Demand Booking Pace
forecastOccupancy() forecastDemand() forecastSeasonality()
par :
Portfolio Property Group Property Region
investment-insight.service.ts
Expansion Renovation Asset Replacement Optimization Divestment
Revenue Occupancy Assets Maintenance Guest Satisfaction
Property Group Paris ROI potentiel 18% ↓ Rénovation recommandée
portfolio-health-score.service.ts
Revenue 25% Occupancy 20% Guest Score 15% Operations 15% Assets 15% Growth 10%
90-100 Excellent 75-89 Healthy 50-74 Warning 0-49 Critical
Portfolio Health 93 Excellent
executive-insight.service.ts
Revenue Opportunities Occupancy Risks Growth Opportunities Asset Risks Investment Priorities
Les propriétés côtières ↑ 22% prévision revenus été ↓ Renforcer l'inventaire
Le groupe Europe Nord ↓ Occupation en baisse -7% ↓ Action recommandée
investment-recommendation.service.ts
CAPEX Expansion Acquisition Renovation Cession
ROI Health Score Forecast Asset Age Revenue Potential
CAPEX 250 000 € ROI estimé 31%
GET /portfolio/intelligence GET /portfolio/forecasts GET /portfolio/insights GET /portfolio/health GET /portfolio/investments GET /portfolio/recommendations
{
"revenueForecast":12450000,
"occupancyForecast":84.2,
"portfolioHealth":93,
"investmentOpportunities":12
}
Forecast Accuracy Investment ROI Health Score Trend Revenue Prediction Accuracy Recommendation Adoption
portfolio.intelligence.read portfolio.intelligence.forecast portfolio.intelligence.investment portfolio.intelligence.health portfolio.intelligence.executive
PORTFOLIO_FORECAST_GENERATED PORTFOLIO_HEALTH_UPDATED EXECUTIVE_INSIGHT_CREATED INVESTMENT_RECOMMENDATION_CREATED INTELLIGENCE_DASHBOARD_VIEWED
Toutes les nuits Portfolio Forecast Refresh Portfolio Health Refresh Executive Insights Generation Investment Recommendation Refresh
À 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.
Compatible avec :
Governance Delegation Approvals Compliance Enterprise Controls
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é
PortfolioForecast PortfolioInsight PortfolioHealthScore InvestmentRecommendation PortfolioForecastService RevenueForecastService OccupancyForecastService InvestmentInsightService PortfolioHealthScoreService ExecutiveInsightService InvestmentRecommendationService Portfolio Intelligence Platform
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
Tenant ↓ Governance Layer ├── RBAC ├── Delegation ├── Approval Workflow ├── Compliance ├── Audit └── Governance Dashboard ↓ Portfolio ↓ Property Groups ↓ Properties
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])
}
model PortfolioPermission {
id String
@id
@default(uuid())
roleId String
permission String
role PortfolioRole
@relation(
fields:[roleId],
references:[id],
onDelete:Cascade
)
@@index([roleId])
@@index([permission])
}
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])
}
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])
}
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])
}
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])
}
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
}
npx prisma migrate dev \
--name governance_core
src/modules/governance ├── roles │ ├── permissions │ ├── delegations │ ├── approvals │ ├── compliance │ ├── dashboard │ └── governance.module.ts
PortfolioRBACService DelegationService ApprovalWorkflowService ComplianceControlService GovernanceDashboardService PermissionResolverService
portfolio-rbac.service.ts
PORTFOLIO_ADMIN PORTFOLIO_MANAGER GROUP_MANAGER PROPERTY_MANAGER OWNER_VIEWER AUDITOR
Read Create Update Delete Approve Export Admin
par scope.
Portfolio Property Group Property
sur chaque permission.
delegation.service.ts
createDelegation() revokeDelegation() validateDelegation() getActiveDelegations()
Congés Remplacement Mission temporaire Support régional
automatiquement à :
endDate
approval-workflow.service.ts
submitApproval() approve() reject() cancelApproval()
Nouvelle propriété Changement propriétaire CAPEX Contrat Suppression actif
un approbateur différent du demandeur.
compliance-control.service.ts
RGPD Audit Sécurité Finance Exploitation
runControls() evaluateCompliance() createViolation() closeViolation()
Compliance Score Risk Score Violation Rate
governance-dashboard.service.ts
Approvals Pending Active Delegations Compliance Score Open Violations Audit Events
Approval Time Compliance Rate Policy Violations Delegation Usage Audit Coverage
GET /governance/dashboard
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
{
"approvalType":"CAPEX_REQUEST",
"entityType":"Asset",
"entityId":"ast_123"
}
permission-resolver.service.ts
dans l'ordre :
Role ↓ Delegation ↓ Portfolio Scope ↓ Property Scope
@RequirePortfolioPermission() @RequireApproval()
ROLE_ASSIGNED DELEGATION_CREATED APPROVAL_SUBMITTED APPROVAL_APPROVED COMPLIANCE_CHECK_EXECUTED
Toutes les heures Delegation Expiration Toutes les nuits Compliance Scan Approval Escalation Governance KPI Refresh
governance.read governance.manage governance.approve governance.compliance governance.audit governance.admin
Compatible avec :
Enterprise Policies Risk Management Internal Controls Governance Intelligence Audit Automation
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é
PortfolioRole PortfolioPermission PortfolioRoleAssignment Delegation ApprovalRequest ComplianceControl PortfolioRBACService DelegationService ApprovalWorkflowService ComplianceControlService GovernanceDashboardService Enterprise Governance Platform
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
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
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])
}
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])
}
model PortfolioHealthScore {
portfolioId String
@id
overallScore Float
revenueScore Float
occupancyScore Float
guestScore Float
operationsScore Float
assetScore Float
growthScore Float
calculatedAt DateTime
@updatedAt
}
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])
}
enum PortfolioForecastType {
REVENUE
OCCUPANCY
RESERVATIONS
REVPAR
ADR
}
enum PortfolioInsightCategory {
REVENUE
OCCUPANCY
OPERATIONS
ASSETS
INVESTMENT
GROWTH
}
enum InvestmentRecommendationType {
ACQUISITION
RENOVATION
REPLACEMENT
EXPANSION
OPTIMIZATION
DIVESTMENT
}
npx prisma migrate dev \
--name portfolio_intelligence
src/modules/portfolio-intelligence ├── forecasts │ ├── revenue │ ├── occupancy │ ├── investments │ ├── health │ ├── insights │ └── portfolio-intelligence.module.ts
PortfolioForecastService RevenueForecastService OccupancyForecastService InvestmentInsightService PortfolioHealthScoreService ExecutiveInsightService InvestmentRecommendationService
revenue-forecast.service.ts
forecastRevenue() forecastADR() forecastRevPAR() forecastGrowth()
Reservations Payments Invoices Portfolio Analytics Seasonality
30 jours 90 jours 12 mois
occupancy-forecast.service.ts
Occupancy Available Nights Demand Booking Pace
forecastOccupancy() forecastDemand() forecastSeasonality()
par :
Portfolio Property Group Property Region
investment-insight.service.ts
Expansion Renovation Asset Replacement Optimization Divestment
Revenue Occupancy Assets Maintenance Guest Satisfaction
Property Group Paris ROI potentiel 18% ↓ Rénovation recommandée
portfolio-health-score.service.ts
Revenue 25% Occupancy 20% Guest Score 15% Operations 15% Assets 15% Growth 10%
90-100 Excellent 75-89 Healthy 50-74 Warning 0-49 Critical
Portfolio Health 93 Excellent
executive-insight.service.ts
Revenue Opportunities Occupancy Risks Growth Opportunities Asset Risks Investment Priorities
Les propriétés côtières ↑ 22% prévision revenus été ↓ Renforcer l'inventaire
Le groupe Europe Nord ↓ Occupation en baisse -7% ↓ Action recommandée
investment-recommendation.service.ts
CAPEX Expansion Acquisition Renovation Cession
ROI Health Score Forecast Asset Age Revenue Potential
CAPEX 250 000 € ROI estimé 31%
GET /portfolio/intelligence GET /portfolio/forecasts GET /portfolio/insights GET /portfolio/health GET /portfolio/investments GET /portfolio/recommendations
{
"revenueForecast":12450000,
"occupancyForecast":84.2,
"portfolioHealth":93,
"investmentOpportunities":12
}
Forecast Accuracy Investment ROI Health Score Trend Revenue Prediction Accuracy Recommendation Adoption
portfolio.intelligence.read portfolio.intelligence.forecast portfolio.intelligence.investment portfolio.intelligence.health portfolio.intelligence.executive
PORTFOLIO_FORECAST_GENERATED PORTFOLIO_HEALTH_UPDATED EXECUTIVE_INSIGHT_CREATED INVESTMENT_RECOMMENDATION_CREATED INTELLIGENCE_DASHBOARD_VIEWED
Toutes les nuits Portfolio Forecast Refresh Portfolio Health Refresh Executive Insights Generation Investment Recommendation Refresh
À 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.
Compatible avec :
Governance Delegation Approvals Compliance Enterprise Controls
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é
PortfolioForecast PortfolioInsight PortfolioHealthScore InvestmentRecommendation PortfolioForecastService RevenueForecastService OccupancyForecastService InvestmentInsightService PortfolioHealthScoreService ExecutiveInsightService InvestmentRecommendationService Portfolio Intelligence Platform
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
Tenant ↓ Governance Layer ├── RBAC ├── Delegation ├── Approval Workflow ├── Compliance ├── Audit └── Governance Dashboard ↓ Portfolio ↓ Property Groups ↓ Properties
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])
}
model PortfolioPermission {
id String
@id
@default(uuid())
roleId String
permission String
role PortfolioRole
@relation(
fields:[roleId],
references:[id],
onDelete:Cascade
)
@@index([roleId])
@@index([permission])
}
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])
}
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])
}
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])
}
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])
}
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
}
npx prisma migrate dev \
--name governance_core
src/modules/governance ├── roles │ ├── permissions │ ├── delegations │ ├── approvals │ ├── compliance │ ├── dashboard │ └── governance.module.ts
PortfolioRBACService DelegationService ApprovalWorkflowService ComplianceControlService GovernanceDashboardService PermissionResolverService
portfolio-rbac.service.ts
PORTFOLIO_ADMIN PORTFOLIO_MANAGER GROUP_MANAGER PROPERTY_MANAGER OWNER_VIEWER AUDITOR
Read Create Update Delete Approve Export Admin
par scope.
Portfolio Property Group Property
sur chaque permission.
delegation.service.ts
createDelegation() revokeDelegation() validateDelegation() getActiveDelegations()
Congés Remplacement Mission temporaire Support régional
automatiquement à :
endDate
approval-workflow.service.ts
submitApproval() approve() reject() cancelApproval()
Nouvelle propriété Changement propriétaire CAPEX Contrat Suppression actif
un approbateur différent du demandeur.
compliance-control.service.ts
RGPD Audit Sécurité Finance Exploitation
runControls() evaluateCompliance() createViolation() closeViolation()
Compliance Score Risk Score Violation Rate
governance-dashboard.service.ts
Approvals Pending Active Delegations Compliance Score Open Violations Audit Events
Approval Time Compliance Rate Policy Violations Delegation Usage Audit Coverage
GET /governance/dashboard
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
{
"approvalType":"CAPEX_REQUEST",
"entityType":"Asset",
"entityId":"ast_123"
}
permission-resolver.service.ts
dans l'ordre :
Role ↓ Delegation ↓ Portfolio Scope ↓ Property Scope
@RequirePortfolioPermission() @RequireApproval()
ROLE_ASSIGNED DELEGATION_CREATED APPROVAL_SUBMITTED APPROVAL_APPROVED COMPLIANCE_CHECK_EXECUTED
Toutes les heures Delegation Expiration Toutes les nuits Compliance Scan Approval Escalation Governance KPI Refresh
governance.read governance.manage governance.approve governance.compliance governance.audit governance.admin
Compatible avec :
Enterprise Policies Risk Management Internal Controls Governance Intelligence Audit Automation
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é
PortfolioRole PortfolioPermission PortfolioRoleAssignment Delegation ApprovalRequest ComplianceControl PortfolioRBACService DelegationService ApprovalWorkflowService ComplianceControlService GovernanceDashboardService Enterprise Governance Platform
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
Governance Layer ↓ Governance Intelligence Engine ├── Risk Engine ├── Policy Engine ├── SoD Engine ├── Audit Intelligence ├── Compliance Forecasting ├── Governance Score └── Executive Recommendations ↓ Executive Governance ↓ Enterprise Controls
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])
}
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])
}
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])
}
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])
}
model GovernanceScore {
tenantId String
@id
overallScore Float
complianceScore Float
auditScore Float
riskScore Float
controlsScore Float
segregationScore Float
calculatedAt DateTime
@updatedAt
}
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
}
npx prisma migrate dev \
--name governance_intelligence
src/modules/governance-intelligence ├── risk ├── policy ├── sod ├── audit ├── forecasting ├── scoring ├── recommendations └── governance-intelligence.module.ts
RiskEngineService PolicyEngineService SegregationOfDutiesService AuditIntelligenceService ComplianceForecastingService GovernanceScoreService GovernanceRecommendationService
risk-engine.service.ts
Risk Registry Risk Scoring Risk Classification Risk Mitigation Risk Monitoring
Accès excessifs Violations politiques Fraudes potentielles Conflits SoD Défauts conformité Anomalies d'audit
detectRisks() calculateRiskScore() classifyRisk() createMitigationPlan() resolveRisk()
policy-engine.service.ts
Policies Rules Exceptions Escalations Approvals
evaluatePolicy() registerException() validateAction() triggerEscalation() auditExecution()
CAPEX > 50 000 € ↓ Double approbation
Suppression propriété ↓ Validation exécutive
segregation-of-duties.service.ts
Création Validation Paiement Audit Administration
Demandeur + Approbateur Créateur + Auditeur Administrateur + Contrôleur
detectConflict() validateRoleAssignment() createViolation() resolveViolation()
audit-intelligence.service.ts
Audit Logs Approvals Permissions Violations Incidents
Anomalies Patterns Abus potentiels Contrôles manquants Zones à risque
analyzeAuditLogs() detectAnomalies() generateFindings() identifyControlGaps()
compliance-forecasting.service.ts
Violations Audit Findings Risk Exposure Compliance Trend
Compliance Controls Audit Logs Governance Risks SoD Violations
forecastCompliance() forecastRiskExposure() forecastAuditFindings()
governance-score.service.ts
Compliance 25% Risk 25% Audit 20% Controls 15% SoD 15%
90-100 Excellent 75-89 Healthy 50-74 Warning 0-49 Critical
Governance Score 94 Excellent
governance-recommendation.service.ts
Réduction risques Renforcement contrôles Corrections conformité Optimisation processus Actions audit
18 violations SoD ↓ Séparer les rôles Finance
Risque conformité en hausse ↓ Audit ciblé recommandé
GET /governance/intelligence GET /governance/risks GET /governance/policies GET /governance/score GET /governance/forecasts GET /governance/recommendations GET /governance/sod
{
"governanceScore":94,
"openRisks":7,
"criticalRisks":1,
"sodViolations":3,
"complianceForecast":91
}
governance.intelligence.read governance.risk.manage governance.policy.manage governance.audit.intelligence governance.executive
RISK_DETECTED POLICY_VIOLATION SOD_VIOLATION_CREATED FORECAST_GENERATED GOVERNANCE_SCORE_UPDATED EXECUTIVE_RECOMMENDATION_CREATED
Toutes les heures Risk Detection Toutes les nuits Compliance Forecast Refresh Governance Score Refresh Audit Intelligence Refresh Recommendation Generation
À la fin du Sprint 6 :
✓ Portfolio Management ✓ Asset Management ✓ Portfolio Analytics ✓ Portfolio Intelligence ✓ Enterprise Governance ✓ Risk Management ✓ Executive Controls
sont entièrement opérationnels.
Compatible avec :
Marketplace OTA Distribution Partners Channels Revenue Sharing
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
GovernanceRisk GovernancePolicy SoDViolation GovernanceForecast GovernanceScore RiskEngineService PolicyEngineService SegregationOfDutiesService AuditIntelligenceService ComplianceForecastingService GovernanceScoreService GovernanceRecommendationService Governance Intelligence Platform