尚未收集儲存庫資訊。
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Práctica de Big Data. Una aplicación Next.js para ejecutar y ver un primer pipeline ETL: extraer mediciones horarias históricas de Open-Meteo, transformarlas, limpiarlas, filtrar y seleccionar qué registros subir, y cargarlos en Supabase.
Extracción → Transformación → Limpieza → Filtrado y selección → Carga
Stack: Next.js 16 (App Router), TypeScript, Tailwind CSS 4, shadcn/ui (Base UI), supabase-js, Vitest.
npm install
cp .env.example .env.local # y rellena los valores
| Variable | Dónde se usa | Secreta |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL (o SUPABASE_URL) | Servidor | No |
SUPABASE_SECRET_KEY (sb_secret_…; también vale SUPABASE_SERVICE_ROLE_KEY) | Solo servidor | Sí |
ETL_PERMITIR_ESCRITURA_SIN_AUTH | Permite cargar con next start | — |
La clave secreta salta RLS: nunca le pongas el prefijo NEXT_PUBLIC_ ni la uses en el navegador.
Ejecuta la migración supabase/migrations/20261026000000_crear_mediciones_meteorologicas.sql
en el SQL Editor de Supabase (o con supabase db push si usas la CLI). Crea la tabla
mediciones_meteorologicas con:
id identidad como clave primaria, importado_en con now() por defecto.(ciudad, fecha_hora): permite el upsert sin duplicados.humedad_pct entre 0 y 100, precipitacion_mm ≥ 0.npm run dev # http://localhost:3000
npm test # pruebas unitarias (fixtures controlados)
npm run test:integracion # Open-Meteo y Supabase reales (requiere .env.local y la migración)
npm run typecheck && npm run build
https://archive-api.open-meteo.com/v1/archive con
hourly=temperature_2m,relative_humidity_2m,precipitation, timezone=UTC, °C y mm. Máximo
31 días por extracción. Las ciudades se piden una a una y se muestra cuáles faltan. El JSON se
guarda tal cual durante la sesión y se puede descargar. Si una ciudad falla se puede reintentar
solo esa: su respuesta sustituye a la anterior, así que no se duplican datos.time[i], temperature_2m[i]…). Cada
posición i pasa a ser un registro {ciudad, fecha_hora, temperatura_c, humedad_pct, precipitacion_mm}. Las horas llegan sin zona (2026-09-01T00:00), así que se interpretan
explícitamente como UTC. Si las longitudes de los arrays no coinciden se avisa y las posiciones
que faltan se marcan como ausentes. Aquí no se corrige ningún valor.POST /api/carga, que vuelve a validar cada registro y el tamaño de
la petición y hace upsert con onConflict: ciudad,fecha_hora. Cada lote tiene su estado. Si
uno falla, los demás se conservan y se puede reintentar solo el fallido. Al terminar, se
comprueba en destino que las claves enviadas existen (POST /api/verificar, consultas por
lotes). Supabase no indica cuántas filas de un upsert eran nuevas y cuántas actualizadas, así
que la app no muestra ese desglose.La pestaña Datos en Supabase lee la tabla real (GET /api/mediciones) con paginación,
filtros, ORDER BY explícito y botón de actualizar. Una tabla no conserva el orden de
inserción, así que cualquier consulta que necesite un orden debe pedirlo.
lib/supabase/servidor.ts importa server-only).npm run dev) la carga está abierta. Con
next start queda bloqueada salvo que se defina ETL_PERMITIR_ESCRITURA_SIN_AUTH=true.
Antes de publicarla hay que proteger /api/carga, /api/verificar y /api/mediciones.app/page.tsx pantalla de trabajo
app/api/carga|verificar|mediciones/route.ts
components/etl/ interfaz (pipeline, tablas, pestañas)
hooks/use-pipeline-etl.ts estado del pipeline en el navegador
lib/etl/ lógica pura: extracción, transformación, limpieza, filtros, carga
lib/supabase/servidor.ts cliente con clave secreta (solo servidor)
supabase/migrations/ SQL de la tabla
tests/unit, tests/integracion, tests/fixtures (solo para pruebas)