Jesús Erro
Explorar conexiones
Fuentes energéticas convergen en un modelo canónico y se dividen en dashboard humano e interfaz machine-readable.

Energy Market Data: de las fuentes al contrato estable

Este artículo es la narrativa pública del documento de trabajo interno correspondiente. Conserva hallazgos, semántica, fallos reales y límites; omite o generaliza únicamente identificadores operativos privados que no aportan valor editorial.

Energy Market Data es el servicio de IXATU para recolectar, normalizar, conservar y publicar datos relevantes del mercado energético desde múltiples fuentes oficiales y de mercado.

Su salida tiene dos caras construidas desde el mismo modelo canónico:

  1. un dashboard humano para consulta visual;
  2. una Machine Interface estable en /api/resumen.json para aplicaciones, agentes IA, automatizaciones y scripts.

El proyecto evita depender de consultas manuales, hojas dispersas, scraping de pantallas o interpretaciones inconsistentes entre fuentes.

1. Para qué sirve

El proyecto centraliza indicadores de mercado que IXATU necesita para análisis, seguimiento y futura integración con sus aplicaciones internas.

Sus objetivos principales son:

  • disponer de una fuente interna de datos energéticos normalizados;
  • automatizar la consulta periódica de fuentes externas;
  • conservar histórico en una base persistente;
  • distinguir correctamente datos confirmados, estimados y no utilizables;
  • unificar unidades, fechas, procedencia y semántica;
  • proporcionar indicadores utilizables por personas y por software;
  • permitir backfills históricos reproducibles;
  • separar la fuente canónica moderna de cálculos o convenciones legacy;
  • reducir riesgo operativo mediante procesos idempotentes, tests y validaciones contra las fuentes oficiales.

2. Problemas que soluciona

2.1 Fuentes fragmentadas

Los datos necesarios para seguir electricidad, gas, almacenamientos, GNL, materias primas y liquidaciones no proceden de una única plataforma.

El proyecto abstrae esa heterogeneidad y la transforma en un modelo común.

2.2 Consulta manual y repetitiva

Sin automatización habría que visitar periódicamente OMIE, REE/ESIOS, GIE, MIBGAS u otras fuentes, interpretar cada formato y trasladar los valores a sistemas internos.

Los workflows programados realizan esa labor de forma recurrente.

2.3 Diferencias semánticas entre proveedores

Un valor no basta por sí solo. Es necesario saber:

  • qué fecha representa;
  • qué mercado o producto representa;
  • si es confirmado o estimado;
  • qué unidad utiliza;
  • de qué fuente procede;
  • si corresponde a cierre provisional o definitivo;
  • si puede compararse realmente con un cálculo histórico de IXATU.

El modelo canónico conserva estos significados.

2.4 Riesgo de mezclar datos provisionales y definitivos

Especialmente en GIE y Liquicomun, el proyecto incorpora reglas explícitas para impedir que una observación menos fiable sustituya silenciosamente a otra de mayor calidad.

2.5 Integraciones frágiles por scraping

Las aplicaciones internas no deberían extraer información del HTML del dashboard.

Para ello existe:

/api/resumen.json

Esta salida machine-readable es un contrato explícito y versionado.

2.6 Exposición innecesaria de infraestructura

Los consumidores no necesitan acceso directo a Supabase ni a las credenciales de las fuentes.

El JSON público es un snapshot estático generado server-side, sin secretos ni consultas a base de datos en runtime.


3. Arquitectura

