Architecture¶
ActuaryLab est un module vertical de Quantis : une app FastAPI + Next.js qui ne gère
pas l'authentification mais consomme le SSO du socle Quantis, et scope toutes ses
données à un tenant_schema.
Portée des diagrammes (renommage Quantis → ActuaryLab)
Le projet s'appelait initialement Quantis (le tout), puis Quantis est devenu la
plateforme-mère et ce livrable concret est devenu ActuaryLab (le premier module).
Les anciens diagrammes (docs/architecture/*.svg) sont titrés « Quantis » et dessinés
à l'échelle plateforme : ils mélangent le socle (auth JWT, page d'accueil, App
Super Admin, DB Utilisateur, Percona, Mail) et le module. Ils sont conservés comme
archive historique. Les diagrammes C4 ci-dessous sont scopés ActuaryLab : le socle
Quantis y est un système externe, pas un conteneur interne.
Rendu : modèle C4 (Mermaid flowchart) généré en SVG au build
Le rendu natif C4Container/C4Component de Mermaid empile les formes en colonne et
chevauche les libellés (illisible). On rend donc le modèle C4 avec le moteur
flowchart. Et plutôt que de laisser Mermaid s'exécuter dans le navigateur — où Material
impose son thème (texte sombre) et rend le texte des boîtes illisible —, les diagrammes
sont pré-rendus en SVG statiques (fond blanc, lisibles en clair comme en sombre).
Sémantique C4 : stéréotype («Person», «Container», «Component»,
«Système externe», «BD») + couleur — ■ personne ·
■ conteneur/BD/composant du module ·
■ système externe ; frontière pointillée = périmètre
du module ; trait plein = construit, pointillé = à venir.
Régénérer après modif : mmdc -i docs/architecture/src/<nom>.mmd -o
docs/architecture/<nom>.svg -b "#ffffff" (les sources .mmd sont versionnées sous
docs/architecture/src/).
C4 niveau 2 — Conteneurs (module ActuaryLab)¶
Le socle Quantis est une dépendance externe (il fournit le SSO). À l'intérieur de la
frontière du module : le portail Next.js, le backend FastAPI (qui embarque actuariat_lib
en process), la base, et le stockage documents. Les éléments « à venir » sont annotés —
seuls le SSO, /api/me et /api/dbo sont aujourd'hui construits.
C4 niveau 3 — Composants du backend ActuaryLab¶
Le v0 s'arrêtait au niveau Conteneurs et ne montrait pas le moteur. Or actuariat_lib
(couche pure, validée par les oracles K1/K1-bis) est le cœur du système. Ce diagramme
ouvre le conteneur Backend et fait apparaître le moteur, la route /api/dbo qui
l'appelle, et la frontière SSO.
🔒 Oracle scellé — la persistance reproduit K1
À l'origine, /api/dbo ne prenait population + hypothèses qu'inline dans la requête,
court-circuitant les bases Données RH et Hypothèses. Désormais ces entrées se
persistent (scopées tenant_schema) : JeuHypotheses, Dossier, Salarie
(backend/app/models.py), exposées par app/persistance.py —
POST/GET /api/hypotheses, POST/GET /api/dossiers, et le calcul depuis la base
POST /api/dbo/dossier {dossier_id, jeu_id}. La route inline /api/dbo subsiste comme
calculateur ad-hoc. Garde de l'oracle : K1 reproduit à travers la base
(tests/test_persistance.py → 2 751 205,018849 FCFA). Stockage SQLite (Postgres =
migration mécanique au Jalon 5). L'UI de gestion existe (/studio), l'upload RH
aussi (/demandes, Jalon 1) ; MinIO reprendra storage/ au durcissement.
Le labo d'hypothèses et les sorties du moteur (état 2026-06-10)¶
Au-delà du calcul simple, le backend expose les capacités d'expérimentation par les
paramètres (ADR-0004) et la double sortie
référentielle, toutes scopées tenant et servies par app/labo.py :
| Route | Capacité | Garde |
|---|---|---|
GET /api/hypotheses/{id} · POST …/fork |
détail d'un jeu, fork versionné (lignée) | isolation tenant |
POST /api/hypotheses/{id}/archiver · /restaurer (idem dossiers) |
archivage réversible — masqué des listes, jamais supprimé, calcul par ID préservé (audit) | test calcul-sur-archivé |
POST /api/dbo/comparer |
1 dossier × N jeux, écarts vs référence | monotonie (K1@3,5 % > K1) |
POST /api/dbo/dossier/trace |
facteurs de l'éq. (6) par salarié (mode trace lib 1.2+) — matière du graphe explorable /labo |
produit des facteurs == oracle K1 |
POST /api/dbo/dossier/ohada |
provision déterministe OHADA (droit acquis constaté G(k)·S) + pont exact en 4 facteurs vers la DBO du même jeu (engagements/ohada.py, lib 1.3.0) |
oracle K-OHADA (10 010 000 / ratio 1,1952) |
Le référentiel déterministe est implémenté directement (fonction pure), pas en
dégénérant le pipeline DBO — justification et bornes :
Déterministe OHADA vs DBO. La convention
d'intérêt du waterfall est l'éq. (7) amendée (D-IC, v2.1) : IC′ = (DBO + CSR)·i.
Diagrammes hérités (archive, échelle plateforme)¶
Conservés tels quels — titrés « Quantis », antérieurs au renommage et à l'échelle plateforme (socle + module mêlés). À ne pas lire comme l'architecture du module seul.
Voir les diagrammes hérités
Contexte système (niveau 1) :
Conteneurs v0 (niveau 2, plateforme) :
Rôles utilisateurs (RBAC propagé par Quantis) :
Principes structurants¶
- Pas d'auth interne : JWT signés par Quantis →
/sso/login/→ session locale (cookie signé), aucune tableusersgénérale. ActuaryLab applique le modèle d'identité fédérée du socle (Levier C) : au login, le persona est résolu via la tablesso_link— lien existant → routage (un lien consultant est ré-évalué par match d'email à chaque login : un staff pré-créé après coup est élevé), sinon élévation par match d'email avec un compte staff pré-créé, sinonconsultant_client. Le claimrolen'est jamais traduit en persona — ADR-0003. - Troisième porte (pattern EC, IDENTITE_FEDEREE.md §6) : landing
/acceshors circuit Quantis, gardée parACTUARYLAB_ACCES_DIRECT_SECRET(vide = porte fermée, 404). Sert aux tests multi-personas et de secours. Le persona n'y est pas choisi : même résolution que le SSO — le secret donne l'entrée, jamais l'élévation. - Multi-tenant par
tenant_schema: chaque donnée filtrée au tenant reçu du JWT pour les utilisateurs clients. Les personas staff (junior, senior, externe) traversent les tenants selon leur périmètre de workflow (assignation / transmission), centralisé dansrbac.pyet journalisé — ADR-0006. actuariat_libpure : la couche de calcul actuariel n'importe rien d'un framework web (sa « règle d'or »), ce qui la rend testable et portable. Le backend l'installe depuis les sources du monorepo (ADR-0002).- Doc-as-service : la documentation est un service du stack, pas un déploiement à part (cf. Déployer).
Pour la trajectoire jalons par jalons, voir le Plan d'implémentation.