====== 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 ----