flowchart LR
    subgraph FUENTES["Fuentes externas"]
        OMIE["OMIE"]
        ESIOS["ESIOS / REE"]
        REDATA["REData"]
        GIE["GIE · AGSI / ALSI"]
        YF["Yahoo Finance"]
        MIBGAS["MIBGAS"]
        LIQ["REE Liquicomun / compodem"]
    end

    subgraph INGESTA["Ingesta Python"]
        ADAPT["Adapters por fuente"]
        VALID["Validación + semántica"]
        CANON["Modelo canónico"]
    end

    subgraph DATA["Persistencia"]
        SUPA["Supabase / PostgreSQL\npublic.medidas"]
        CSV["CSV local\nsolo fallback DEV"]
    end

    subgraph BUILD["Publicación"]
        GEN["dashboard.generar"]
        HTML["dist/index.html"]
        JSON["dist/api/resumen.json"]
    end

    subgraph CLOUD["Entrega"]
        GHA["GitHub Actions"]
        ACR["Azure Container Registry"]
        ACA["Azure Container Apps\nnginx estático"]
        ENTRA["Microsoft Entra ID"]
    end

    OMIE --> ADAPT
    ESIOS --> ADAPT
    REDATA --> ADAPT
    GIE --> ADAPT
    YF --> ADAPT
    MIBGAS --> ADAPT
    LIQ --> ADAPT

    ADAPT --> VALID --> CANON
    CANON --> SUPA
    CANON -. desarrollo .-> CSV

    SUPA --> GEN
    GEN --> HTML
    GEN --> JSON

    GHA --> GEN
    HTML --> ACR
    JSON --> ACR
    ACR --> ACA
    ENTRA --> HTML
    ACA --> JSON

Idea arquitectónica clave

El runtime público no es una API Python.

El dashboard y la Machine Interface se generan previamente y se sirven como ficheros estáticos mediante nginx. No hay Python ni consultas a Supabase en cada petición del usuario.

Esta decisión reduce:

  • superficie de ataque;
  • complejidad operativa;
  • dependencia de disponibilidad de Supabase en tiempo de lectura;
  • latencia;
  • coste de ejecución;
  • riesgo de filtrar secretos.

4. Componentes del repositorio

Componente Responsabilidad
fuentes/ Adaptadores y recolectores de cada fuente externa.
comun/db.py Persistencia y acceso común a datos.
dashboard/ Modelo de presentación, semántica, freshness, HTML y Machine Interface.
herramientas/ Utilidades operativas, incluido backfill histórico.
db/migrations/ Evoluciones puntuales del esquema persistente.
.github/workflows/ CI, recolección diaria, liquidaciones mensuales y publicación.
docker/ + docker-bake.hcl Imagen estática del dashboard.
tests/ Contratos, parsers, semántica, persistencia y generación.
pyproject.toml / uv.lock Toolchain Python reproducible.

5. Modelo de datos canónico

La persistencia principal se encuentra en Supabase:

public.medidas

Campos base

Cada medida utiliza como mínimo:

  • fecha
  • variable
  • valor
  • unidad
  • fuente
  • calidad cuando aplica

Clave primaria:

(fecha, variable)

Esto permite realizar upsert idempotente: repetir una descarga actualiza la misma observación y no crea duplicados.

Calidad

La calidad se utiliza especialmente con GIE:

  • C → confirmado;
  • E → estimado;
  • N → no aceptado para las series que requieren dato utilizable.

No todas las fuentes necesitan calidad; en esos casos puede almacenarse NULL.

Provenance

La procedencia se conserva de forma explícita.

Ejemplos:

  • OMIE
  • ESIOS
  • REData
  • GIE
  • MIBGAS
  • liquicomun_A2
  • liquicomun_C2

La combinación variable + fecha + fuente + calidad permite interpretar un dato, no solo mostrar un número.


6. Fuentes de datos

6.1 OMIE

Uso: mercado eléctrico spot español.

Obtiene:

  • precio spot day-ahead España;
  • media diaria;
  • periodos reales intradiarios/cuarto-horarios cuando corresponden.

Características:

  • fuente pública;
  • no requiere credenciales;
  • utilizada como referencia canónica para spot_es;
  • el histórico conserva los periodos reales, incluidos días con cambio horario.

6.2 ESIOS / Red Eléctrica

Uso diario:

  • PVPC;
  • spot como contraste.

Requiere:

ESIOS_TOKEN

Comportamiento relevante:

  • la consulta diaria no confía ciegamente en filtros server-side;
  • el adapter valida la fecha local del dato recibido;
  • una respuesta vacía se considera error visible, no ejecución correcta.

6.3 REData

Uso principal: backfill histórico.

Series utilizadas:

  • PVPC — ID 1001;
  • spot — ID 600.

El backfill consulta el widget:

mercados/precios-mercados-tiempo-real

