ⓘ Info

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 (référentiel)
  • /catalogue/entitesEntités
  • /catalogue/phasesPhases
  • /catalogue/missionsMissions
  • /catalogue/profilsProfils
  • /catalogue/tauxTaux journaliers
  • /catalogue/presetsPresets de tâches (par mission)
  • /catalogue/parametresParamètres de chiffrage
Marché → sous-marchés
  • /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 / tableRôleChamps clésRelations
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) uniqueTacheModele, Phase
TacheModeleCharge
tache_modele_charge
Charge par défaut (jours) par (tâche-type, phase, profil).nbJoursDefaut, (tacheModeleId, phaseId, profilId) uniqueTacheModele, 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 / tableRôleChamps clésRelations
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 / tableRôleChamps clésRelations
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), ordreMarche, → 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), entiteParentIdMarche, Entite, parent/sousTraitants, → SousMarcheEntite, LigneHonoraire, TacheRaci, MarcheMission
SousMarcheEntite
sous_marche_entite
Prestataires d'un sous-marché (sous-ensemble de l'équipe).(sousMarcheId, marcheEntiteId) uniqueSousMarche, MarcheEntite
MarchePhase
marche_phase
Phase retenue sur un sous-marché (ferme/optionnelle, ordonnable).ordre, typeTranche (FERME/OPTIONNELLE), (sousMarcheId, phaseId) uniqueSousMarche, Phase, → LigneHonoraire, Tache
MarcheMission
marche_mission
Mission portée par une entité titulaire sur un sous-marché.(sousMarcheId, missionId, marcheEntiteId) uniqueSousMarche, Mission, MarcheEntite, → Tache
LigneHonoraire
ligne_honoraire
PIVOT FORFAIT — grain (entité × phase).montantForfait, (marcheEntiteId, marchePhaseId) uniqueMarcheEntite, 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) uniqueTache, Profil
TacheRaci
tache_raci
Matrice RACI : rôle d'une entité sur une tâche.role (R/A/C/I), (tacheId, marcheEntiteId, role) uniqueTache, MarcheEntite

Paramètres de chiffrage

Modèle / tableRôleChamps clésRelations
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.tauxDefaut sinon alerte.
  • Sous-traitance : auto-référence MarcheEntite.entiteParentId.