Feat(holidays): Implement database-backed holiday detection system
- Adds a new `MercadosFeriados` table to the database to persist market holidays.
- Implements `HolidayDataFetcher` to update holidays weekly from Finnhub API.
- Implements `IHolidayService` with in-memory caching to check for holidays efficiently.
- Worker service now skips fetcher execution on market holidays.
- Adds a new API endpoint `/api/mercados/es-feriado/{mercado}`.
- Integrates a non-blocking holiday alert into the `BolsaLocalWidget`."
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using Mercados.Core.Entities;
|
||||
using Mercados.Infrastructure.Persistence.Repositories;
|
||||
using Mercados.Infrastructure.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Mercados.Api.Controllers
|
||||
@@ -11,6 +12,7 @@ namespace Mercados.Api.Controllers
|
||||
private readonly ICotizacionBolsaRepository _bolsaRepo;
|
||||
private readonly ICotizacionGranoRepository _granoRepo;
|
||||
private readonly ICotizacionGanadoRepository _ganadoRepo;
|
||||
private readonly IHolidayService _holidayService;
|
||||
private readonly ILogger<MercadosController> _logger;
|
||||
|
||||
// Inyectamos TODOS los repositorios que necesita el controlador.
|
||||
@@ -18,11 +20,13 @@ namespace Mercados.Api.Controllers
|
||||
ICotizacionBolsaRepository bolsaRepo,
|
||||
ICotizacionGranoRepository granoRepo,
|
||||
ICotizacionGanadoRepository ganadoRepo,
|
||||
IHolidayService holidayService,
|
||||
ILogger<MercadosController> logger)
|
||||
{
|
||||
_bolsaRepo = bolsaRepo;
|
||||
_granoRepo = granoRepo;
|
||||
_ganadoRepo = ganadoRepo;
|
||||
_holidayService = holidayService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -147,5 +151,30 @@ namespace Mercados.Api.Controllers
|
||||
return StatusCode(500, "Ocurrió un error interno en el servidor.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("es-feriado/{mercado}")]
|
||||
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
public async Task<IActionResult> IsMarketHoliday(string mercado)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Usamos la fecha actual en la zona horaria de Argentina
|
||||
TimeZoneInfo argentinaTimeZone;
|
||||
try { argentinaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("America/Argentina/Buenos_Aires"); }
|
||||
catch { argentinaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Argentina Standard Time"); }
|
||||
|
||||
var todayInArgentina = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, argentinaTimeZone);
|
||||
|
||||
var esFeriado = await _holidayService.IsMarketHolidayAsync(mercado.ToUpper(), todayInArgentina);
|
||||
return Ok(esFeriado);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error al comprobar si es feriado para el mercado {Mercado}.", mercado);
|
||||
// Si hay un error, devolvemos 'false' para no bloquear la UI innecesariamente.
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user