Características:

  • procesa rangos explícitos de fechas;
  • calcula media diaria a partir de las observaciones recibidas;
  • no fuerza artificialmente 24 o 96 registros;
  • conserva correctamente los días de cambio horario;
  • falla antes de escribir si faltan series, días o valores válidos.

La ingesta histórica mediante REData está deliberadamente separada de la ingesta diaria ESIOS. Las filas históricas conservan fuente = REData.


6.4 GIE — AGSI / ALSI

GIE proporciona información sobre almacenamiento de gas y terminales LNG.

Requiere:

GIE_KEY

AGSI

Se utilizan al menos:

  • almacenamiento España;
  • almacenamiento agregado UE.

Regla:

  • AGSI acepta únicamente datos C confirmados.

Hallazgo operativo importante:

En producción se comprobó que el último dato C confirmado de AGSI UE podía estar fuera de una ventana de búsqueda de 7 días.

Se amplió solo AGSI UE a 14 días, manteniendo la exigencia status=C. No se promocionan datos E o N a confirmados.

ALSI

Para llenado de terminales LNG de España:

  • el valor principal sigue siendo el último C confirmado;
  • si aparece posteriormente un E, se conserva como avance estimado;
  • el estimado nunca reemplaza silenciosamente al confirmado;
  • los estados N se rechazan.

Los porcentajes se validan en:

0 <= valor <= 100


6.5 Yahoo Finance / yfinance

Indicadores de mercado adicionales:

  • TTF;
  • Brent;
  • Henry Hub.

No constituyen una sustitución de las referencias oficiales españolas cuando existe una serie más adecuada para la operativa.

En especial:

Tras la integración de MIBGAS, TTF queda como referencia complementaria, no como referencia principal del precio diario de gas PVB para IXATU.


6.6 MIBGAS

Fuente oficial pública.

Producto canónico integrado:

GDAES D+1 — PVB España

Variable:

mibgas_gdaes_d1

Unidad:

EUR/MWh

Razón de negocio

Es la referencia prioritaria de gas para la operativa de IXATU, especialmente para fórmulas indexadas españolas.

Semántica de fecha

fecha_dato corresponde al Trading day, es decir, el día en el que MIBGAS fija el precio.

La fecha de entrega es conceptualmente:

fecha_dato + 1 día

pero no se persiste como un campo independiente.

Media mensual

La Machine Interface añade una media mensual basada únicamente en las sesiones GDAES D+1 realmente publicadas:

  • no interpola huecos;
  • no inventa fines de semana;
  • no rellena festivos;
  • informa de n_observaciones.

Publicación

La fuente oficial publica aproximadamente a las 18:00 Europe/Madrid.

El recolector se ejecuta a las 18:30.


6.7 Liquicomun — REE

Se ingieren liquidaciones mensuales desde los ZIP oficiales:

compodem_*

No requieren ESIOS_TOKEN.

Cierres

  • A2 → provisional;
  • C2 → final.

Archivos utilizados por la lógica actual:

  • A2 → archive fijo 3;
  • C2 → archive fijo 8.

Reglas de precedencia

C2 gana siempre sobre A2.

Cuando llega C2:

  • se escriben las claves finales;
  • se retiran residuos A2;
  • no se permite degradar posteriormente el mes escribiendo A2 encima de C2.

Variables

Se generan variables dinámicas:

compodem_<componente>

Unidad:

EUR/MWh

Provenance:

  • liquicomun_A2
  • liquicomun_C2

NOCUR

Uno de los hallazgos funcionales más importantes fue separar correctamente el universo NOCUR / mercado libre del TOTAL técnico.

Indicadores destacados:

  • RAD3 NOCUR;
  • CT3 NOCUR;
  • SECX NOCUR;
  • Total Compodem NOCUR;
  • TOTAL técnico.

Existe un migration guard para evitar presentar datos históricos calculados bajo semántica TOTAL como si fueran NOCUR.


7. Machine Interface — /api/resumen.json

Finalidad

Es el contrato público para:

  • IXATU Operations;
  • agentes IA;
  • automatizaciones;
  • scripts;
  • dashboards secundarios;
  • integraciones futuras.

