Aller au contenu

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 Conteneurs — module ActuaryLab

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.

C4 Composants — Backend ActuaryLab

🔒 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.pyPOST/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) :

Contexte système (hérité)

Conteneurs v0 (niveau 2, plateforme) :

Conteneurs v0 (hérité)

Rôles utilisateurs (RBAC propagé par Quantis) :

Rôles des utilisateurs Quantis

Principes structurants

  • Pas d'auth interne : JWT signés par Quantis → /sso/login/ → session locale (cookie signé), aucune table users gé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 table sso_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éé, sinon consultant_client. Le claim role n'est jamais traduit en persona — ADR-0003.
  • Troisième porte (pattern EC, IDENTITE_FEDEREE.md §6) : landing /acces hors circuit Quantis, gardée par ACTUARYLAB_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é dans rbac.py et journalisé — ADR-0006.
  • actuariat_lib pure : 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.