Some checks failed
		
		
	
	Optimized Build and Deploy / remote-build-and-deploy (push) Failing after 4m10s
				
			
		
			
				
	
	
		
			248 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			248 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 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;
 | |
| 
 | |
| var builder = WebApplication.CreateBuilder(args);
 | |
| 
 | |
| // --- Registros de Servicios ---
 | |
| builder.Services.AddSingleton<DbConnectionFactory>();
 | |
| builder.Services.AddScoped<PasswordHasherService>();
 | |
| builder.Services.AddScoped<IAuthRepository, AuthRepository>();
 | |
| builder.Services.AddScoped<IAuthService, AuthService>();
 | |
| builder.Services.AddScoped<ITipoPagoRepository, TipoPagoRepository>();
 | |
| builder.Services.AddScoped<ITipoPagoService, TipoPagoService>();
 | |
| builder.Services.AddScoped<IZonaRepository, ZonaRepository>();
 | |
| builder.Services.AddScoped<IZonaService, ZonaService>();
 | |
| builder.Services.AddScoped<IEmpresaRepository, EmpresaRepository>();
 | |
| builder.Services.AddScoped<IEmpresaService, EmpresaService>();
 | |
| builder.Services.AddScoped<ISaldoRepository, SaldoRepository>();
 | |
| builder.Services.AddScoped<IPlantaRepository, PlantaRepository>();
 | |
| builder.Services.AddScoped<IPlantaService, PlantaService>();
 | |
| builder.Services.AddScoped<ITipoBobinaRepository, TipoBobinaRepository>();
 | |
| builder.Services.AddScoped<ITipoBobinaService, TipoBobinaService>();
 | |
| builder.Services.AddScoped<IEstadoBobinaRepository, EstadoBobinaRepository>();
 | |
| builder.Services.AddScoped<IEstadoBobinaService, EstadoBobinaService>();
 | |
| builder.Services.AddScoped<IOtroDestinoRepository, OtroDestinoRepository>();
 | |
| builder.Services.AddScoped<IOtroDestinoService, OtroDestinoService>();
 | |
| builder.Services.AddScoped<IPerfilRepository, PerfilRepository>();
 | |
| builder.Services.AddScoped<IPerfilService, PerfilService>();
 | |
| builder.Services.AddScoped<IPermisoRepository, PermisoRepository>();
 | |
| builder.Services.AddScoped<IPermisoService, PermisoService>();
 | |
| builder.Services.AddScoped<IUsuarioRepository, UsuarioRepository>();
 | |
| builder.Services.AddScoped<IUsuarioService, UsuarioService>();
 | |
| builder.Services.AddScoped<ICanillaRepository, CanillaRepository>();
 | |
| builder.Services.AddScoped<ICanillaService, CanillaService>();
 | |
| builder.Services.AddScoped<IDistribuidorRepository, DistribuidorRepository>();
 | |
| builder.Services.AddScoped<IDistribuidorService, DistribuidorService>();
 | |
| builder.Services.AddScoped<IPublicacionRepository, PublicacionRepository>();
 | |
| builder.Services.AddScoped<IPublicacionService, PublicacionService>();
 | |
| builder.Services.AddScoped<IRecargoZonaRepository, RecargoZonaRepository>();
 | |
| builder.Services.AddScoped<IRecargoZonaService, RecargoZonaService>();
 | |
| builder.Services.AddScoped<IPorcPagoRepository, PorcPagoRepository>();
 | |
| builder.Services.AddScoped<IPorcPagoService, PorcPagoService>();
 | |
| builder.Services.AddScoped<IPorcMonCanillaRepository, PorcMonCanillaRepository>();
 | |
| builder.Services.AddScoped<IPorcMonCanillaService, PorcMonCanillaService>();
 | |
| builder.Services.AddScoped<IPubliSeccionRepository, PubliSeccionRepository>();
 | |
| builder.Services.AddScoped<IPubliSeccionService, PubliSeccionService>();
 | |
| builder.Services.AddScoped<IPrecioRepository, PrecioRepository>();
 | |
| builder.Services.AddScoped<IPrecioService, PrecioService>();
 | |
| builder.Services.AddScoped<IStockBobinaRepository, StockBobinaRepository>();
 | |
| builder.Services.AddScoped<IStockBobinaService, StockBobinaService>();
 | |
| builder.Services.AddScoped<IRegTiradaRepository, RegTiradaRepository>();
 | |
| builder.Services.AddScoped<IRegPublicacionSeccionRepository, RegPublicacionSeccionRepository>();
 | |
| builder.Services.AddScoped<ITiradaService, TiradaService>();
 | |
| builder.Services.AddScoped<ISalidaOtroDestinoRepository, SalidaOtroDestinoRepository>();
 | |
| builder.Services.AddScoped<ISalidaOtroDestinoService, SalidaOtroDestinoService>();
 | |
| builder.Services.AddScoped<IEntradaSalidaDistRepository, EntradaSalidaDistRepository>();
 | |
| builder.Services.AddScoped<IEntradaSalidaDistService, EntradaSalidaDistService>();
 | |
| builder.Services.AddScoped<IEntradaSalidaCanillaRepository, EntradaSalidaCanillaRepository>();
 | |
| builder.Services.AddScoped<IEntradaSalidaCanillaService, EntradaSalidaCanillaService>();
 | |
| builder.Services.AddScoped<IControlDevolucionesRepository, ControlDevolucionesRepository>();
 | |
| builder.Services.AddScoped<IControlDevolucionesService, ControlDevolucionesService>();
 | |
| builder.Services.AddScoped<IPagoDistribuidorRepository, PagoDistribuidorRepository>();
 | |
| builder.Services.AddScoped<IPagoDistribuidorService, PagoDistribuidorService>();
 | |
| builder.Services.AddScoped<INotaCreditoDebitoRepository, NotaCreditoDebitoRepository>();
 | |
| builder.Services.AddScoped<INotaCreditoDebitoService, NotaCreditoDebitoService>();
 | |
| builder.Services.AddScoped<IRitmoRepository, RitmoRepository>();
 | |
| builder.Services.AddScoped<IRitmoService, RitmoService>();
 | |
| builder.Services.AddScoped<ICancionRepository, CancionRepository>();
 | |
| builder.Services.AddScoped<ICancionService, CancionService>();
 | |
| builder.Services.AddScoped<IRadioListaService, RadioListaService>();
 | |
| builder.Services.AddScoped<INovedadCanillaRepository, NovedadCanillaRepository>();
 | |
| builder.Services.AddScoped<INovedadCanillaService, NovedadCanillaService>();
 | |
| builder.Services.AddScoped<ICambioParadaRepository, CambioParadaRepository>();
 | |
| builder.Services.AddScoped<ICambioParadaService, CambioParadaService>();
 | |
| // Servicio de Saldos
 | |
| builder.Services.AddScoped<ISaldoService, SaldoService>();
 | |
| // Repositorios de Reportes
 | |
| builder.Services.AddScoped<IReportesRepository, ReportesRepository>();
 | |
| // Servicios de Reportes
 | |
| builder.Services.AddScoped<IReportesService, ReportesService>();
 | |
| // QuestPDF
 | |
| builder.Services.AddScoped<IQuestPdfGenerator, QuestPdfGenerator>();
 | |
| 
 | |
| // --- 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<string>() // 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(); |