No debe consumirse el HTML mediante scraping.

Contrato actual

schema_version: "1.0"

Principio de compatibilidad:

Los consumidores deben localizar indicadores por id, nunca por posición dentro del array.

Así pueden añadirse indicadores nuevos sin romper integraciones existentes.

Campos superiores

  • schema_version
  • generated_at
  • proxima_regeneracion
  • electricidad
  • mercados
  • almacenamientos_gnl
  • liquicomun

Campos comunes de indicador

  • id
  • variable_origen
  • valor
  • unidad
  • fecha_dato
  • fuente
  • calidad
  • disponibilidad

Valores de disponibilidad:

  • disponible
  • ausente

Si no existe dato canónico utilizable:

  • valor = null
  • fecha_dato = null

Distinción crítica de fechas

generated_at significa:

momento de generación del artefacto

fecha_dato significa:

fecha real del dato de mercado

No son equivalentes.

El sistema conserva el último éxito. Que el JSON se haya generado hoy no implica que cada indicador corresponda a hoy.

Cualquier consumidor que necesite controlar freshness debe evaluar fecha_dato, la naturaleza de la fuente y su calendario de publicación.


8. Indicadores expuestos en Machine Interface v1

Electricidad

ID Variable origen Uso
spot_omie spot_es Media canónica OMIE.

Mercados

ID Variable origen Uso
mibgas_gdaes_d1 mibgas_gdaes_d1 Referencia prioritaria gas PVB España D+1.
ttf ttf Referencia europea complementaria.
brent brent Petróleo Brent.
henry_hub henry_hub Gas Henry Hub.

Almacenamientos / GNL

ID Variable origen Uso
agsi_full_es agsi_full_es Almacenamiento España.
agsi_full_eu agsi_full_eu Almacenamiento agregado UE.
alsi_full_es alsi_full_es LNG España; confirmado + avance estimado cuando existe.

Liquicomun

ID Variable origen Semántica
rad3_nocur compodem_rad3 RAD3 NOCUR.
ct3_nocur compodem_ct3 CT3 NOCUR.
secx_nocur compodem_secx SECX NOCUR.
compodem_nocur_total compodem_nocur_total Total NOCUR.
compodem_total compodem_total TOTAL técnico.

Liquicomun añade además:

  • semantica
  • cierre
  • estado_cierre
  • estado_migracion

9. Dashboard humano

El dashboard visual se genera desde el mismo modelo que la Machine Interface.

Esto es importante porque evita mantener dos lógicas paralelas:

Supabase
   │
   ▼
modelo canónico
   ├──► dashboard humano
   └──► /api/resumen.json

La interpretación funcional debe ser la misma en ambas salidas.

Seguridad

El diseño vigente separa:

  • / → dashboard humano protegido mediante Microsoft Entra ID;
  • /api/resumen.json → endpoint público machine-readable.

La excepción pública está limitada al recurso necesario; no implica exponer la base de datos ni las credenciales.


10. Flujo diario

sequenceDiagram
    participant GH as GitHub Actions
    participant F as Fuentes externas
    participant S as Supabase
    participant G as Generador
    participant A as Azure Container Apps

    GH->>F: 17:30 OMIE + ESIOS + mercados
    F-->>GH: datos validados
    GH->>S: upsert medidas

    GH->>F: 18:30 MIBGAS
    F-->>GH: GDAES D+1
    GH->>S: upsert

    GH->>F: 20:30 GIE
    F-->>GH: AGSI / ALSI
    GH->>S: upsert

    GH->>G: generar artefactos
    G->>S: leer public.medidas
    G-->>GH: index.html + resumen.json
    GH->>A: desplegar imagen nginx

Horarios en:

Europe/Madrid

Descargas diarias

  • 17:30 → OMIE, ESIOS y mercados.
  • 18:30 → MIBGAS.
  • 20:30 → AGSI/ALSI.

La ejecución manual mediante workflow_dispatch puede lanzar las fuentes bajo control del operador.


11. Flujo Liquicomun mensual

Se procesa siempre el mes anterior.

A2 provisional

Intentos:

  • día 6 → 09:17
  • día 9 → 09:17
  • día 12 → 09:17

