feat: Worker Service - API endpoints

Implement and configure Worker Service to orchestrate data fetchers - Implement API endpoints for stock market data
This commit is contained in:
2025-07-01 12:19:00 -03:00
parent 2fdf80f5b4
commit 10f19af9f8
15 changed files with 680 additions and 44 deletions

View File

@@ -0,0 +1,57 @@
using Mercados.Core.Entities;
using Mercados.Infrastructure.Persistence.Repositories;
using Microsoft.AspNetCore.Mvc;
namespace Mercados.Api.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class MercadosController : ControllerBase
{
private readonly ICotizacionBolsaRepository _bolsaRepo;
private readonly ILogger<MercadosController> _logger;
// Inyectamos los repositorios que este controlador necesita.
public MercadosController(ICotizacionBolsaRepository bolsaRepo, ILogger<MercadosController> logger)
{
_bolsaRepo = bolsaRepo;
_logger = logger;
}
[HttpGet("bolsa/eeuu")]
[ProducesResponseType(typeof(IEnumerable<CotizacionBolsa>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetBolsaUsa()
{
try
{
var data = await _bolsaRepo.ObtenerUltimasPorMercadoAsync("EEUU");
return Ok(data);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener cotizaciones de bolsa de EEUU.");
return StatusCode(500, "Ocurrió un error interno en el servidor.");
}
}
[HttpGet("bolsa/local")]
[ProducesResponseType(typeof(IEnumerable<CotizacionBolsa>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetBolsaLocal()
{
try
{
var data = await _bolsaRepo.ObtenerUltimasPorMercadoAsync("Local");
return Ok(data);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al obtener cotizaciones de bolsa local.");
return StatusCode(500, "Ocurrió un error interno en el servidor.");
}
}
// NOTA: Añadiremos los endpoints para Granos y Ganado en un momento.
}
}

View File

@@ -1,17 +1,22 @@
using FluentMigrator.Runner; // <--- AÑADIR
using Mercados.Database.Migrations; // <--- AÑADIR
using FluentMigrator.Runner;
using Mercados.Database.Migrations;
using Mercados.Infrastructure;
using Mercados.Infrastructure.Persistence;
using System.Reflection; // <--- AÑADIR
using Mercados.Infrastructure.Persistence.Repositories;
using System.Reflection;
var builder = WebApplication.CreateBuilder(args);
// --- V INICIO DE NUESTRO CÓDIGO V ---
// 1. Registramos nuestra fábrica de conexiones.
// 1. Registramos nuestra fábrica de conexiones a la BD.
builder.Services.AddSingleton<IDbConnectionFactory, SqlConnectionFactory>();
// 2. Configurar FluentMigrator
// 2. AÑADIR: Registramos los repositorios que la API necesitará para LEER datos.
builder.Services.AddScoped<ICotizacionGanadoRepository, CotizacionGanadoRepository>();
builder.Services.AddScoped<ICotizacionGranoRepository, CotizacionGranoRepository>();
builder.Services.AddScoped<ICotizacionBolsaRepository, CotizacionBolsaRepository>();
builder.Services.AddScoped<IFuenteDatoRepository, FuenteDatoRepository>();
// 3. Configurar FluentMigrator
builder.Services
.AddFluentMigratorCore()
.ConfigureRunner(rb => rb
@@ -25,8 +30,6 @@ builder.Services
.AddLogging(lb => lb.AddFluentMigratorConsole());
// --- ^ FIN DE NUESTRO CÓDIGO ^ ---
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
@@ -35,9 +38,7 @@ builder.Services.AddSwaggerGen();
var app = builder.Build();
// --- V INICIO DE NUESTRO CÓDIGO DE EJECUCIÓN V ---
// 3. Ejecutar las migraciones al iniciar la aplicación (ideal para desarrollo y despliegues sencillos)
// 4. Ejecutar las migraciones al iniciar la aplicación (ideal para desarrollo y despliegues sencillos)
// Obtenemos el "scope" de los servicios para poder solicitar el MigrationRunner
using (var scope = app.Services.CreateScope())
{
@@ -46,9 +47,6 @@ using (var scope = app.Services.CreateScope())
migrationRunner.MigrateUp();
}
// --- ^ FIN DE NUESTRO CÓDIGO DE EJECUCIÓN ^ ---
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{

View File

@@ -8,5 +8,12 @@
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Server=TECNICA3;Database=MercadosDb;User Id=mercadosuser;Password=@mercados1351@;Trusted_Connection=False;Encrypt=False;"
},
"ApiKeys": {
"Finnhub": "cuvhr0hr01qs9e81st2gcuvhr0hr01qs9e81st30",
"Bcr": {
"Key": "D1782A51-A5FD-EF11-9445-00155D09E201",
"Secret": "da96378186bc5a256fa821fbe79261ec7172dec283214da0aacca41c640f80e3"
}
}
}