< Summary

Information
Line coverage
0%
Covered lines: 0
Uncovered lines: 150
Coverable lines: 150
Total lines: 216
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.Security;
 3using FAU.API.Seeds;
 4using FAU.DataAccess;
 5using FAU.DataAccess.Repositories;
 6using FAU.Entidades.Auditoria;
 7using FAU.Logica.Services;
 8using Microsoft.AspNetCore.Authentication.JwtBearer;
 9using Microsoft.AspNetCore.Authorization;
 10using Microsoft.EntityFrameworkCore;
 11using Microsoft.IdentityModel.Tokens;
 12using Microsoft.OpenApi.Models;
 13using Microsoft.AspNetCore.HttpOverrides;
 14
 15// Npgsql 7+ requiere Kind=UTC para timestamptz; habilitar comportamiento legacy para columnas timestamp sin zona
 016AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
 17
 018var builder = WebApplication.CreateBuilder(args);
 19
 20// Log del ambiente y configuración cargada
 021var environment = builder.Environment.EnvironmentName;
 022var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
 23
 024Console.WriteLine("=====================================");
 025Console.WriteLine($"Ambiente: {environment}");
 026Console.WriteLine("=====================================");
 27
 028builder.Services.AddDbContext<ApplicationDbContext>(options =>
 029    options.UseNpgsql(connectionString));
 30
 031Auditoria.IniciarAuditoria(builder.Configuration);
 32
 33// Configuración de JWT
 034var jwtKey = builder.Configuration["Jwt:Key"] ?? throw new InvalidOperationException("JWT Key no configurada");
 035var jwtIssuer = builder.Configuration["Jwt:Issuer"];
 036var jwtAudience = builder.Configuration["Jwt:Audience"];
 37
 038builder.Services.AddAuthentication(options =>
 039{
 040    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
 041    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
 042})
 043.AddJwtBearer(options =>
 044{
 045    options.RequireHttpsMetadata = false; // En producción debe ser true
 046    options.SaveToken = true;
 047    options.TokenValidationParameters = new TokenValidationParameters
 048    {
 049        ValidateIssuerSigningKey = true,
 050        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey)),
 051        ValidateIssuer = true,
 052        ValidIssuer = jwtIssuer,
 053        ValidateAudience = true,
 054        ValidAudience = jwtAudience,
 055        ValidateLifetime = true,
 056        ClockSkew = TimeSpan.Zero
 057    };
 058});
 59
 060builder.Services.AddAuthorization();
 61
 62// Políticas dinámicas: Permission:xxx
 063builder.Services.AddSingleton<IAuthorizationPolicyProvider, PermissionPolicyProvider>();
 064builder.Services.AddSingleton<IAuthorizationHandler, PermissionAuthorizationHandler>();
 65
 66// HttpContext + Current user context (auditoría)
 067builder.Services.AddHttpContextAccessor();
 068builder.Services.AddScoped<FAU.Logica.Services.ICurrentUserContext, FAU.API.Services.CurrentUserContext>();
 69
 70// Registro de repositorios
 071builder.Services.AddScoped<IUsuarioRepository, UsuarioRepository>();
 072builder.Services.AddScoped<IRolRepository, RolRepository>();
 073builder.Services.AddScoped<IPermisoRepository, PermisoRepository>();
 074builder.Services.AddScoped<IAuditoriaRepository, AuditoriaRepository>();
 075builder.Services.AddScoped<IBancoRepository, BancoRepository>();
 076builder.Services.AddScoped<IPersonalRepository, PersonalRepository>();
 077builder.Services.AddScoped<ITipoBeneficioRepository, TipoBeneficioRepository>();
 078builder.Services.AddScoped<IBeneficioSocialRepository, BeneficioSocialRepository>();
 079builder.Services.AddScoped<IIrpfRepository, IrpfRepository>();
 080builder.Services.AddScoped<IDependienteRepository, DependienteRepository>();
 081builder.Services.AddScoped<ICompensacionRepository, CompensacionRepository>();
 082builder.Services.AddScoped<IParametroLiquidacionRepository, ParametroLiquidacionRepository>();
 083builder.Services.AddScoped<IPeriodosRepository, PeriodosRepository>();
 084builder.Services.AddScoped<INovedadPeriodoRepository, NovedadPeriodoRepository>();
 085builder.Services.AddScoped<ISnapshotsRepository, SnapshotsRepository>();
 86
 87// Registro de servicios
 088builder.Services.AddScoped<IAuthService, AuthService>();
 089builder.Services.AddScoped<IUsuarioService, UsuarioService>();
 090builder.Services.AddScoped<IRolService, RolService>();
 091builder.Services.AddScoped<IAuditoriaCatalogoResolver, AuditoriaCatalogoResolver>();
 092builder.Services.AddScoped<IAuditoriaService, AuditoriaService>();
 093builder.Services.AddScoped<IBancoService, BancoService>();
 094builder.Services.AddScoped<IPersonalService, PersonalService>();
 095builder.Services.AddScoped<ITipoBeneficioService, TipoBeneficioService>();
 096builder.Services.AddScoped<IBeneficioSocialService, BeneficioSocialService>();
 097builder.Services.AddScoped<IDependienteService, DependienteService>();
 098builder.Services.AddScoped<ICompensacionService, CompensacionService>();
 099builder.Services.AddScoped<IParametroLiquidacionService, ParametroLiquidacionService>();
 0100builder.Services.AddScoped<IPeriodoService, PeriodoService>();
 0101builder.Services.AddScoped<INovedadPeriodoService, NovedadPeriodoService>();
 0102builder.Services.AddScoped<IPeriodoGuard, PeriodoGuard>();
 0103builder.Services.AddScoped<ILiquidacionService, LiquidacionService>();
 104
 105// Add services to the container.
 0106builder.Services.AddControllers();
 107
 108// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
 0109builder.Services.AddEndpointsApiExplorer();
 0110builder.Services.AddHealthChecks();
 0111builder.Services.AddSwaggerGen(c =>
 0112{
 0113    c.SwaggerDoc("v1", new OpenApiInfo
 0114    {
 0115        Title = "FAU Liquidación API",
 0116        Version = "v1",
 0117        Description = "API para el sistema de liquidación de la FAU"
 0118    });
 0119
 0120    // Configurar Swagger para usar JWT
 0121    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
 0122    {
 0123        Description = "JWT Authorization header usando el esquema Bearer. Ejemplo: \"Bearer {token}\"",
 0124        Name = "Authorization",
 0125        In = ParameterLocation.Header,
 0126        Type = SecuritySchemeType.ApiKey,
 0127        Scheme = "Bearer"
 0128    });
 0129
 0130    c.AddSecurityRequirement(new OpenApiSecurityRequirement
 0131    {
 0132        {
 0133            new OpenApiSecurityScheme
 0134            {
 0135                Reference = new OpenApiReference
 0136                {
 0137                    Type = ReferenceType.SecurityScheme,
 0138                    Id = "Bearer"
 0139                }
 0140            },
 0141            Array.Empty<string>()
 0142        }
 0143    });
 0144});
 145
 146// Configuración de CORS (opcional, para desarrollo)
 0147builder.Services.AddCors(options =>
 0148{
 0149    options.AddPolicy("AllowAll", policy =>
 0150    {
 0151        policy.AllowAnyOrigin()
 0152              .AllowAnyMethod()
 0153              .AllowAnyHeader();
 0154    });
 0155});
 156
 0157var app = builder.Build();
 158
 159// Forwarded headers (si está detrás de proxy / ingress)
 0160app.UseForwardedHeaders(new ForwardedHeadersOptions
 0161{
 0162    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
 0163});
 164
 165// Comando de seeding: dotnet run --seed-admin
 166// Crea el primer usuario Administrador y termina sin levantar el servidor HTTP.
 0167if (args.Contains("--seed-admin"))
 168{
 0169    using var scope = app.Services.CreateScope();
 0170    var exitCode = await SuperAdminSeeder.RunAsync(args, scope.ServiceProvider);
 0171    Environment.Exit(exitCode);
 0172    return;
 173}
 174
 175// Validar conexión a la base de datos al inicio
 0176using (var scope = app.Services.CreateScope())
 177{
 0178    var services = scope.ServiceProvider;
 179    try
 180    {
 0181        var context = services.GetRequiredService<ApplicationDbContext>();
 0182        var canConnect = context.Database.CanConnect();
 183
 0184        if (!canConnect)
 185        {
 0186            app.Logger.LogError("No se pudo conectar a la base de datos");
 0187            throw new Exception("No se pudo establecer conexión con la base de datos");
 188        }
 0189    }
 0190    catch (Exception ex)
 191    {
 0192        app.Logger.LogError(ex, "Error al validar la conexión a la base de datos: {Message}", ex.Message);
 0193        throw;
 194    }
 0195}
 196
 197// Configure the HTTP request pipeline.
 198// Habilitar Swagger en todos los ambientes (útil para Docker)
 0199app.UseSwagger();
 0200app.UseSwaggerUI(c =>
 0201{
 0202    c.SwaggerEndpoint("/swagger/v1/swagger.json", "FAU Liquidación API v1");
 0203});
 204
 0205app.UseHttpsRedirection();
 206
 0207app.UseCors("AllowAll");
 208
 0209app.UseAuthentication(); // IMPORTANTE: debe ir antes de UseAuthorization
 0210app.UseAuthorization();
 211
 212
 0213app.MapHealthChecks("/health");
 0214app.MapControllers();
 215
 0216app.Run();

Methods/Properties

<Main>$()