Modèle de données PostgreSQL (Supabase)
Schéma relationnel normalisé (migration 0001_schema.sql), sécurité au niveau des lignes sur 100 % des tables métier (0002_rls.sql), audit par déclencheurs (0003_audit.sql), jeu de démonstration (0004_seed_demo.sql). Identifiants UUID générés en base, horodatages UTC, montants en numeric exacts. Nommage : français technique sans accents, tables au pluriel.
Vue d'ensemble des entités
organisations 1--N profils (roles) organisations 1--N clients
profils (conseiller) N--N clients via affectations
clients 1--N simulations 1--1 allocations (4 lignes)
simulations 1--N echeances simulations 1--N projections (scenario x mois)
clients 1--N documents (PDF) organisations 1--N hypotheses_scenarios (versionnees)
toutes entites --> audit_log (declencheurs) profils 1--N notifications
Types énumérés
| Type | Valeurs |
role_utilisateur | conseiller · administrateur · conformite · direction |
statut_kyc | a_jour · a_renouveler · expire |
code_scenario | prudent · equilibre · dynamique |
type_echeance | versement_initial · versement_mensuel · versement_exceptionnel · arbitrage |
statut_echeance | planifie · en_cours · valide · rejete · annule |
statut_simulation | brouillon · active · archivee |
classe_actif | actions · obligations · fonds_euros · liquidites |
Tables et champs
organisations · profils · affectations
| Colonne | Type | Description |
| organisations.id / nom | uuid / text | Cabinet ou réseau ; raison sociale affichée (rapports, en-têtes). |
| organisations.frais_gestion_defaut | numeric(5,4) | Frais annuels par défaut des nouvelles simulations (0.0060 = 0,60 %, H-06). |
| profils.user_id | uuid (PK) | Clé du compte d'authentification ; pivot de toutes les politiques RLS. |
| profils.organisation_id / role | uuid / enum | Rattachement (jamais modifiable par l'utilisateur) et rôle applicatif. |
| profils.prenom, nom, actif | text / boolean | Identité affichée ; désactivation immédiate sans suppression. |
| affectations.conseiller_id + client_id | uuid (PK composite) | Relation d'affectation ; fonde le droit d'accès du conseiller. |
clients
| Colonne | Type | Description |
| id, organisation_id | uuid | Identifiant et rattachement d'organisation. |
| civilite, prenom, nom | text | Identité ; la civilité pilote l'accord des libellés (« Cliente depuis »). |
| date_naissance / date_entree_relation | date | Âge affiché au bandeau ; badge d'ancienneté (« depuis 2016 »). |
| patrimoine_estime | numeric(14,2) ≥ 0 | Patrimoine déclaré, affiché en k€ (RG-17). |
| objectif_annee | int (2000 à 2100) | Année cible du projet (« Objectif : 2040 »). |
| profil_investisseur / note_risque | text / int (1 à 10) | Badge du bandeau (RG-09) ; note « n / 10 ». |
| statut_kyc / kyc_valide_jusqu_au | enum / date | Pilotent RG-14 : badge et blocage de l'export. |
| archive, cree_le, modifie_le | boolean / timestamptz | Archivage logique ; horodatages de gestion. |
simulations · allocations · hypotheses_scenarios
| Colonne | Type | Description |
| simulations.libelle / statut | text / enum | Nom métier ; brouillon, active, archivee. Une seule active par client : index partiel unique (RG-02). |
| simulations.horizon_annees | int (1 à 40) | Horizon de projection (titre du graphique). |
| simulations.objectif_capital | numeric(14,2) > 0 | Requis pour la colonne progression (RG-13). |
| simulations.versement_initial / versement_mensuel | numeric(14,2) ≥ 0 | Paramètres du moteur (V0, Vm). |
| simulations.jour_prelevement | int (1 à 28) | Jour des occurrences mensuelles (RG-12). |
| simulations.scenario_defaut / frais_gestion | enum / numeric(5,4) | Scénario présenté par défaut ; frais figés à la création (rejouabilité). |
| simulations.hypotheses_version | int | Version des hypothèses utilisée : clé de la rejouabilité (RG-03). |
| allocations.simulation_id + classe / poids | PK composite / numeric(5,2) | Quatre lignes par simulation ; somme contrôlée à 100,00 par déclencheur différé (RG-04). |
| hypotheses_scenarios.version, scenario, rendement_brut_annuel | int / enum / numeric(6,4) | Jeu versionné par organisation ; seule la version active alimente les nouvelles simulations. |
echeances · projections · documents · notifications · audit_log
| Colonne | Type | Description |
| echeances.date_echeance, type, montant, statut | date / enums / numeric | Cœur de l'échéancier ; contrainte : montant nul si et seulement si arbitrage (RG-10) ; machine à états RG-11. |
| echeances.commentaire | text | Motif de rejet, note de replanification. |
| projections.simulation_id + scenario + mois | PK composite | Séries mensuelles historisées : source unique du graphique et du PDF ; preuve datée (calcule_le, CA-12). |
| documents.type, chemin_storage, taille_octets, genere_par | text / bigint / uuid | Rapport PDF dans le bucket privé « rapports » ; auteur tracé. |
| notifications.titre, corps, lu | text / boolean | Notification applicative (cloche) ; purge à 90 jours. |
| audit_log.entite, entite_id, action, avant, apres | text / jsonb | Preuve d'audit : images avant et après ; table en ajout seul (RG-15), rétention 12 mois. |
Sécurité au niveau des lignes (RLS)
La RLS est activée sur toutes les tables métier ; aucune requête n'y échappe, y compris via l'API REST générée. Fonctions d'aide et politique représentative :
create function fn_org() returns uuid ... -- organisation de l'appelant
create function fn_role() returns role_utilisateur ...
create function fn_client_accessible(cid uuid) returns boolean ...
-- meme organisation ET (role transverse OU affectation conseiller/client)
create policy clients_select on clients for select
using (organisation_id = fn_org() and fn_client_accessible(id));
create policy simulations_all on simulations for all
using (fn_client_accessible(client_id))
with check (organisation_id = fn_org() and fn_client_accessible(client_id));
create policy audit_insert_only on audit_log for insert with check (true);
-- aucune politique update/delete sur audit_log : journal inalterable (RG-15)
Journal d'audit par déclencheurs
La fonction fn_audit() (security definer) insère auteur, horodatage UTC, organisation, entité, action et contenu avant/après (JSON) à chaque insertion, mise à jour ou suppression sur clients, simulations et echeances. Aucune écriture applicative directe : l'application ne peut ni omettre ni falsifier une entrée.
Index de performance
idx_clients_org (organisation_id, nom) : listes et recherche.
idx_echeances_sim_date (simulation_id, date_echeance) : échéancier trié.
idx_documents_client (client_id, cree_le desc) : documents récents.
idx_audit_org_date (organisation_id, survenu_le desc) : consultation du journal.
unq_simulation_active : index partiel unique, une simulation active par client (RG-02).
Jeu de démonstration (seed)
1 organisation, 4 utilisateurs (un par rôle), 25 clients dont Marie Dupont reproduisant les valeurs de la maquette (45 ans, 320 k€, objectif 2040, risque 5/10, profil équilibré, KYC à jour, entrée en relation 2016), sa simulation active (horizon 10 ans, versement initial 5 000 €, mensuel 150 €, allocation 45/30/20/5, frais 0,60 %) et ses 24 échéances dont les 4 lignes visibles de la maquette. Référence des tests visuels (CA-08) et des tests de calcul. Aucune donnée réelle hors production (C-05).