Info — structure du site & modèle de données
Documentation interne, tenue à jour avec le code. Dernière mise à jour : 19 juin 2026.
Stack
- Monorepo npm :
apps/api(NestJS + Prisma + PostgreSQL),apps/web(Next.js App Router + Tailwind + TanStack Query). - Clients API générés par Orval depuis l'OpenAPI de Nest (jamais écrits à la main) —
npm run gen. - Argent en
Prisma.Decimal; écart = forfait − déboursé, recalculé, jamais persisté.
Arborescence du site
/catalogue/entitesEntités/catalogue/phasesPhases/catalogue/missionsMissions/catalogue/profilsProfils/catalogue/tauxTaux journaliers/catalogue/presetsPresets de tâches (par mission)/catalogue/parametresParamètres de chiffrage
/marchesListe des marchés (clic → éditeur de rédaction)/marches/[id]/redactionÉditeur de l'offre à onglets (mode principal : Vue d'ensemble, Offre, chapitres, finance, planning ; pleine hauteur)/marches/[id]Redirige vers l'éditeur (la « Vue d'ensemble » est son 1er onglet)/marches/[id]/offreOffre / devis (ancien éditeur en défilement, via le tiroir « Navigation »)/marches/[id]/sm/[smId]Réglages sous-marché (nom, budget, prestataires)/marches/[id]/sm/[smId]/phasesPhases/marches/[id]/sm/[smId]/missionsMissions/marches/[id]/sm/[smId]/honorairesHonoraires/marches/[id]/sm/[smId]/tachesTâches (charges + RACI + ajout preset à la carte)/marches/[id]/sm/[smId]/planningPlanning (semaines + Gantt)
Un marché porte une équipe (Groupement) partagée et plusieurs sous-marchés. Chaque sous-marché a ses phases, son budget (optionnel), ses prestataires (sous-ensemble de l'équipe), ses honoraires et sa matrice RACI. Cela permet d'isoler les parties hors loi MOP (diagnostic, OPC…) et les tranches optionnelles sur une partie du budget. Paramètres de chiffrage = présets éditables (barème MOE, presets par mission, répartition générique loi MOP). Un marché se navigue désormais par l'éditeur de rédaction à onglets (mode principal) ; la navigation détaillée (sous-marchés, phases, honoraires, ancien éditeur) s'ouvre via le bouton « ☰ Navigation » de l'en-tête. Le bouton « Mode simple » de l'en-tête est un filtre d'affichage global : il focalise la partie marché sur Équilibre Structures (mandataire + Équilibre cotraitant, ses missions, sa colonne d'honoraires et de RACI) sans modifier les données.
Modèle de données — Catalogue (réutilisable)
| Modèle / table | Rôle | Champs clés | Relations |
|---|---|---|---|
Entite entite | Société (BET, archi, économiste…) réutilisable d'un marché à l'autre. Participe au groupement et porte les taux journaliers ; adossée à un Tiers de l'annuaire. | raisonSociale, siret (unique), formeJuridique, tiersId (→ annuaire) | Tiers, → TauxJournalier, MarcheEntite |
Phase phase | Phase loi MOP ou assimilée (FAISA, DIAG, ESQ, APS, APD, PRO, DCE, ACT, VISA, EXE 1/2, DET, AOR, GPA, OPC, SYN). | code (unique), libelle, description, ordre | → MarchePhase, TacheModelePhase, TacheModeleCharge |
Mission mission | Type de mission (ARCH, MDT, STR existant, DIAG, STRUCT…), pilote un preset de tâches. | code (unique), libelle, base, ordre | → MarcheMission, TacheModele |
Profil profil | Profil de collaborateur (DIR, ING, PROJ, TECH) avec taux par défaut. | code (unique), libelle, tauxDefaut | → TauxJournalier, TacheCharge, TacheModeleCharge |
TauxJournalier taux_journalier | Taux journalier par (entité, profil) avec période de validité. | montant, dateDebut, dateFin (null = en cours) | Entite, Profil |
TacheModele tache_modele | Tâche-type hiérarchique d'une mission (preset). | libelle, ordre, parentId (hiérarchie), description (Markdown, défaut) | Mission, parent/enfants, → TacheModelePhase, TacheModeleCharge |
TacheModelePhase tache_modele_phase | Phases qui déclenchent une tâche-type. | (tacheModeleId, phaseId) unique | TacheModele, Phase |
TacheModeleCharge tache_modele_charge | Charge par défaut (jours) par (tâche-type, phase, profil). | nbJoursDefaut, (tacheModeleId, phaseId, profilId) unique | TacheModele, Phase, Profil |
Modèle de données — Annuaire (rapprochement ERP, non branché)
Annuaire local qui épouse la forme de l'ERP interne « Équilibre » (Dolibarr) : Tiers ↔ /api/thirdparties, Edifice ↔ /api/edifices. Aucun branchement actif aujourd'hui : la colonne dolibarrId (vide) servira de pont — l'apparier suffira à relier une fiche locale à l'ERP. Les offres existantes ont été migrées (MOA depuis le texte moa conservé, MOE depuis le mandataire du groupement) sans perte.
| Modèle / table | Rôle | Champs clés | Relations |
|---|---|---|---|
Tiers tiers | Annuaire unifié de sociétés (MOA, MOE/architecte, cotraitants…). Le rôle n'est pas porté par la fiche mais par le contexte (marché : moaTiers/moeTiers ; groupement : Entite.tiers). ↔ /api/thirdparties de l'ERP. | raisonSociale, adresse, codePostal, ville, pays, siret, formeJuridique, email, telephone, url, note, dolibarrId (unique, null = non branché) | → Entite, Marche (moaTiers / moeTiers) |
Edifice edifice | Bâtiment / édifice (le « Lieu » de l'opération), avec GPS. ↔ /api/edifices de l'ERP. | label, nomComplet, adresse, codePostal, ville, departement, pays, gps (« lat,lng »), classification (MH…), epoque, note, dolibarrId (unique) | → Marche (edifice) |
Modèle de données — Transactionnel (par marché)
| Modèle / table | Rôle | Champs clés | Relations |
|---|---|---|---|
Marche marche | Affaire / appel d'offre (≈ Project de l'ERP). Porte l'équipe (groupement), les sous-marchés, et rattache MOA / MOE / édifice. | mission (libellé principal ↔ ERP proposal.mission, remplace l'intitulé), intitule (miroir de mission, conservé pour la compat), moa (texte hérité), dateRemise, moaTiersId, moeTiersId, edificeId, dolibarrId (unique, null = non branché) | moaTiers / moeTiers (Tiers), edifice (Edifice), → MarcheEntite, SousMarche, Offre |
Offre offre | Devis / offre commerciale d'un marché (document PDF éditable). | statut (BROUILLON/ENVOYE/VALIDE/REFUSE), titre, sousTitre, devisNum (↔ proposal.ref), dolibarrId (unique), imageCouverture, moeBloc, versions (tableau manuel), validiteMois, tva, chapitres Markdown (objectifs/enjeux/philosophie/moyens/delais), delaisVisible, planningVisible, exclusions, annexe (dernier chapitre, ex. fiche type de relevé — fusion PDF en aval), financeApproches (par sous-marché). La mission est portée par le marché. | Marche (1-1). Textes-types via paramètre offre_textes. PDF via service WeasyPrint. |
SousMarche sous_marche | Périmètre chiffrable autonome (phases, budget, prestataires, honoraires, tâches). | nom, montantTravauxEstime (optionnel), ordre | Marche, → MarchePhase, MarcheMission, Tache, SousMarcheEntite |
MarcheEntite marche_entite | Membre du groupement (niveau marché ; rôle + sous-traitance par auto-référence). | role (MANDATAIRE/COTRAITANT/SOUSTRAITANT), entiteParentId | Marche, Entite, parent/sousTraitants, → SousMarcheEntite, LigneHonoraire, TacheRaci, MarcheMission |
SousMarcheEntite sous_marche_entite | Prestataires d'un sous-marché (sous-ensemble de l'équipe). | (sousMarcheId, marcheEntiteId) unique | SousMarche, MarcheEntite |
MarchePhase marche_phase | Phase retenue sur un sous-marché (ferme/optionnelle, ordonnable). | ordre, typeTranche (FERME/OPTIONNELLE), (sousMarcheId, phaseId) unique | SousMarche, Phase, → LigneHonoraire, Tache |
MarcheMission marche_mission | Mission portée par une entité titulaire sur un sous-marché. | (sousMarcheId, missionId, marcheEntiteId) unique | SousMarche, Mission, MarcheEntite, → Tache |
LigneHonoraire ligne_honoraire | PIVOT FORFAIT — grain (entité × phase). | montantForfait, (marcheEntiteId, marchePhaseId) unique | MarcheEntite, MarchePhase |
Tache tache | Instance de tâche hiérarchique (par mission × phase) — base du déboursé. | libelle, ordre, parentId, origine (PRESET/MANUEL), description (Markdown), frais (€ fixes non temporels, ajoutés au coût de la feuille), masquerContenu (exclut du chapitre Contenu, reste en finance), semaineDebut/semaineFin (planning, S+1 = notification) | SousMarche, MarcheMission, MarchePhase, parent/enfants, → TacheCharge, TacheRaci |
TacheCharge tache_charge | Charge (jours par profil) sur les tâches feuilles. | nbJours, (tacheId, profilId) unique | Tache, Profil |
TacheRaci tache_raci | Matrice RACI : rôle d'une entité sur une tâche. | role (R/A/C/I), (tacheId, marcheEntiteId, role) unique | Tache, MarcheEntite |
Paramètres de chiffrage
| Modèle / table | Rôle | Champs clés | Relations |
|---|---|---|---|
Parametre parametre | Présets éditables (clé → JSON), partagés entre marchés. | cle = bareme_moe | presets_missions | repartition_loi_mop | offre_textes | salaries_equilibre ; valeur (JSON) | — |
Relations clés
- Forfait au grain entité × phase (
LigneHonoraire, pivot unique). - Mission = responsabilité d'une seule entité (
MarcheMission) ; elle pilote un preset de tâches. - Tâche relève d'une seule mission ; hiérarchique, instanciée par phase. Charges & RACI sur les feuilles uniquement.
- Déboursé = Σ (charges × taux de l'entité titulaire valide à la dateRemise) ; repli sur
Profil.tauxDefautsinon alerte. - Sous-traitance : auto-référence
MarcheEntite.entiteParentId.