Ceci est une ancienne révision du document !
Table des matières
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