C2 final

Intentos:

  • día 16 → 09:23
  • día 20 → 09:23

Los primeros intentos pueden tolerar únicamente el estado explícito:

archive todavía no publicado

El último intento y las ejecuciones manuales deben fallar si el fichero esperado sigue sin existir.


12. Backfill histórico

Herramienta:

herramientas/backfill.py

Uso conceptual:

uv run --frozen python herramientas/backfill.py \
  --desde YYYY-MM-DD \
  --hasta YYYY-MM-DD

Propiedades

  • requiere Supabase;
  • no usa fallback CSV;
  • no necesita ESIOS_TOKEN;
  • valida configuración antes de descargar;
  • descarga REData para el rango;
  • obtiene OMIE histórico;
  • utiliza upsert sobre (fecha, variable);
  • repetir el mismo rango es idempotente;
  • no existe una transacción global para todo el rango;
  • si falla en mitad del proceso, los días ya persistidos permanecen;
  • puede repetirse el rango completo de forma segura.

13. Persistencia y fallback local

Producción

Variables obligatorias:

  • SUPABASE_URL
  • SUPABASE_SECRET_KEY

El proyecto Supabase actual persiste en:

public.medidas

Desarrollo

Si ninguna variable Supabase está presente, algunos recolectores pueden utilizar:

data/medidas.csv

como fallback local.

Configuración parcial

Si solo se configura una parte de las credenciales Supabase, el proceso falla deliberadamente.

No se permite caer silenciosamente a CSV porque podría producir una ejecución aparentemente correcta que en realidad no actualizase producción.

Liquicomun y el backfill histórico exigen persistencia real en Supabase.


14. Automatización y CI/CD

Workflows

ci.yml

Valida el código en pull requests.

Los tests están diseñados para ejecutarse:

  • sin Internet;
  • sin secretos;
  • con HTTP simulado.

descarga-diaria.yml

Ejecuta la recolección diaria según ventanas de publicación.

liquidaciones-mensuales.yml

Gestiona los intentos A2/C2.

publicar-dashboard.yml

Se dispara:

  • manualmente;
  • después de completar descarga diaria;
  • después de completar liquidaciones mensuales.

Proceso:

  1. checkout;
  2. Python 3.12 + uv;
  3. uv sync --frozen;
  4. tests;
  5. generación desde Supabase;
  6. verificación de dist/index.html;
  7. verificación JSON de dist/api/resumen.json;
  8. controles para evitar información no publicable;
  9. creación de artefacto;
  10. login Azure mediante OIDC;
  11. build/push a ACR;
  12. actualización de Azure Container App.

15. Seguridad

Secretos

Variables sensibles:

  • GIE_KEY
  • ESIOS_TOKEN
  • SUPABASE_SECRET_KEY

Principios:

  • nunca versionarlas;
  • nunca exponerlas en cliente;
  • nunca registrarlas en logs;
  • usar GitHub Secrets para los workflows;
  • utilizar .env únicamente de forma local e ignorada por Git.

SUPABASE_SECRET_KEY posee acceso privilegiado y debe considerarse especialmente sensible.

Azure

El despliegue utiliza:

GitHub Actions → OIDC → Azure

Esto evita guardar credenciales Azure de larga duración para el pipeline.

Artefacto público

El workflow comprueba que /api/resumen.json no contenga referencias a:

  • credenciales Supabase;
  • benchmark Power BI legacy;
  • clientes;
  • información interna no publicable.

16. Hallazgos y decisiones importantes

H1 — MIBGAS debe ser la referencia operativa española de gas

Para fórmulas indexadas y seguimiento PVB España:

MIBGAS GDAES D+1 > TTF

TTF sigue siendo útil como referencia complementaria de mercado europeo.


H2 — La calidad de GIE es parte del dato

No debe interpretarse igual:

  • confirmado;
  • estimado;
  • no aceptable.

El estado de calidad forma parte de la semántica canónica.


H3 — ALSI no debe ocultar el último confirmado

El último C confirmado es el valor principal.

Un E posterior es información adicional y debe presentarse como avance, no como sustitución.


