using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System.Text; using GestionIntegral.Api.Data; using GestionIntegral.Api.Services.Contables; using GestionIntegral.Api.Services.Distribucion; using GestionIntegral.Api.Services.Radios; using GestionIntegral.Api.Data.Repositories.Contables; using GestionIntegral.Api.Data.Repositories.Distribucion; using GestionIntegral.Api.Data.Repositories.Impresion; using GestionIntegral.Api.Data.Repositories.Radios; using GestionIntegral.Api.Services.Impresion; using GestionIntegral.Api.Services.Usuarios; using GestionIntegral.Api.Data.Repositories.Usuarios; using Microsoft.OpenApi.Models; using GestionIntegral.Api.Data.Repositories.Reportes; using GestionIntegral.Api.Services.Reportes; using GestionIntegral.Api.Services.Pdf; using Microsoft.Extensions.Diagnostics.HealthChecks; using GestionIntegral.Api.Services.Anomalia; using GestionIntegral.Api.Data.Repositories.Suscripciones; using GestionIntegral.Api.Services.Suscripciones; using GestionIntegral.Api.Models.Comunicaciones; using GestionIntegral.Api.Services.Comunicaciones; var builder = WebApplication.CreateBuilder(args); // --- Registros de Servicios --- builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); // Servicio de Saldos builder.Services.AddScoped(); // Repositorios de Reportes builder.Services.AddScoped(); // Servicios de Reportes builder.Services.AddScoped(); // QuestPDF builder.Services.AddScoped(); // Servicio de Alertas builder.Services.AddScoped(); // --- Suscripciones --- builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); // --- Comunicaciones --- builder.Services.Configure(builder.Configuration.GetSection("MailSettings")); builder.Services.AddTransient(); // --- SERVICIO DE HEALTH CHECKS --- // Añadimos una comprobación específica para SQL Server. // El sistema usará la cadena de conexión configurada en appsettings.json o variables de entorno. builder.Services.AddHealthChecks() .AddSqlServer( connectionString: builder.Configuration.GetConnectionString("DefaultConnection") ?? "", healthQuery: "SELECT 1;", name: "sql-server", failureStatus: HealthStatus.Unhealthy, tags: new string[] { "database" } ); // --- Configuración de Autenticación JWT --- var jwtSettings = builder.Configuration.GetSection("Jwt"); // Le decimos que busque la clave JWT en la raíz de la configuración (donde están las variables de entorno). // Si no la encuentra, como respaldo, busca en la sección "Jwt" del appsettings. var jwtKey = builder.Configuration["JWT_KEY"] ?? jwtSettings["Key"] ?? throw new ArgumentNullException("JWT_KEY or Jwt:Key not configured"); var keyBytes = Encoding.ASCII.GetBytes(jwtKey); builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.RequireHttpsMetadata = builder.Environment.IsProduction(); options.SaveToken = true; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(keyBytes), ValidateIssuer = true, ValidIssuer = jwtSettings["Issuer"], ValidateAudience = true, ValidAudience = jwtSettings["Audience"], ValidateLifetime = true, ClockSkew = TimeSpan.Zero }; }); // --- Configuración de Autorización --- builder.Services.AddAuthorization(); // --- Configuración de CORS --- // var MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; builder.Services.AddCors(options => { options.AddPolicy(name: MyAllowSpecificOrigins, policy => { policy.WithOrigins( "http://localhost:5173", // Para desarrollo local "https://gestion.eldiaservicios.com" // Para producción ) .AllowAnyHeader() .AllowAnyMethod(); }); }); // --- Fin CORS --- // --- Servicios del Contenedor --- builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); // --- Configuración Avanzada de Swagger/OpenAPI --- builder.Services.AddSwaggerGen(options => { // Definición general del documento Swagger options.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "GestionIntegral API", Description = "API para el sistema de Gestión Integral (Migración VB.NET)", // Puedes añadir TermsOfService, Contact, License si lo deseas }); // (Opcional) Incluir comentarios XML si los usas en tus controladores/DTOs // var xmlFilename = $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml"; // options.IncludeXmlComments(System.IO.Path.Combine(AppContext.BaseDirectory, xmlFilename)); // Definición de Seguridad para JWT en Swagger UI // Esto añade el botón "Authorize" en la UI de Swagger para poder pegar el token Bearer options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { In = ParameterLocation.Header, Description = "Por favor, introduce 'Bearer' seguido de un espacio y luego tu token JWT.", Name = "Authorization", Type = SecuritySchemeType.ApiKey, // Usar ApiKey para el formato Bearer simple Scheme = "Bearer" // Esquema a usar }); options.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" // Debe coincidir con el Id definido en AddSecurityDefinition }, Scheme = "oauth2", // Aunque el scheme sea ApiKey, a veces se usa oauth2 aquí para la UI Name = "Bearer", In = ParameterLocation.Header, }, new List() // Lista de scopes (vacía si no usas scopes OAuth2 complejos) } }); }); // --- Fin Configuración Swagger --- var app = builder.Build(); // Habilitamos Swagger SIEMPRE, sin importar el entorno. app.UseSwagger(); // Habilita el middleware para servir el JSON de Swagger app.UseSwaggerUI(options => // Habilita el middleware para servir la UI de Swagger { options.SwaggerEndpoint("/swagger/v1/swagger.json", "GestionIntegral API v1"); // Opcional: Para que Swagger aparezca en la raíz de la API (ej: http://192.168.4.128:8081/) options.RoutePrefix = string.Empty; }); // Mantenemos esta lógica solo para la página de error de desarrollo, si quieres. if (app.Environment.IsDevelopment()) { // Aquí puedes dejar otras herramientas solo para desarrollo si las tuvieras. } // ¡¡¡NO USAR UseHttpsRedirection si la API corre en HTTP!!! // Comenta o elimina la siguiente línea si SÓLO usas http://localhost:5183 //app.UseHttpsRedirection(); app.UseCors(MyAllowSpecificOrigins); app.UseAuthentication(); // Debe ir ANTES de UseAuthorization app.UseAuthorization(); // Mapeamos la ruta "/health". Cuando se acceda a ella, se ejecutarán todas las comprobaciones registradas. // Esto va ANTES de app.MapControllers(). app.MapHealthChecks("/health"); app.MapControllers(); app.Run();