< Summary

Information
Line coverage
0%
Covered lines: 0
Uncovered lines: 146
Coverable lines: 146
Total lines: 210
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
 015var builder = WebApplication.CreateBuilder(args);
 16
 17// Log del ambiente y configuración cargada
 018var environment = builder.Environment.EnvironmentName;
 019var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
 20
 021Console.WriteLine("=====================================");
 022Console.WriteLine($"Ambiente: {environment}");
 023Console.WriteLine("=====================================");
 24
 025builder.Services.AddDbContext<ApplicationDbContext>(options =>
 026    options.UseNpgsql(connectionString));
 27
 028Auditoria.IniciarAuditoria(builder.Configuration);
 29
 30// Configuración de JWT
 031var jwtKey = builder.Configuration["Jwt:Key"] ?? throw new InvalidOperationException("JWT Key no configurada");
 032var jwtIssuer = builder.Configuration["Jwt:Issuer"];
 033var jwtAudience = builder.Configuration["Jwt:Audience"];
 34
 035builder.Services.AddAuthentication(options =>
 036{
 037    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
 038    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
 039})
 040.AddJwtBearer(options =>
 041{
 042    options.RequireHttpsMetadata = false; // En producción debe ser true
 043    options.SaveToken = true;
 044    options.TokenValidationParameters = new TokenValidationParameters
 045    {
 046        ValidateIssuerSigningKey = true,
 047        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey)),
 048        ValidateIssuer = true,
 049        ValidIssuer = jwtIssuer,
 050        ValidateAudience = true,
 051        ValidAudience = jwtAudience,
 052        ValidateLifetime = true,
 053        ClockSkew = TimeSpan.Zero
 054    };
 055});
 56
 057builder.Services.AddAuthorization();
 58
 59// Políticas dinámicas: Permission:xxx
 060builder.Services.AddSingleton<IAuthorizationPolicyProvider, PermissionPolicyProvider>();
 061builder.Services.AddSingleton<IAuthorizationHandler, PermissionAuthorizationHandler>();
 62
 63// HttpContext + Current user context (auditoría)
 064builder.Services.AddHttpContextAccessor();
 065builder.Services.AddScoped<FAU.Logica.Services.ICurrentUserContext, FAU.API.Services.CurrentUserContext>();
 66
 67// Registro de repositorios
 068builder.Services.AddScoped<IUsuarioRepository, UsuarioRepository>();
 069builder.Services.AddScoped<IRolRepository, RolRepository>();
 070builder.Services.AddScoped<IPermisoRepository, PermisoRepository>();
 071builder.Services.AddScoped<IAuditoriaRepository, AuditoriaRepository>();
 072builder.Services.AddScoped<IBancoRepository, BancoRepository>();
 073builder.Services.AddScoped<IPersonalRepository, PersonalRepository>();
 074builder.Services.AddScoped<ITipoBeneficioRepository, TipoBeneficioRepository>();
 075builder.Services.AddScoped<IBeneficioSocialRepository, BeneficioSocialRepository>();
 076builder.Services.AddScoped<IIrpfRepository, IrpfRepository>();
 077builder.Services.AddScoped<IDependienteRepository, DependienteRepository>();
 078builder.Services.AddScoped<ICompensacionRepository, CompensacionRepository>();
 079builder.Services.AddScoped<IParametroLiquidacionRepository, ParametroLiquidacionRepository>();
 080builder.Services.AddScoped<IPeriodosRepository, PeriodosRepository>();
 081builder.Services.AddScoped<ISnapshotsRepository, SnapshotsRepository>();
 82
 83// Registro de servicios
 084builder.Services.AddScoped<IAuthService, AuthService>();
 085builder.Services.AddScoped<IUsuarioService, UsuarioService>();
 086builder.Services.AddScoped<IRolService, RolService>();
 087builder.Services.AddScoped<IAuditoriaCatalogoResolver, AuditoriaCatalogoResolver>();
 088builder.Services.AddScoped<IAuditoriaService, AuditoriaService>();
 089builder.Services.AddScoped<IBancoService, BancoService>();
 090builder.Services.AddScoped<IPersonalService, PersonalService>();
 091builder.Services.AddScoped<ITipoBeneficioService, TipoBeneficioService>();
 092builder.Services.AddScoped<IBeneficioSocialService, BeneficioSocialService>();
 093builder.Services.AddScoped<IDependienteService, DependienteService>();
 094builder.Services.AddScoped<ICompensacionService, CompensacionService>();
 095builder.Services.AddScoped<IParametroLiquidacionService, ParametroLiquidacionService>();
 096builder.Services.AddScoped<IPeriodoService, PeriodoService>();
 097builder.Services.AddScoped<ILiquidacionService, LiquidacionService>();
 98
 99// Add services to the container.
 0100builder.Services.AddControllers();
 101
 102// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
 0103builder.Services.AddEndpointsApiExplorer();
 0104builder.Services.AddHealthChecks();
 0105builder.Services.AddSwaggerGen(c =>
 0106{
 0107    c.SwaggerDoc("v1", new OpenApiInfo
 0108    {
 0109        Title = "FAU Liquidación API",
 0110        Version = "v1",
 0111        Description = "API para el sistema de liquidación de la FAU"
 0112    });
 0113
 0114    // Configurar Swagger para usar JWT
 0115    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
 0116    {
 0117        Description = "JWT Authorization header usando el esquema Bearer. Ejemplo: \"Bearer {token}\"",
 0118        Name = "Authorization",
 0119        In = ParameterLocation.Header,
 0120        Type = SecuritySchemeType.ApiKey,
 0121        Scheme = "Bearer"
 0122    });
 0123
 0124    c.AddSecurityRequirement(new OpenApiSecurityRequirement
 0125    {
 0126        {
 0127            new OpenApiSecurityScheme
 0128            {
 0129                Reference = new OpenApiReference
 0130                {
 0131                    Type = ReferenceType.SecurityScheme,
 0132                    Id = "Bearer"
 0133                }
 0134            },
 0135            Array.Empty<string>()
 0136        }
 0137    });
 0138});
 139
 140// Configuración de CORS (opcional, para desarrollo)
 0141builder.Services.AddCors(options =>
 0142{
 0143    options.AddPolicy("AllowAll", policy =>
 0144    {
 0145        policy.AllowAnyOrigin()
 0146              .AllowAnyMethod()
 0147              .AllowAnyHeader();
 0148    });
 0149});
 150
 0151var app = builder.Build();
 152
 153// Forwarded headers (si está detrás de proxy / ingress)
 0154app.UseForwardedHeaders(new ForwardedHeadersOptions
 0155{
 0156    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
 0157});
 158
 159// Comando de seeding: dotnet run --seed-admin
 160// Crea el primer usuario Administrador y termina sin levantar el servidor HTTP.
 0161if (args.Contains("--seed-admin"))
 162{
 0163    using var scope = app.Services.CreateScope();
 0164    var exitCode = await SuperAdminSeeder.RunAsync(args, scope.ServiceProvider);
 0165    Environment.Exit(exitCode);
 0166    return;
 167}
 168
 169// Validar conexión a la base de datos al inicio
 0170using (var scope = app.Services.CreateScope())
 171{
 0172    var services = scope.ServiceProvider;
 173    try
 174    {
 0175        var context = services.GetRequiredService<ApplicationDbContext>();
 0176        var canConnect = context.Database.CanConnect();
 177
 0178        if (!canConnect)
 179        {
 0180            app.Logger.LogError("No se pudo conectar a la base de datos");
 0181            throw new Exception("No se pudo establecer conexión con la base de datos");
 182        }
 0183    }
 0184    catch (Exception ex)
 185    {
 0186        app.Logger.LogError(ex, "Error al validar la conexión a la base de datos: {Message}", ex.Message);
 0187        throw;
 188    }
 0189}
 190
 191// Configure the HTTP request pipeline.
 192// Habilitar Swagger en todos los ambientes (útil para Docker)
 0193app.UseSwagger();
 0194app.UseSwaggerUI(c =>
 0195{
 0196    c.SwaggerEndpoint("/swagger/v1/swagger.json", "FAU Liquidación API v1");
 0197});
 198
 0199app.UseHttpsRedirection();
 200
 0201app.UseCors("AllowAll");
 202
 0203app.UseAuthentication(); // IMPORTANTE: debe ir antes de UseAuthorization
 0204app.UseAuthorization();
 205
 206
 0207app.MapHealthChecks("/health");
 0208app.MapControllers();
 209
 0210app.Run();

Methods/Properties

<Main>$()