{
  "openapi": "3.0.4",
  "info": {
    "title": "WattMind Energy API",
    "description": "API d'intelligence carbone & énergétique du réseau électrique français.\n\nAgrège 15 signaux RTE (Ecowatt, Tempo, génération, prix, marges...) en un score 0-100 sur 4 dimensions (prix, carbone, réseau, adéquation), actionnable en temps réel et en prévision horaire.\n\n**Rate Limiting** : Chaque réponse inclut des headers de quota :\n- `X-RateLimit-Limit-Minute` / `X-RateLimit-Remaining-Minute`\n- `X-RateLimit-Limit-Month` / `X-RateLimit-Remaining-Month`\n- `Retry-After` (secondes) en cas de dépassement (HTTP 429)\n- `X-WattMind-Confidence` : `degraded` si certaines sources sont indisponibles\n\n**Plans** : Starter (10 req/min, 3k/mois), Pro (60 req/min, 30k/mois), Scale (200 req/min, 150k/mois).",
    "contact": {
      "name": "WattMind",
      "email": "contact@wattmind.fr"
    },
    "version": "v1"
  },
  "paths": {
    "/v1/carbon/intensity": {
      "get": {
        "tags": [
          "CarbonIntensity"
        ],
        "summary": "Intensité carbone temps réel du réseau électrique français.\nRetourne le pourcentage de production décarbonée, la part renouvelable,\net le facteur d'émission estimé (gCO2eq/kWh).",
        "description": "Idéal pour le reporting scope 2 (CSRD/BEGES) en \"location-based\" et \"market-based\".",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CarbonIntensityResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CarbonIntensityResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CarbonIntensityResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable"
          }
        }
      }
    },
    "/v1/score": {
      "get": {
        "tags": [
          "EnergyData"
        ],
        "summary": "Score composite temps réel national de la \"propreté\" de l'électricité du réseau français.\nCombine intensité carbone, prix spot, tension réseau et adéquation prévisionnelle.\nUtilisé pour décider en temps réel : faut-il lancer ce process maintenant ou reporter ?",
        "parameters": [
          {
            "name": "profile",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wPrice",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "wCarbon",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "wGrid",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "wAdequacy",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/EnergyScore"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnergyScore"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnergyScore"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable"
          }
        }
      }
    },
    "/v1/score/forecast": {
      "get": {
        "tags": [
          "EnergyData"
        ],
        "summary": "Prévision horaire 1-48h du score composite national.\nIdentifie les créneaux optimaux pour planifier recharge VE, précooling HVAC,\nprocess industriels flexibles, ou pilotage batteries stationnaires.",
        "parameters": [
          {
            "name": "hours",
            "in": "query",
            "description": "Nombre d'heures de prévision (1-48, défaut: 24)",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 24
            }
          },
          {
            "name": "profile",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wPrice",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "wCarbon",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "wGrid",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "wAdequacy",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ScoreForecast"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScoreForecast"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScoreForecast"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/v1/grid/status": {
      "get": {
        "tags": [
          "EnergyData"
        ],
        "summary": "Signal Ecowatt J à J+3 : tension du réseau électrique français.\nUtile pour les opérateurs d'effacement (NEBEF), facility managers et pilotage de délestage.",
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable"
          }
        }
      }
    },
    "/v1/tariff/today": {
      "get": {
        "tags": [
          "EnergyData"
        ],
        "summary": "Couleur Tempo du jour (Bleu/Blanc/Rouge). Concerne uniquement les contrats Tempo EDF\n(~5% du marché). Pour l'intelligence carbone générique, préférez /v1/carbon/intensity.",
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/v1/score/history": {
      "get": {
        "tags": [
          "ScoreHistory"
        ],
        "summary": "Historique des scores calculés sur une plage de dates.\nRetourne les snapshots horaires avec sous-scores et valeurs clés.\nLe score étant national, aucun filtre géographique n'est applicable.",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "description": "Date de début (ISO 8601, ex: 2026-04-01)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "description": "Date de fin (ISO 8601, ex: 2026-04-12)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ScoreHistoryResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScoreHistoryResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScoreHistoryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/v1/score/analytics": {
      "get": {
        "tags": [
          "ScoreHistory"
        ],
        "summary": "Analytics agrégées sur une période : score moyen, meilleures/pires heures.",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "description": "Date de début (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "description": "Date de fin (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ScoreAnalyticsResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScoreAnalyticsResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScoreAnalyticsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CarbonIntensityResponse": {
        "type": "object",
        "properties": {
          "timestamp": {
            "type": "string",
            "description": "Horodatage UTC de la mesure.",
            "format": "date-time"
          },
          "totalGenerationMW": {
            "type": "number",
            "description": "Production totale en MW.",
            "format": "double"
          },
          "lowCarbonPct": {
            "type": "number",
            "description": "Part bas-carbone (nucléaire + ENR) en %.",
            "format": "double"
          },
          "renewablePct": {
            "type": "number",
            "description": "Part renouvelable (ENR uniquement, hors nucléaire) en %.",
            "format": "double"
          },
          "estimatedGCo2PerKwh": {
            "type": "number",
            "description": "Facteur d'émission estimé en gCO2eq/kWh (pondéré par le mix).",
            "format": "double"
          },
          "mix": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MixEntry"
            },
            "description": "Détail du mix de production trié par valeur décroissante.",
            "nullable": true
          },
          "methodology": {
            "type": "string",
            "description": "Méthodologie de calcul.",
            "nullable": true
          },
          "emissionFactorsSource": {
            "$ref": "#/components/schemas/EmissionFactorsMetadata"
          }
        },
        "additionalProperties": false,
        "description": "Intensité carbone du réseau électrique français à un instant T.\nCalculée à partir du mix de production temps réel (RTE ActualGeneration) et des facteurs\nd'émission ADEME Base Carbone® par filière (synchronisés, licence Etalab).\nDonnées nationales — pas de dimension spatiale."
      },
      "EmissionFactorsMetadata": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "description": "Source officielle des facteurs.",
            "nullable": true
          },
          "license": {
            "type": "string",
            "description": "Licence de réutilisation de la donnée.",
            "nullable": true
          },
          "lastSyncedAt": {
            "type": "string",
            "description": "Horodatage de la dernière synchronisation réussie depuis l'ADEME.",
            "format": "date-time"
          },
          "mostRecentAdemeModification": {
            "type": "string",
            "description": "Date de modification ADEME la plus récente parmi les facteurs utilisés.",
            "format": "date"
          },
          "containsExpiredValidity": {
            "type": "boolean",
            "description": "True si au moins un facteur utilisé a une période de validité ADEME échue\n(le facteur reste \"Valide générique\" côté ADEME ; signalé pour transparence d'audit)."
          },
          "containsFallbackValues": {
            "type": "boolean",
            "description": "True si au moins un facteur provient d'une valeur héritée WattMind plutôt que de l'ADEME\n(filières BIOMASS / WASTE absentes de la Base Carbone)."
          }
        },
        "additionalProperties": false,
        "description": "Métadonnées de provenance des facteurs d'émission, exposées dans la réponse API\npour rendre `/v1/carbon/intensity` auditable (CSRD scope 2)."
      },
      "EnergyScore": {
        "required": [
          "recommendation",
          "subScores"
        ],
        "type": "object",
        "properties": {
          "computedAt": {
            "type": "string",
            "description": "Horodatage de calcul du score.",
            "format": "date-time"
          },
          "globalScore": {
            "type": "integer",
            "description": "Score global (0-100). Plus c'est haut, plus c'est favorable.",
            "format": "int32"
          },
          "level": {
            "$ref": "#/components/schemas/ScoreLevel"
          },
          "recommendation": {
            "type": "string",
            "description": "Recommandation actionnable en français.",
            "nullable": true
          },
          "subScores": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SubScore"
            },
            "description": "Décomposition par dimension (price, carbon, grid, adequacy).",
            "nullable": true
          },
          "confidence": {
            "type": "integer",
            "description": "Indicateur de confiance (0-100%) basé sur la disponibilité des sources de données.\nEn-dessous de 60%, le score est considéré comme dégradé.",
            "format": "int32"
          },
          "status": {
            "type": "string",
            "description": "Statut de service du score : \"ok\" (>=70), \"degraded\" (50-69), \"insufficient\" (<50).",
            "nullable": true
          },
          "sourceAvailability": {
            "type": "object",
            "additionalProperties": {
              "type": "boolean"
            },
            "description": "Audit de disponibilité par source de données utilisée dans le calcul.\nPermet à un client B2B de comprendre pourquoi un score est dégradé.",
            "nullable": true
          },
          "weightsApplied": {
            "$ref": "#/components/schemas/ScoreWeights"
          },
          "profileApplied": {
            "type": "string",
            "description": "Nom du profil métier appliqué (ex. \"balanced\", \"green-first\") ou \"custom\" si weights explicites.\nNull si calcul par défaut.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Score composite indiquant si le moment est favorable pour consommer de l'électricité."
      },
      "HourlyScore": {
        "required": [
          "subScores"
        ],
        "type": "object",
        "properties": {
          "time": {
            "type": "string",
            "description": "Début du créneau horaire.",
            "format": "date-time"
          },
          "globalScore": {
            "type": "integer",
            "description": "Score global (0-100).",
            "format": "int32"
          },
          "level": {
            "$ref": "#/components/schemas/ScoreLevel"
          },
          "subScores": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SubScore"
            },
            "description": "Décomposition par dimension.",
            "nullable": true
          },
          "confidence": {
            "type": "integer",
            "description": "Indicateur de confiance (0-100%) basé sur la disponibilité des sources.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Score composite pour une heure donnée."
      },
      "MixEntry": {
        "type": "object",
        "properties": {
          "productionType": {
            "type": "string",
            "nullable": true
          },
          "valueMW": {
            "type": "number",
            "format": "double"
          },
          "sharePct": {
            "type": "number",
            "format": "double"
          },
          "isLowCarbon": {
            "type": "boolean"
          }
        },
        "additionalProperties": false,
        "description": "Entrée du mix de production."
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": { }
      },
      "ScoreAnalyticsResponse": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "sampleCount": {
            "type": "integer",
            "format": "int32"
          },
          "avgGlobalScore": {
            "type": "number",
            "format": "double"
          },
          "avgConfidence": {
            "type": "number",
            "format": "double"
          },
          "avgSpotPriceEurMwh": {
            "type": "number",
            "format": "double"
          },
          "bestHours": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "worstHours": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "optimalPct": {
            "type": "number",
            "format": "double"
          },
          "unfavorablePct": {
            "type": "number",
            "format": "double"
          }
        },
        "additionalProperties": false
      },
      "ScoreForecast": {
        "required": [
          "bestHour",
          "hours",
          "recommendation",
          "worstHour"
        ],
        "type": "object",
        "properties": {
          "computedAt": {
            "type": "string",
            "description": "Horodatage du calcul de la prévision.",
            "format": "date-time"
          },
          "hours": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HourlyScore"
            },
            "description": "Scores horaires pour les prochaines heures.",
            "nullable": true
          },
          "bestHour": {
            "$ref": "#/components/schemas/HourlyScore"
          },
          "worstHour": {
            "$ref": "#/components/schemas/HourlyScore"
          },
          "recommendation": {
            "type": "string",
            "description": "Recommandation de planification basée sur la prévision.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Prévision du score composite sur les prochaines heures."
      },
      "ScoreHistoryEntry": {
        "type": "object",
        "properties": {
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "globalScore": {
            "type": "integer",
            "format": "int32"
          },
          "level": {
            "type": "string",
            "nullable": true
          },
          "confidence": {
            "type": "integer",
            "format": "int32"
          },
          "scorePrice": {
            "type": "integer",
            "format": "int32"
          },
          "scoreCarbon": {
            "type": "integer",
            "format": "int32"
          },
          "scoreGrid": {
            "type": "integer",
            "format": "int32"
          },
          "scoreAdequacy": {
            "type": "integer",
            "format": "int32"
          },
          "spotPriceEurMwh": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "renewableSharePct": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ScoreHistoryResponse": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "count": {
            "type": "integer",
            "format": "int32"
          },
          "snapshots": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScoreHistoryEntry"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ScoreLevel": {
        "enum": [
          "Optimal",
          "Acceptable",
          "Unfavorable"
        ],
        "type": "string",
        "description": "Niveau global du score énergétique."
      },
      "ScoreWeights": {
        "type": "object",
        "properties": {
          "price": {
            "type": "number",
            "format": "double"
          },
          "carbon": {
            "type": "number",
            "format": "double"
          },
          "grid": {
            "type": "number",
            "format": "double"
          },
          "adequacy": {
            "type": "number",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "Pondérations des 4 sous-scores composant le score global WattMind.\nSomme = 1.0 (±0.01). Chaque valeur ∈ [0, 1].\n            \nDeux modes d'utilisation :\n  - Preset métier (M:WattMind.Core.Domain.Score.ScoreWeights.FromProfile(System.String)) : le client choisit un profil nommé\n    (balanced, green-first, data-center, ev-charging, …) qui encapsule un jeu\n    de poids cohérent avec son cas d'usage.\n  - Custom (M:WattMind.Core.Domain.Score.ScoreWeights.Create(System.Double,System.Double,System.Double,System.Double)) : power users — validation stricte."
      },
      "SubScore": {
        "required": [
          "detail",
          "dimension"
        ],
        "type": "object",
        "properties": {
          "dimension": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "integer",
            "format": "int32"
          },
          "detail": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Sous-score individuel sur une dimension du score composite.\nValeur normalisée entre 0 (pire) et 100 (meilleur)."
      }
    },
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "description": "Votre clé API WattMind (format: wm_xxxxxxxx)",
        "name": "X-Api-Key",
        "in": "header"
      }
    }
  },
  "security": [
    { }
  ],
  "tags": [
    {
      "name": "CarbonIntensity"
    },
    {
      "name": "EnergyData"
    },
    {
      "name": "ScoreHistory"
    }
  ]
}