Multi-owner Support Guide
Suivi fonctionnel et technique du module de copropriété multi-détenteurs introduit en janvier 2025.
Vue d’ensemble
Objectif : permettre à un lot (unit) d’avoir plusieurs copropriétaires simultanés, chacun avec une quote-part (%), un contact principal et un historique complet.
Backend : logique métier dans
backend/src/application/use_cases/unit_owner_use_cases.rset entitébackend/src/domain/entities/unit_owner.rs.Frontend : composants Svelte centrés sur
frontend/src/components/UnitOwners.svelte,OwnerList.svelte,OwnerCreateModal.svelteetOwnerEditModal.svelte.Tests : couverture via
backend/tests/integration_unit_owner.rs(PostgreSQL réel) et scénarios BDD multi-tenant.
Modèle de données
La table unit_owners crée une relation many-to-many entre units et owners.
CREATE TABLE unit_owners (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
unit_id UUID NOT NULL REFERENCES units(id) ON DELETE CASCADE,
owner_id UUID NOT NULL REFERENCES owners(id) ON DELETE CASCADE,
ownership_percentage DOUBLE PRECISION NOT NULL CHECK (ownership_percentage > 0 AND ownership_percentage <= 1),
start_date TIMESTAMPTZ NOT NULL DEFAULT NOW(),
end_date TIMESTAMPTZ,
is_primary_contact BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(unit_id, owner_id, end_date),
CHECK (end_date IS NULL OR end_date > start_date)
);
Invariants clés
Quote-part : stockée sous forme décimale (
0.25= 25%). La création/mise à jour refuse toute valeur<= 0ou> 1.Somme des quotes-parts :
UnitOwnerUseCases::add_owner_to_unitetupdate_ownership_percentagevérifient que la somme active ne dépasse jamais100 %.Temporalité :
start_dateest fixé à la création,end_dateest rempli lors d’un retrait ou d’un transfert.Contact principal : un seul copropriétaire actif peut être marqué
is_primary_contact = true. La méthode interneunset_all_primary_contactsgarantit l’unicité.
Règles métier & validations
Règle |
Détails |
|---|---|
Création d’un lien |
Le lot et le copropriétaire doivent exister ( |
Unicité active |
Impossible d’ajouter deux fois le même copropriétaire tant que la relation actuelle n’est pas clôturée ( |
Quote-part totale |
Addition de toutes les quotes-part actives ≤ |
Mise à jour |
Impossible de modifier une relation dont |
Transfert |
Clôture automatique de l’ancien propriétaire et création d’une nouvelle relation avec la même quote-part. |
Historique |
Méthodes |
Endpoints API
Tous les endpoints sont préfixés par /api/v1.
Méthode |
Endpoint |
Description |
|---|---|---|
|
|
Liste des copropriétaires actifs d’un lot. |
|
|
Historique complet (actifs + inactifs). |
|
|
Somme actuelle des quotes-parts. |
|
|
Ajoute un copropriétaire ( |
|
|
Termine la relation (renseigne |
|
|
Met à jour la quote-part ou définit le contact principal. |
|
|
Transfère une quote-part d’un propriétaire vers un autre. |
|
|
Tous les lots actifs d’un copropriétaire. |
|
|
Historique complet des lots possédés. |
ℹ️ Les chemins d’update sont centralisés sur
/unit-owners/{id}(contrainte technique : l’identifiant de relation est nécessaire pour conserver l’historique).
DTO principaux
// POST /units/{unit_id}/owners
{
"owner_id": "5a4b1b4b-09f7-4b3f-a591-5c0f0ffbfa98",
"ownership_percentage": 0.4,
"is_primary_contact": true
}
// PUT /unit-owners/{relationship_id}
{
"ownership_percentage": 0.25
}
// POST /units/{unit_id}/owners/transfer
{
"from_owner_id": "0edab1e9-6764-4a22-9d71-6c8a7d72f7bc",
"to_owner_id": "5c613076-2abf-4bf9-b6aa-05260cdc7246"
}
Réponses typiques (UnitOwnerResponseDto) :
{
"id": "8b296dd4-87c5-4d49-8a0a-c44faa7a0f05",
"unit_id": "f216217a-987c-4684-8796-79f6792a4a2a",
"owner_id": "5a4b1b4b-09f7-4b3f-a591-5c0f0ffbfa98",
"ownership_percentage": 0.4,
"start_date": "2025-01-27T10:12:45.123456Z",
"end_date": null,
"is_primary_contact": true,
"is_active": true,
"created_at": "2025-01-27T10:12:45.123456Z",
"updated_at": "2025-01-27T10:12:45.123456Z"
}
Frontend
Composant |
Rôle |
Endpoints consommés |
|---|---|---|
|
Vue embarquée sur la fiche lot (liste actifs, historique optionnel, somme des pourcentages, badges contact principal). |
|
|
Vue tableau paginée des copropriétaires avec accès à leurs lots ( |
|
|
Formulaire de création de copropriétaire (super-admin ⇒ choix organisation). |
|
|
Modification des coordonnées d’un copropriétaire. |
|
|
Vue détaillée des lots détenus par un copropriétaire (actifs + historique). |
|
Le total des quotes-parts est affiché en temps réel et surligné en rouge si ≠ 100 %. Les badges « Contact principal » s’appuient sur is_primary_contact.
Scénarios d’usage
Ajouter un nouveau copropriétaire principal
Créer le copropriétaire via
OwnerCreateModal.Sur la fiche lot, utiliser le bouton « Ajouter » (
POST /units/{unit_id}/owners).Si
is_primary_contact = true, les autres contacts sont automatiquement rétrogradés.
Transférer une quote-part
Appeler
POST /units/{unit_id}/owners/transferavec les identifiants source/cible.L’ancien lien est clôturé (
end_date) et un nouveau lien est créé avec la même quote-part.
Mettre à jour une quote-part suite à un acte notarié
Récupérer l’
idde relation (GET /units/{unit_id}/owners).Appeler
PUT /unit-owners/{id}avec la nouvelleownership_percentage.Vérifier que la somme (
GET /units/{unit_id}/owners/total-percentage) reste =1.0.
Auditer l’historique d’un lot
Consulter
/units/{unit_id}/owners/history.Afficher les périodes
start_date→end_datepour chaque copropriétaire.
Tests & Vérification
Unit tests :
backend/src/domain/entities/unit_owner.rs(validation pourcentage, dates, contact principal).Use cases :
backend/src/application/use_cases/unit_owner_use_cases.rs(validation somme 100 %, transferts).Intégration PostgreSQL :
backend/tests/integration_unit_owner.rs.API : couvertes par les tests BDD génériques (multi-tenancy) et les tests API
owner/unitexistants.Frontend : interactions testées via Playwright (liste des copropriétaires dans
frontend/tests/e2e/dashboards.spec.ts).
Pour valider manuellement :
# Rejouer la batterie de tests liée
make test-unit # inclut les tests domaine
make test-integration # exécute integration_unit_owner.rs
make test-bdd # scénarios Cucumber
Ressources liées
backend/migrations/20250127000000_refactor_owners_multitenancy.sqlbackend/src/infrastructure/web/handlers/unit_owner_handlers.rsdocs/GIT_HOOKS.rst– prérequis qualité (pre-commit/pre-push)README.md– aperçu des fonctionnalités multi-ownerCLAUDE.md– architecture et règlement de contribution
✨ Checklist release
base de données migrée (
sqlx migrate run)cache SQLx préparé (
cargo sqlx prepare)tests verts (
make test)documentation Sphinx reconstruite (
make docs-sphinx)guides frontend/ops mis à jour