H4 — La ventana temporal puede ser parte de la lógica de calidad

AGSI UE demostró que un dato confirmado válido puede quedar fuera de una ventana demasiado corta.

Solución aplicada:

  • ampliar búsqueda UE de 7 a 14 días;
  • conservar estrictamente status=C.

H5 — generated_at no representa freshness del mercado

El artefacto puede regenerarse correctamente utilizando el último dato válido disponible.

Por ello los consumidores deben mirar:

  • fecha_dato;
  • fuente;
  • calidad;
  • calendario esperado de publicación.

H6 — Liquicomun NOCUR y TOTAL técnico no son intercambiables

RAD3, CT3 y SECX se interpretan dentro del universo NOCUR / mercado libre.

El proyecto mantiene además TOTAL técnico, pero no mezcla ambas semánticas.


H7 — C2 no puede degradarse a A2

Una vez disponible cierre final C2, no debe reaparecer A2 como estado vigente del mes.

La persistencia incorpora esta invariancia.


H8 — Los cambios horarios no justifican inventar observaciones

En series horarias o cuarto-horarias:

  • no se exige artificialmente 24/96 periodos;
  • se utilizan las observaciones reales;
  • se conserva la fecha derivada del timestamp suministrado.

Esto evita errores en transiciones DST.


H9 — Una respuesta vacía es fallo

Las fuentes externas pueden devolver HTTP correcto pero sin datos útiles.

El proyecto considera eso un error explícito, evitando almacenar una falsa sensación de éxito.


H10 — El JSON machine-readable es preferible a exponer Supabase

Las aplicaciones consumidoras no necesitan conocer:

  • tablas;
  • credenciales;
  • esquemas internos;
  • lógica de selección.

/api/resumen.json actúa como contrato de integración.


17. Evidencias de validación

La release v0.5.0 consolidó:

  • MIBGAS GDAES D+1;
  • Machine Interface pública;
  • hardening AGSI UE;
  • validación end-to-end de AGSI/ALSI;
  • dashboard PROD;
  • CI verde;
  • 311 tests tras el hardening.

Golden sample Liquicomun validado

Para C2 julio de 2026 se contrastaron, entre otros:

Indicador Valor
RAD3 NOCUR 1,9259 EUR/MWh
CT3 NOCUR 0,0467 EUR/MWh
SECX NOCUR -0,2824 EUR/MWh
Total NOCUR 16,2639 EUR/MWh
TOTAL técnico 16,3279 EUR/MWh

Estos valores son evidencia histórica de validación, no constantes del sistema.


18. Integración con IXATU Operations

La Machine Interface permite que IXATU Operations consuma los datos sin conocer la arquitectura interna del recolector.

Caso de uso previsto:

Home de Operations

Puede mostrar una barra horizontal compacta con indicadores de mercado, por ejemplo:

  • OMIE;
  • MIBGAS;
  • TTF;
  • Brent;
  • almacenamientos ES/UE;
  • Liquicomun.
flowchart LR
    EMD["Energy Market Data"] --> API["/api/resumen.json"]
    API --> OPS["IXATU Operations"]
    OPS --> HOME["Home / Market Bar"]

Regla de integración

Operations debería depender del contrato público id + schema version, no de:

  • nombres internos de tablas;
  • estructura de Supabase;
  • posición de los indicadores;
  • HTML del dashboard.

19. Qué no es este proyecto

No es:

  • un sistema de facturación;
  • un CRM;
  • el core transaccional de clientes;
  • un reemplazo de IXATU Operations;
  • una API REST dinámica tradicional;
  • un proxy de las APIs externas;
  • un motor de trading;
  • una copia completa de todos los mercados energéticos.

Es una capa especializada de adquisición, normalización y publicación de inteligencia de mercado energético.


20. Límites y pendientes conocidos

OMIP

OMIP no está integrado actualmente.

No debe:

  • inventarse un indicador;
  • presentarse como fallo del sistema;
  • confundirse con OMIE.

Puede incorporarse en el futuro mediante un nuevo indicador aditivo.

Freshness de Yahoo Finance

Existe margen para seguir afinando la semántica de calidad/frescura de las series obtenidas mediante Yahoo Finance.

