Este repositorio contiene la solución completa para la obtención, almacenamiento y visualización de datos del pronóstico del tiempo del **Servicio Meteorológico Nacional (SMN) de Argentina**. La arquitectura está diseñada para ser robusta, escalable y fácil de mantener, desacoplando la obtención de datos (Worker) de la exposición de los mismos (API) y la visualización (Frontend).
## ✨ Características Principales
- **Proceso ETL Automatizado:** Un Worker Service de fondo se encarga de descargar, transformar y cargar (`ETL`) los datos del pronóstico de 5 días desde la fuente oficial del SMN.
- **Parseo Robusto:** El sistema es capaz de manejar archivos ZIP y parsear el formato de texto de ancho fijo proporcionado por el SMN.
- **Base de Datos Persistente:** Utiliza SQL Server para almacenar el historial de pronósticos, con un esquema gestionado por migraciones de código (`FluentMigrator`).
- **Frontend Modular y Moderno:** Construido con React, TypeScript y Vite. La UI está compuesta por "widgets" independientes que se pueden reorganizar o embeber en otros sitios.
- **Arquitectura Resiliente:** El Worker utiliza políticas de reintento (`Polly`) para manejar fallos temporales en la red o en la fuente de datos.
- **Listo para Producción:** El proyecto está completamente "contenedorizado" con Docker y `docker-compose` para un despliegue sencillo y consistente.
---
## 🏛️ Arquitectura del Sistema
El proyecto sigue una arquitectura de microservicios desacoplados que se comunican a través de redes y APIs.
**Flujo de Datos (ETL):**
`Fuente SMN (.zip)` ➔ `Clima.Worker (ETL)` ➔ `Base de Datos SQL Server`
# Establecer la cadena de conexión (reemplaza con tu configuración local)
dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=.;Database=ClimaDb;Trusted_Connection=True;Encrypt=False;" --project src/Clima.Api
dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=.;Database=ClimaDb;Trusted_Connection=True;Encrypt=False;" --project src/Clima.Worker
```
### 3. Instalar Dependencias del Frontend
```bash
cd frontend
npm install
cd ..
```
### 4. Crear y Migrar la Base de Datos
La primera vez que ejecutes la API, FluentMigrator creará la base de datos y aplicará las migraciones.
```bash
dotnet run --project src/Clima.Api
```
Puedes detenerla (`Ctrl+C`) una vez que el servidor se haya iniciado.
---
## 🏃 Cómo Ejecutar el Proyecto
Para trabajar en el proyecto, necesitarás 3 terminales abiertas en la raíz (`/Clima`).
**1. Terminal 1 - Iniciar el Backend API:**
```bash
dotnet run --project src/Clima.Api
```
*La API estará disponible en los puertos definidos en `launchSettings.json` (ej. `http://localhost:5000`).*
**2. Terminal 2 - Iniciar el Worker Service:**
```bash
dotnet run --project src/Clima.Worker
```
*El worker se ejecutará una vez al inicio para obtener datos y luego cada 3 horas.*
**3. Terminal 3 - Iniciar el Frontend:**
```bash
cd frontend
npm run dev
```
*La aplicación de React estará disponible en `http://localhost:5173`.*
---
## 📁 Estructura del Proyecto
- **`src/Clima.Core`**: Contiene las entidades de dominio (modelos de datos) compartidas por toda la solución.
- **`src/Clima.Infrastructure`**: Contiene la lógica de acceso a datos (Repositorios con Dapper) y la comunicación con servicios externos (el `SmnEtlFetcher`).
- **`src/Clima.Database`**: Define el esquema de la base de datos a través de migraciones de FluentMigrator.
- **`src/Clima.Api`**: La API web de ASP.NET Core que expone los datos a través de endpoints REST.
- **`src/Clima.Worker`**: El servicio de fondo que se ejecuta periódicamente para realizar el proceso ETL.
- **`frontend/`**: El proyecto de React/Vite que contiene todos los componentes de la interfaz de usuario.
- **`docker-compose.yml`**: Orquesta el despliegue de los servicios en un entorno de producción.
---
## 🐳 Despliegue en Producción (Docker)
El proyecto está diseñado para ser desplegado como un stack de Docker Compose.
1. **Construir las Imágenes:** Desde la raíz del proyecto en el servidor de producción, ejecuta:
```bash
docker compose build
```
2. **Lanzar el Stack:** Asegúrate de tener un archivo `.env` en el servidor con la cadena de conexión de producción y ejecuta:
```bash
docker compose up -d
```
El `docker-compose.yml` está configurado para conectarse a una red externa `shared-net` y ser gestionado por un proxy inverso externo como Nginx Proxy Manager.