< Summary

Information
Line coverage
0%
Covered lines: 0
Uncovered lines: 160
Coverable lines: 160
Total lines: 231
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 6
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
<Main>$()0%4260%

File(s)

/home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.API/Program.cs

#LineLine coverage
 1using System.Text;
 2using FAU.API.Middleware;
 3using FAU.API.Security;
 4using FAU.API.Seeds;
 5using FAU.DataAccess;
 6using FAU.DataAccess.Repositories;
 7using FAU.Entidades.Auditoria;
 8using FAU.Logica.Services;
 9using FAU.Logica.Services.InsumoValidators;
 10using Microsoft.AspNetCore.Authentication.JwtBearer;
 11using Microsoft.AspNetCore.Authorization;
 12using Microsoft.EntityFrameworkCore;
 13using Microsoft.IdentityModel.Tokens;
 14using Microsoft.OpenApi.Models;
 15using Microsoft.AspNetCore.HttpOverrides;
 16using Serilog;
 17
 18// Npgsql 7+ requiere Kind=UTC para timestamptz; habilitar comportamiento legacy para columnas timestamp sin zona
 019AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
 20
 021var builder = WebApplication.CreateBuilder(args);
 22
 23// Log del ambiente y configuración cargada
 024var environment = builder.Environment.EnvironmentName;
 025var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
 26
 027Console.WriteLine("=====================================");
 028Console.WriteLine($"Ambiente: {environment}");
 029Console.WriteLine("=====================================");
 30
 031builder.Services.AddDbContext<ApplicationDbContext>(options =>
 032    options.UseNpgsql(connectionString, o => o.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery)));
 33
 034Auditoria.IniciarAuditoria(builder.Configuration);
 35
 36// Redirigir ILogger<T> de todos los servicios/controladores hacia Serilog
 037builder.Logging.ClearProviders();
 038builder.Logging.AddSerilog(Log.Logger);
 39
 40// Configuración de JWT
 041var jwtKey = builder.Configuration["Jwt:Key"] ?? throw new InvalidOperationException("JWT Key no configurada");
 042var jwtIssuer = builder.Configuration["Jwt:Issuer"];
 043var jwtAudience = builder.Configuration["Jwt:Audience"];
 44
 045builder.Services.AddAuthentication(options =>
 046{
 047    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
 048    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
 049})
 050.AddJwtBearer(options =>
 051{
 052    options.RequireHttpsMetadata = false; // En producción debe ser true
 053    options.SaveToken = true;
 054    options.TokenValidationParameters = new TokenValidationParameters
 055    {
 056        ValidateIssuerSigningKey = true,
 057        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey)),
 058        ValidateIssuer = true,
 059        ValidIssuer = jwtIssuer,
 060        ValidateAudience = true,
 061        ValidAudience = jwtAudience,
 062        ValidateLifetime = true,
 063        ClockSkew = TimeSpan.Zero
 064    };
 065});
 66
 067builder.Services.AddAuthorization();
 68
 69// Políticas dinámicas: Permission:xxx
 070builder.Services.AddSingleton<IAuthorizationPolicyProvider, PermissionPolicyProvider>();
 071builder.Services.AddSingleton<IAuthorizationHandler, PermissionAuthorizationHandler>();
 72
 73// HttpContext + Current user context (auditoría)
 074builder.Services.AddHttpContextAccessor();
 075builder.Services.AddScoped<FAU.Logica.Services.ICurrentUserContext, FAU.API.Services.CurrentUserContext>();
 76
 77// Registro de repositorios
 078builder.Services.AddScoped<IUsuarioRepository, UsuarioRepository>();
 079builder.Services.AddScoped<IRolRepository, RolRepository>();
 080builder.Services.AddScoped<IPermisoRepository, PermisoRepository>();
 081builder.Services.AddScoped<IAuditoriaRepository, AuditoriaRepository>();
 082builder.Services.AddScoped<IBancoRepository, BancoRepository>();
 083builder.Services.AddScoped<IPersonalRepository, PersonalRepository>();
 084builder.Services.AddScoped<ITipoBeneficioRepository, TipoBeneficioRepository>();
 085builder.Services.AddScoped<IBeneficioSocialRepository, BeneficioSocialRepository>();
 086builder.Services.AddScoped<IIrpfRepository, IrpfRepository>();
 087builder.Services.AddScoped<IDependienteRepository, DependienteRepository>();
 088builder.Services.AddScoped<ICompensacionRepository, CompensacionRepository>();
 089builder.Services.AddScoped<IParametroLiquidacionRepository, ParametroLiquidacionRepository>();
 090builder.Services.AddScoped<IPeriodosRepository, PeriodosRepository>();
 091builder.Services.AddScoped<INovedadPeriodoRepository, NovedadPeriodoRepository>();
 092builder.Services.AddScoped<ISnapshotsRepository, SnapshotsRepository>();
 93
 94// Registro de servicios
 095builder.Services.AddScoped<IAuthService, AuthService>();
 096builder.Services.AddScoped<IUsuarioService, UsuarioService>();
 097builder.Services.AddScoped<IRolService, RolService>();
 098builder.Services.AddScoped<IAuditoriaCatalogoResolver, AuditoriaCatalogoResolver>();
 099builder.Services.AddScoped<IAuditoriaService, AuditoriaService>();
 0100builder.Services.AddScoped<IBancoService, BancoService>();
 0101builder.Services.AddScoped<IPersonalService, PersonalService>();
 0102builder.Services.AddScoped<ITipoBeneficioService, TipoBeneficioService>();
 0103builder.Services.AddScoped<IBeneficioSocialService, BeneficioSocialService>();
 0104builder.Services.AddScoped<IDependienteService, DependienteService>();
 0105builder.Services.AddScoped<ICompensacionService, CompensacionService>();
 0106builder.Services.AddScoped<IParametroLiquidacionService, ParametroLiquidacionService>();
 0107builder.Services.AddScoped<IInsumoValidator, LotesCompensacionValidator>();
 0108builder.Services.AddScoped<IInsumoValidator, BeneficiosSocialesValidator>();
 0109builder.Services.AddScoped<IInsumoValidator, NovedadesPeriodoValidator>();
 0110builder.Services.AddScoped<IInsumoValidator, RetroactividadesPendientesValidator>();
 0111builder.Services.AddScoped<IInsumoValidator, TablasReferenciaValidator>();
 0112builder.Services.AddScoped<IInsumoEvaluador, InsumoEvaluador>();
 0113builder.Services.AddScoped<IInsumosPeriodoLoader, InsumosPeriodoLoader>();
 0114builder.Services.AddScoped<IPeriodoService, PeriodoService>();
 0115builder.Services.AddScoped<INovedadPeriodoService, NovedadPeriodoService>();
 0116builder.Services.AddScoped<IPeriodoGuard, PeriodoGuard>();
 0117builder.Services.AddScoped<ILiquidacionService, LiquidacionService>();
 118
 119// Add services to the container.
 0120builder.Services.AddControllers();
 121
 122// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
 0123builder.Services.AddEndpointsApiExplorer();
 0124builder.Services.AddHealthChecks();
 0125builder.Services.AddSwaggerGen(c =>
 0126{
 0127    c.SwaggerDoc("v1", new OpenApiInfo
 0128    {
 0129        Title = "FAU Liquidación API",
 0130        Version = "v1",
 0131        Description = "API para el sistema de liquidación de la FAU"
 0132    });
 0133
 0134    // Configurar Swagger para usar JWT
 0135    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
 0136    {
 0137        Description = "JWT Authorization header usando el esquema Bearer. Ejemplo: \"Bearer {token}\"",
 0138        Name = "Authorization",
 0139        In = ParameterLocation.Header,
 0140        Type = SecuritySchemeType.ApiKey,
 0141        Scheme = "Bearer"
 0142    });
 0143
 0144    c.AddSecurityRequirement(new OpenApiSecurityRequirement
 0145    {
 0146        {
 0147            new OpenApiSecurityScheme
 0148            {
 0149                Reference = new OpenApiReference
 0150                {
 0151                    Type = ReferenceType.SecurityScheme,
 0152                    Id = "Bearer"
 0153                }
 0154            },
 0155            Array.Empty<string>()
 0156        }
 0157    });
 0158});
 159
 160// Configuración de CORS (opcional, para desarrollo)
 0161builder.Services.AddCors(options =>
 0162{
 0163    options.AddPolicy("AllowAll", policy =>
 0164    {
 0165        policy.AllowAnyOrigin()
 0166              .AllowAnyMethod()
 0167              .AllowAnyHeader();
 0168    });
 0169});
 170
 0171var app = builder.Build();
 172
 173// Forwarded headers (si está detrás de proxy / ingress)
 0174app.UseForwardedHeaders(new ForwardedHeadersOptions
 0175{
 0176    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
 0177});
 178
 179// Comando de seeding: dotnet run --seed-admin
 180// Crea el primer usuario Administrador y termina sin levantar el servidor HTTP.
 0181if (args.Contains("--seed-admin"))
 182{
 0183    using var scope = app.Services.CreateScope();
 0184    var exitCode = await SuperAdminSeeder.RunAsync(args, scope.ServiceProvider);
 0185    Environment.Exit(exitCode);
 0186    return;
 187}
 188
 189// Validar conexión a la base de datos al inicio
 0190using (var scope = app.Services.CreateScope())
 191{
 0192    var services = scope.ServiceProvider;
 193    try
 194    {
 0195        var context = services.GetRequiredService<ApplicationDbContext>();
 0196        var canConnect = context.Database.CanConnect();
 197
 0198        if (!canConnect)
 199        {
 0200            app.Logger.LogError("No se pudo conectar a la base de datos");
 0201            throw new Exception("No se pudo establecer conexión con la base de datos");
 202        }
 0203    }
 0204    catch (Exception ex)
 205    {
 0206        app.Logger.LogError(ex, "Error al validar la conexión a la base de datos: {Message}", ex.Message);
 0207        throw;
 208    }
 0209}
 210
 211// Configure the HTTP request pipeline.
 212// Habilitar Swagger en todos los ambientes (útil para Docker)
 0213app.UseSwagger();
 0214app.UseSwaggerUI(c =>
 0215{
 0216    c.SwaggerEndpoint("/swagger/v1/swagger.json", "FAU Liquidación API v1");
 0217});
 218
 0219app.UseHttpsRedirection();
 220
 0221app.UseCors("AllowAll");
 222
 0223app.UseAuthentication(); // IMPORTANTE: debe ir antes de UseAuthorization
 0224app.UseMiddleware<LogUserEnricherMiddleware>(); // Enriquece logs con el usuario autenticado
 0225app.UseAuthorization();
 226
 227
 0228app.MapHealthChecks("/health");
 0229app.MapControllers();
 230
 0231app.Run();

Methods/Properties

<Main>$()