Ejecuciones manuales fuera de ventana

Las ejecuciones workflow_dispatch pueden requerir reglas más explícitas cuando se lanzan antes de que una fuente haya publicado el dato esperado.

Último dato válido frente a fallo operativo

Supabase conserva observaciones exitosas, no un estado de error por indicador.

Por tanto, un consumidor que necesite alertas operativas debería complementar el JSON con lógica de freshness o telemetría de workflows.


21. Principios del proyecto

No inventar datos para rellenar huecos.

La procedencia y la calidad forman parte del dato.

Un cierre definitivo nunca debe degradarse a uno provisional.

Un estimado puede complementar a un confirmado, pero no sustituirlo silenciosamente.

Los consumidores dependen del contrato público, no de la persistencia interna.

generated_at no es fecha_dato.

La automatización debe fallar visiblemente antes que producir un éxito falso.


22. Operación local

Preparación

uv sync --frozen

Ejecución de fuentes

uv run --frozen python fuentes/omie.py
uv run --frozen python fuentes/mercados.py
uv run --frozen python fuentes/mibgas.py
GIE_KEY=<valor-local> uv run --frozen python fuentes/agsi.py
ESIOS_TOKEN=<valor-local> uv run --frozen python fuentes/esios.py

Tests

uv run --frozen python -m pytest
uv run --frozen python -m compileall fuentes comun herramientas dashboard
uv build

23. Superficies públicas del servicio

El servicio publica un dashboard humano y una Machine Interface machine-readable. Los consumidores deben preferir /api/resumen.json frente a cualquier acceso directo a Supabase o a particularidades de cada proveedor externo.

Las URLs concretas de despliegue viven en la operativa interna del proyecto y no aportan valor editorial más allá de esa distinción de superficies.


24. Mapa mental del proyecto

mindmap
  root((Energy Market Data))
    Ingesta
      OMIE
      ESIOS
      REData
      GIE
        AGSI
        ALSI
      Yahoo Finance
      MIBGAS
      Liquicomun
    Modelo canónico
      fecha
      variable
      valor
      unidad
      fuente
      calidad
    Persistencia
      Supabase
      public.medidas
      upsert
      idempotencia
    Publicación
      Dashboard
      Machine Interface
      schema 1.0
    Automatización
      descarga diaria
      liquidaciones mensuales
      backfill manual
      GitHub Actions
    Delivery
      Docker
      ACR
      Azure Container Apps
      nginx
      Entra ID
    Reglas
      confirmed over estimated
      C2 over A2
      NOCUR != TOTAL
      fecha dato != generación
      no silent fallback

25. Resumen ejecutivo

Energy Market Data convierte fuentes externas heterogéneas en un pequeño dominio de datos de mercado controlado por IXATU.

Su valor no reside solo en descargar precios, sino en:

  1. seleccionar la serie correcta;
  2. conservar su significado;
  3. validar calidad y fechas;
  4. persistir de forma idempotente;
  5. automatizar la actualización;
  6. exponer un contrato estable;
  7. separar infraestructura interna de consumidores;
  8. ofrecer la misma verdad tanto al dashboard humano como a las aplicaciones.

La dirección arquitectónica correcta es mantenerlo como un servicio especializado de market data, consumido por proyectos como IXATU Operations mediante la Machine Interface, evitando acoplar otros sistemas directamente a Supabase o a las peculiaridades de cada proveedor externo.


Referencias internas del repositorio

  • README.md
  • docs/api/resumen-v1.md
  • fuentes/
  • comun/db.py
  • dashboard/
  • .github/workflows/descarga-diaria.yml
  • .github/workflows/liquidaciones-mensuales.yml
  • .github/workflows/publicar-dashboard.yml
  • db/migrations/
  • herramientas/backfill.py
  • pyproject.toml

Historial clave

  • v0.4.1 — hardening funcional y contraste legacy.
  • v0.4.2 — Liquicomun NOCUR y freshness explicativo.
  • v0.4.3 — Machine Interface v1 y modernización de toolchain.
  • v0.5.0 — MIBGAS GDAES D+1 y hardening AGSI UE.