// schemas.ts — forme attendue de chaque JSON de données injecté dans les // moteurs. Source de vérité des fichiers `schemas/.schema.json`, que // `npm run build` réécrit depuis ce module (scripts/ecrire-schemas.mjs) : le // paquet reste sans I/O, et un consommateur peut lire les JSON. // // Sous-ensemble de JSON Schema compris par `valider()` : type (simple ou // liste), required, properties, items, enum, minItems. Vérification // structurelle maison, pas un validateur JSON Schema complet. const nombreOuNull = { type: ['number', 'null'] }; const chaineOuNull = { type: ['string', 'null'] }; const booleenOuNull = { type: ['boolean', 'null'] }; export const SCHEMAS = { postes: { $id: 'https://git.trans-former.fr/jules/moteurs/schemas/postes.schema.json', description: 'Postes du simulateur autonomie (calculs.trans-former.fr/calculs/data/postes.json). Champs lus par les moteurs.', type: 'array', minItems: 1, items: { type: 'object', required: ['Id', 'axe', 'code', 'poste'], properties: { Id: { type: 'integer' }, axe: { type: 'string', enum: ['eau', 'energie', 'alimentation'] }, code: { type: 'string' }, poste: { type: 'string' }, ordre: nombreOuNull, obligatoire: booleenOuNull, actif: booleenOuNull, description: chaineOuNull, }, }, }, options: { $id: 'https://git.trans-former.fr/jules/moteurs/schemas/options.schema.json', description: 'Typologies (options) du simulateur autonomie. Les prix y sont des DONNÉES publiées par calculs, jamais des constantes du paquet. parametre_dim, couplages_requis et couplages_exclus arrivent en JSON sérialisé (NocoDB) ou déjà parsés.', type: 'array', minItems: 1, items: { type: 'object', required: ['Id', 'poste_id', 'code', 'nom'], properties: { Id: { type: 'integer' }, poste_id: { type: 'integer' }, code: { type: 'string' }, nom: { type: 'string' }, typologie: chaineOuNull, actif: booleenOuNull, prix_mat_min: nombreOuNull, prix_mat_max: nombreOuNull, prix_pro_min: nombreOuNull, prix_pro_max: nombreOuNull, prix_par_unite: nombreOuNull, prix_fixe: nombreOuNull, unite: chaineOuNull, quantite_default: nombreOuNull, parametre_dim: { type: ['string', 'object', 'null'] }, couplages_requis: { type: ['string', 'array', 'null'] }, couplages_exclus: { type: ['string', 'array', 'null'] }, flag_diy: booleenOuNull, complexite_pose: nombreOuNull, accessible_fr: booleenOuNull, filiere_agreee: booleenOuNull, surface_min_m2: nombreOuNull, surface_optimale_m2: nombreOuNull, tags: { type: ['array', 'null'] }, source: chaineOuNull, source_date: chaineOuNull, description: chaineOuNull, description_pedago: chaineOuNull, notes_techniques: chaineOuNull, }, }, }, france_climat: { $id: 'https://git.trans-former.fr/jules/moteurs/schemas/france_climat.schema.json', description: 'Une ligne par département (2A, 2B et 971-976 compris) : zone RT, pluviométrie, DJU base 18, zone biogéographique numérique.', type: 'array', minItems: 1, items: { type: 'object', required: ['dept', 'zone_rt'], properties: { dept: { type: 'string' }, nom_dept: chaineOuNull, zone_rt: { type: 'string', enum: ['H1a', 'H1b', 'H1c', 'H2a', 'H2b', 'H2c', 'H2d', 'H3'] }, pluvio_mm_an: nombreOuNull, dju_base_18: nombreOuNull, zone_biogeo: nombreOuNull, source_climat: chaineOuNull, source_date: chaineOuNull, }, }, }, algo_config: { $id: 'https://git.trans-former.fr/jules/moteurs/schemas/algo_config.schema.json', description: 'Heuristiques de conception du simulateur autonomie (poids, modulateurs, matrices, tolérances, alias, poids des postes). Données non sourcées, injectées, jamais importées.', type: 'object', required: ['poids_axes_base', 'modulateurs', 'adequation_weights', 'tolerances', 'bonus_malus', 'couplages_alias', 'postes_poids'], properties: { poids_axes_base: { type: 'object', required: ['eau', 'energie', 'alim'], properties: { eau: { type: 'number' }, energie: { type: 'number' }, alim: { type: 'number' } }, }, modulateurs: { type: 'object' }, adequation_weights: { type: 'object' }, tolerances: { type: 'object', properties: { budget_overrun_pct: { type: 'number' }, budget_underspend_pct: { type: 'number' }, tolerance_par_poste_pct: { type: 'number' }, }, }, bonus_malus: { type: 'object' }, couplages_alias: { type: 'object' }, postes_poids: { type: 'object' }, }, }, }; export const NOMS_TABLES = Object.keys(SCHEMAS);