Files
JulesandClaude Fable 5.1 69809df5d1 LOT P1.0 : paquet @transformer/moteurs v0.1.0
Extraction du cœur autonomie de calculs.trans-former.fr (12 modules, sans
singleton, couplages sans mutation, console derrière debug), découpage en trois
moteurs d'axe + intégrateur (mode global = calculs, mode par_axe = plateforme),
moteurs commun.contexte (Corse 2A/2B, DOM 97x corrigés) et commun.geometrie,
table des coefficients harmonisés (docs/CONSTANTES.md pour Jules, R-7),
validation structurelle des données (schemas/), tests hors ligne : 28 assertions
d'origine + épingle générée depuis le code d'astro-pro + écarts d'harmonisation
figés + contrat des moteurs. dist/ committé.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019UBHYPdeQYy2m1GVJp6b12
2026-09-28 17:06:49 +02:00

91 lines
5.0 KiB
Markdown

# @transformer/moteurs
Moteurs de calcul **purs** pour la rénovation et l'autonomie d'une maison, partagés par
[calculs.trans-former.fr](https://calculs.trans-former.fr) et [plateforme.trans-former.fr](https://plateforme.trans-former.fr).
Un moteur reçoit des entrées et des données, rend des sorties **avec ses sources et ses avertissements**,
et ne lit rien d'autre : ni réseau, ni disque, ni horloge. **Jamais de prix dans le paquet** : les prix,
barèmes et tables sont des données publiées ailleurs et injectées.
Licence MIT (le contenu de la plateforme reste sous sa propre licence).
## Ce que le paquet contient (v0.1.0)
| Moteur (`id`) | Entrées | Données injectées | Sorties |
|---|---|---|---|
| `commun.contexte` | code postal | `france_climat` | département (Corse 2A/2B, DOM 97x), zone RT, zone biogéographique, pluviométrie, DJU |
| `commun.geometrie` | emprise, niveaux, hauteur, pente, mitoyenneté, SHAB connue (facultatif) | — | murs extérieurs et opaques, vitrage, toiture, plancher bas, SHAB estimée, volume |
| `autonomie.eau` · `autonomie.energie` · `autonomie.alimentation` | autodiag, budget d'axe, contexte | `postes`, `options`, `algo_config` | postes retenus (typologie, dimension, coût), alternatives, statut, journal des couplages, taux de couverture de l'axe |
| `autonomie.integrateur` | autodiag, budget total, mode `global` (= calculs) ou `par_axe` (= plateforme), axes actifs | idem + `france_climat` | contexte, poids d'axes, budget par axe, sélection par axe, total, statut, taux par axe |
Plus, dans `commun` : la table des coefficients (`COEFFICIENTS`), `valider(table, json)`, les helpers
d'argent (fourchettes, mensualité, annuité) ; dans `autonomie` : le noyau V2 complet (`autonomie.noyau.selectionner`),
les taux de couverture et les prix d'options (`prixOption`, `prixPreset`).
## Consommer
```json
"dependencies": {
"@transformer/moteurs": "git+https://git.trans-former.fr/jules/moteurs.git#v0.1.0"
}
```
Toujours une **étiquette** (`#vX.Y.Z`), jamais une branche : deux sites qui ne calculent pas pareil sans
que personne ne le sache est exactement le risque à éviter. Le dépôt est public, `dist/` est committé :
l'installation ne demande aucune étape de build, seulement `git` sur la machine qui fait `npm ci`
(piège connu : `node:22-alpine` n'a pas `git` → `apk add --no-cache git`).
```ts
import { contexte, eau, integrateur, valider } from '@transformer/moteurs'
// 1. les données viennent de l'extérieur (URL publiée, instantané daté…) et se valident à la frontière
for (const [table, json] of Object.entries(donnees)) {
const v = valider(table, json)
if (!v.ok) throw new Error(v.erreurs.join('\n'))
}
// 2. contexte depuis le code postal
const ctx = contexte.calculer({ code_postal: '31170' }, { france_climat: donnees.france_climat }).sorties
// 3. un moteur d'axe sur son budget
const r = eau.calculer(
{ autodiag: { nb_personnes: 4, surface_toit_m2: 80, surface_parcelle_m2: 800, orientation_toit: 'sud-est', temps_dispo: 2 }, budget_axe: 14000, contexte: ctx },
{ postes: donnees.postes, options: donnees.options, algo_config: donnees.algo_config },
)
r.sorties.postes // typologies retenues, dimensions, coûts
r.sorties.taux_couverture // % du besoin substituable couvert
r.sources // chaque coefficient et chaque prix utilisés, avec source et date
r.avertissements // chaque défaut appliqué, chaque donnée manquante
r.version // '0.1.0'
```
Le mode `global` de l'intégrateur reproduit exactement le simulateur de calculs (pipeline complet,
couplages et réajustement entre axes) ; le mode `par_axe` calcule chaque branche du menu sur son
budget et additionne.
Sous-chemins : `@transformer/moteurs/commun`, `/autonomie`, `/autonomie/eau`, `/autonomie/energie`,
`/autonomie/alimentation`, `/autonomie/integrateur`, `/autonomie/noyau`, `/schemas/<table>.schema.json`,
`/fixtures/<fichier>` (`algo-config.json`, `profils-reference.json`).
## Les coefficients
Chaque grandeur physique existe une fois, dans `src/commun/coefficients.ts`, avec sa source et sa date ;
la version lisible est [`docs/CONSTANTES.md`](docs/CONSTANTES.md) (ancienne valeur → retenue, source,
ce que ça change). Les heuristiques de conception du simulateur (poids d'axes, matrices, tolérances) sont
des données : `fixtures/algo-config.json`, injectées.
## Développer
```bash
npm install # typescript seulement
npm test # build (tsc → dist/, schémas) puis node --test test/ — hors ligne
npm run ecarts # table des écarts origine → harmonisée sur les trois profils de référence
```
Règles du dépôt et carte détaillée : [`AGENTS.md`](AGENTS.md). Jeux de données figés : [`fixtures/README.md`](fixtures/README.md).
## Publier une étiquette
`npm test` vert → `git commit` (avec `dist/` et `schemas/` reconstruits) → `git tag vX.Y.Z` →
`git push && git push --tags` → monter la version chez les consommateurs le même jour. Patch = correction
de formule ; mineur = nouvelle sortie ou nouveau moteur ; majeur = entrée modifiée.