Omnigraph
그래프 엔진으로 컨텍스트를 조립하고, 객체 저장소 기반에서 에이전트가 코드처럼 그래프 데이터를 분기·타입·검토·병합·감사·거버넌스합니다
저장소 정보는 아직 수집하지 않았습니다.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Primera práctica de Big Data. Es una aplicación web para ejecutar y observar un pipeline ETL completo: extraer datos horarios de la API histórica de Open-Meteo, transformarlos, limpiarlos, filtrarlos y seleccionarlos, y cargarlos en Supabase. Cada fase muestra su estado, los registros de entrada y salida y su duración real.
Stack: Next.js 16 (App Router), TypeScript, Tailwind CSS 4, shadcn/ui (Base UI) y @supabase/supabase-js.
npm install
cp .env.example .env.local # y rellena los valores
| Variable | Dónde se usa | Descripción |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | servidor | URL del proyecto (Project Settings → API) |
SUPABASE_SECRET_KEY | solo servidor | Clave secreta sb_secret_… (o la antigua service_role). Nunca con el prefijo NEXT_PUBLIC_ |
ETL_PERMITIR_ESCRITURA | servidor | En producción la escritura está desactivada salvo que valga true (ver Seguridad) |
NEXT_PUBLIC_MAPTILER_KEY | navegador | Clave de MapTiler para el mapa. Es pública por diseño: restríngela por origen HTTP en cloud.maptiler.com |
El mapa usa MapLibre GL con los estilos dataviz / dataviz-dark de MapTiler. MapLibre 6 carga su
worker desde un archivo aparte: npm install lo copia a public/ (script postinstall).
Aplica la migración supabase/migrations/20261026120000_crear_mediciones_meteorologicas.sql:
npx supabase link --project-ref <ref> y después npx supabase db push.La tabla mediciones_meteorologicas tiene la restricción única (ciudad, fecha_hora) y comprueba
que la humedad está en [0, 100], que la precipitación es ≥ 0 y que ningún valor es NaN ni infinito.
Tiene RLS activado y no tiene políticas.
npm run dev # http://localhost:3000
npm test # pruebas unitarias con fixtures controlados
npm run test:integracion # API real de Open-Meteo y endpoints (requiere npm run dev)
npm run typecheck && npm run lint && npm run build
https://archive-api.open-meteo.com/v1/archive con timezone=GMT, °C y mm. Cada extracción
cubre como máximo 365 días. El JSON original se guarda durante la sesión y se puede descargar.
Si una ciudad falla, se puede reintentar solo esa ciudad; su respuesta sustituye a la anterior,
así que no se acumulan duplicados.lib/etl/transformacion.ts): convierte los
arrays paralelos de hourly en un registro por ciudad y hora. Las horas llegan sin zona
(2026-09-01T00:00) y se interpretan explícitamente como UTC. Si los arrays tienen
longitudes distintas, se avisa y se recorre la longitud máxima, de modo que ningún valor se
pierde sin que se note. Esta fase no corrige ningún valor.lib/etl/limpieza.ts): una fila se rechaza si le falta la
ciudad, si la fecha no es válida o si alguna medición es null, está vacía, es texto o no es
finita. Nunca se convierte nada en 0. También se rechaza la humedad fuera de [0, 100] y la
precipitación negativa. No hay umbrales para temperaturas extremas. Ante un duplicado
(ciudad, fecha_hora) se conserva la primera aparición en el orden de extracción. Cada
rechazo indica su motivo y su tipo (calidad o duplicado).lib/etl/filtros.ts): el orden es
válidos → filtros → ordenación → selección → carga. La paginación solo afecta a la vista. Solo
se suben las filas seleccionadas que siguen cumpliendo los filtros actuales. Las que no los
cumplen se cuentan aparte y no se seleccionan automáticamente filas nuevas.lib/etl/carga.ts, app/api/carga):
al pulsar el botón se congela una copia del conjunto y de su orden. Se envía en lotes de hasta
500 registros, siempre en serie y sin envíos simultáneos. Cada lote hace un por
. El servidor vuelve a validar los datos y el tamaño de la petición, y
devuelve una huella de lo que recibió, que se compara con la de la vista previa. Si un lote
falla, los anteriores conservan su estado y se pueden reintentar solo los fallidos. Después, la
aplicación consulta el destino para comprobar que todas las claves enviadas existen.
Supabase no indica en un upsert qué filas se insertaron y cuáles se actualizaron, así que solo
se informa de las filas «procesadas».El paso 6 · Destino lee la tabla real a través de /api/mediciones, con paginación,
filtros y ORDER BY explícito. Una base de datos no garantiza el orden de inserción: el orden de
lectura hay que pedirlo siempre.
pd.read_csv("validos-filtrados.csv", parse_dates=["fecha_hora"]).df.describe() (n, media,
desviación típica muestral, mínimo, percentiles 25/50/75 y máximo) sobre los registros filtrados.supabase-js, y cómo abrir en pandas el CSV exportado, con botón de copiar.text, timestamptz, float8).localStorage).SUPABASE_SECRET_KEY como Secret; NEXT_PUBLIC_MAPTILER_KEY como Config (va al
navegador por diseño, Vercel avisa si se marca como Secret).localhost y el dominio de producción). Desde las URLs de despliegue o de rama de Vercel el
mapa da 403 salvo que se añada un patrón como <proyecto>-*-<usuario>.vercel.app.lib/supabase/servidor.ts importa server-only). La clave secreta
no llega al navegador; se ha comprobado que no aparece en .next/static.anon y authenticated./api/carga está abierta. En producción
(Vercel) devuelve 403 salvo que ETL_PERMITIR_ESCRITURA=true. Antes de activarla, protege la ruta,
por ejemplo con Supabase Auth, Vercel Deployment Protection o un middleware.tests/fixtures/barcelona-2026-09-01.json: respuesta real guardada (1 ciudad, 1 día).tests/fixtures/respuesta-con-problemas.json: fixture controlado con nulls, cadena vacía,
texto, humedad 104, precipitación negativa, fecha imposible, hora duplicada y un array más corto.
Solo se usa en los tests; nunca se mezcla con las extracciones reales.supabase-js y pandas.| Comando | Qué cubre | Resultado |
|---|---|---|
npm test | 38 pruebas unitarias en 6 archivos: transformación de arrays paralelos, interpretación UTC, limpieza (null, vacíos, textos, rangos, fechas, duplicados, balance válidos + rechazados), filtros y orden antes de paginar, selección entre páginas, lotes y reintentos, validación del servidor, exportación CSV, resúmenes, perfil estadístico y consulta equivalente | 38 superadas |
npm run test:integracion | API real de Open-Meteo, validación del servidor (422 y 413) y, con Supabase configurado, carga, verificación, idempotencia y fallo parcial | 3 superadas; las 3 de Supabase se omiten si no hay credenciales |
npm run typecheck, npm run lint, npm run build | Tipos, estilo y compilación de producción | Sin errores |
| Prueba manual en Vercel | Flujo completo en el despliegue: extracción, limpieza, selección, carga en Supabase y lectura en Destino | Correcta |
| Revisión manual en móvil | Lectura y uso de la interfaz en pantalla pequeña | Correcta |
ETL_PERMITIR_ESCRITURA=true; antes de activarla hay que
proteger /api/carga (ver Seguridad)..env.local y sin ellas se omiten indicando el motivo. La carga real se ha comprobado a mano
en el despliegue de Vercel.(ciudad, fecha_hora)