Mismo que anterior Commit
This commit is contained in:
15
.env
15
.env
@@ -1,15 +0,0 @@
|
||||
# --- Conexión a la Base de Datos ---
|
||||
ConnectionStrings__DefaultConnection="Server=TECNICA3;Database=MercadosDb;User Id=mercadosuser;Password=@mercados1351@;Trusted_Connection=False;Encrypt=False;"
|
||||
|
||||
# --- Claves de APIs Externas ---
|
||||
ApiKeys__Finnhub="cuvhr0hr01qs9e81st2gcuvhr0hr01qs9e81st30"
|
||||
ApiKeys__Bcr__Key="D1782A51-A5FD-EF11-9445-00155D09E201"
|
||||
ApiKeys__Bcr__Secret="da96378186bc5a256fa821fbe79261ec7172dec283214da0aacca41c640f80e3"
|
||||
|
||||
# --- Configuración de Email para Alertas ---
|
||||
SMTP_HOST="mail.eldia.com"
|
||||
SMTP_PORT="587"
|
||||
SMTP_USER="alertas@eldia.com"
|
||||
SMTP_PASS="@Alertas713550@"
|
||||
EMAIL_SENDER_NAME="Servicio de Mercados"
|
||||
EMAIL_RECIPIENT="dmolinari@eldia.com"
|
||||
@@ -1,13 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>28c6a673-1f1e-4140-aa75-a0d894d1fbc4</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DotNetEnv" Version="3.1.1" />
|
||||
<PackageReference Include="FluentMigrator.Runner" Version="7.1.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.5" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.1" />
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
using DotNetEnv;
|
||||
using FluentMigrator.Runner;
|
||||
using Mercados.Database.Migrations;
|
||||
using Mercados.Infrastructure;
|
||||
using Mercados.Infrastructure.Persistence;
|
||||
using Mercados.Infrastructure.Persistence.Repositories;
|
||||
using DotNetEnv.Configuration;
|
||||
|
||||
|
||||
var envFilePath = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../../../.env"));
|
||||
|
||||
// Cargamos el archivo .env desde la ruta explícita.
|
||||
if (!Env.Load(envFilePath).Any())
|
||||
{
|
||||
Console.WriteLine($"ADVERTENCIA: No se pudo encontrar el archivo .env en la ruta: {envFilePath}");
|
||||
}
|
||||
using Mercados.Api.Utils;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
@@ -50,7 +40,14 @@ builder.Services
|
||||
.ScanIn(typeof(CreateInitialTables).Assembly).For.Migrations())
|
||||
.AddLogging(lb => lb.AddFluentMigratorConsole());
|
||||
|
||||
// Servicios del contenedor estándar (perfecto)
|
||||
|
||||
builder.Services.AddControllers()
|
||||
.AddJsonOptions(options =>
|
||||
{
|
||||
// Añadimos nuestro convertidor personalizado para manejar las fechas.
|
||||
options.JsonSerializerOptions.Converters.Add(new UtcDateTimeConverter());
|
||||
});
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
|
||||
27
src/Mercados.Api/Utils/UtcDateTimeConverter.cs
Normal file
27
src/Mercados.Api/Utils/UtcDateTimeConverter.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Mercados.Api.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// Un convertidor de JSON personalizado para asegurar que los objetos DateTime
|
||||
/// se serialicen al formato ISO 8601 en UTC (con el designador 'Z').
|
||||
/// </summary>
|
||||
public class UtcDateTimeConverter : JsonConverter<DateTime>
|
||||
{
|
||||
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
// Al leer un string de fecha, nos aseguramos de que se interprete como UTC
|
||||
return reader.GetDateTime().ToUniversalTime();
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
|
||||
{
|
||||
// Antes de escribir el string, especificamos que el 'Kind' es Utc.
|
||||
// Si ya es Utc, no hace nada. Si es Local o Unspecified, lo trata como si fuera Utc.
|
||||
// Esto es seguro porque sabemos que todas nuestras fechas en la BD son UTC.
|
||||
var utcValue = DateTime.SpecifyKind(value, DateTimeKind.Utc);
|
||||
writer.WriteStringValue(utcValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,24 @@
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": ""
|
||||
},
|
||||
"Schedules": {
|
||||
"MercadoAgroganadero": "0 11 * * 1-5",
|
||||
"BCR": "30 11 * * 1-5",
|
||||
"Bolsas": "10 11-17 * * 1-5"
|
||||
},
|
||||
"ApiKeys": {
|
||||
"Finnhub": "",
|
||||
"Bcr": {
|
||||
"Key": "",
|
||||
"Secret": ""
|
||||
}
|
||||
},
|
||||
"SmtpSettings": {
|
||||
"Host": "",
|
||||
"Port": 587,
|
||||
"User": "",
|
||||
"Pass": "",
|
||||
"SenderName": "Servicio de Mercados",
|
||||
"Recipient": ""
|
||||
}
|
||||
}
|
||||
@@ -20,12 +20,12 @@ namespace Mercados.Infrastructure.Services
|
||||
public async Task SendFailureAlertAsync(string subject, string message, DateTime? eventTimeUtc = null)
|
||||
{
|
||||
// Leemos la configuración de forma segura desde IConfiguration (que a su vez lee el .env)
|
||||
var smtpHost = _configuration["SMTP_HOST"];
|
||||
var smtpPort = int.Parse(_configuration["SMTP_PORT"] ?? "587");
|
||||
var smtpUser = _configuration["SMTP_USER"];
|
||||
var smtpPass = _configuration["SMTP_PASS"];
|
||||
var senderName = _configuration["EMAIL_SENDER_NAME"];
|
||||
var recipient = _configuration["EMAIL_RECIPIENT"];
|
||||
var smtpHost = _configuration["SmtpSettings:Host"];
|
||||
var smtpPort = _configuration.GetValue<int>("SmtpSettings:Port");
|
||||
var smtpUser = _configuration["SmtpSettings:User"];
|
||||
var smtpPass = _configuration["SmtpSettings:Pass"];
|
||||
var senderName = _configuration["SmtpSettings:SenderName"];
|
||||
var recipient = _configuration["SmtpSettings:Recipient"];
|
||||
|
||||
if (string.IsNullOrEmpty(smtpHost) || string.IsNullOrEmpty(smtpUser) || string.IsNullOrEmpty(smtpPass))
|
||||
{
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Cronos" Version="0.11.0" />
|
||||
<PackageReference Include="DotNetEnv" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -7,49 +7,30 @@ using Mercados.Worker;
|
||||
using Polly;
|
||||
using Polly.Extensions.Http;
|
||||
using Mercados.Infrastructure.Services;
|
||||
using DotNetEnv;
|
||||
using DotNetEnv.Configuration;
|
||||
|
||||
var envFilePath = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../../../.env"));
|
||||
|
||||
// Cargamos el archivo .env desde la ruta explícita.
|
||||
// Si no lo encuentra, Load retornará false.
|
||||
if (!Env.Load(envFilePath).Any())
|
||||
{
|
||||
Console.WriteLine($"ADVERTENCIA: No se pudo encontrar el archivo .env en la ruta: {envFilePath}");
|
||||
}
|
||||
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
|
||||
IHost host = Host.CreateDefaultBuilder(args)
|
||||
.ConfigureServices((hostContext, services) =>
|
||||
{
|
||||
// La línea 'config.AddDotNetEnv(optional: true);' ha sido eliminada.
|
||||
|
||||
IConfiguration configuration = hostContext.Configuration;
|
||||
|
||||
// --- 1. Registro de Servicios de Infraestructura ---
|
||||
// El resto del código no cambia. IConfiguration recogerá automáticamente
|
||||
// las variables de entorno que cargamos correctamente.
|
||||
services.AddSingleton<IDbConnectionFactory, SqlConnectionFactory>();
|
||||
services.AddScoped<ICotizacionGanadoRepository, CotizacionGanadoRepository>();
|
||||
services.AddScoped<ICotizacionGranoRepository, CotizacionGranoRepository>();
|
||||
services.AddScoped<ICotizacionBolsaRepository, CotizacionBolsaRepository>();
|
||||
services.AddScoped<IFuenteDatoRepository, FuenteDatoRepository>();
|
||||
//services.AddScoped<INotificationService, ConsoleNotificationService>();
|
||||
services.AddScoped<INotificationService, EmailNotificationService>();
|
||||
|
||||
// --- 2. Registro de los Data Fetchers ---
|
||||
// Descomentados para la versión final y funcional.
|
||||
services.AddScoped<IDataFetcher, MercadoAgroFetcher>();
|
||||
services.AddScoped<IDataFetcher, BcrDataFetcher>();
|
||||
services.AddScoped<IDataFetcher, FinnhubDataFetcher>();
|
||||
services.AddScoped<IDataFetcher, YahooFinanceDataFetcher>();
|
||||
|
||||
// --- 3. Configuración de Clientes HTTP con Polly ---
|
||||
services.AddHttpClient("MercadoAgroFetcher").AddPolicyHandler(GetRetryPolicy());
|
||||
services.AddHttpClient("BcrDataFetcher").AddPolicyHandler(GetRetryPolicy());
|
||||
services.AddHttpClient("FinnhubDataFetcher").AddPolicyHandler(GetRetryPolicy());
|
||||
|
||||
// --- 4. Registro del Worker Principal ---
|
||||
services.AddHostedService<DataFetchingService>();
|
||||
})
|
||||
.Build();
|
||||
|
||||
@@ -20,5 +20,13 @@
|
||||
"Key": "",
|
||||
"Secret": ""
|
||||
}
|
||||
},
|
||||
"SmtpSettings": {
|
||||
"Host": "",
|
||||
"Port": 587,
|
||||
"User": "",
|
||||
"Pass": "",
|
||||
"SenderName": "Servicio de Mercados",
|
||||
"Recipient": ""
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user