mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-07-16 17:47:22 +00:00
Moves brewery CRUD from the Service.Breweries/Infrastructure.Repository layered split into a single Features.Breweries project: MediatR commands/queries replace BreweryService, and the repository moves in alongside its own controller. Extracts Infrastructure.Sql out of Infrastructure.Repository (just the generic ADO.NET connection/base-repo plumbing) since Breweries no longer needs the rest of that project, while Auth and UserAccount repos still do until their own migration. Also fixes the API.Core and Infrastructure.Repository.Tests Dockerfiles, which were restoring against COPY destinations that didn't match the projects' actual relative paths (silently working only because of the COPY . . that followed); both now restore against Core.slnx with correctly nested paths, verified with a real docker build.
118 lines
3.7 KiB
C#
118 lines
3.7 KiB
C#
using API.Core;
|
|
using API.Core.Authentication;
|
|
using Features.Breweries.Controllers;
|
|
using Features.Breweries.DependencyInjection;
|
|
using FluentValidation;
|
|
using FluentValidation.AspNetCore;
|
|
using Infrastructure.Email;
|
|
using Infrastructure.Email.Templates.Rendering;
|
|
using Infrastructure.Jwt;
|
|
using Infrastructure.PasswordHashing;
|
|
using Infrastructure.Repository.Auth;
|
|
using Infrastructure.Repository.UserAccount;
|
|
using Infrastructure.Sql;
|
|
using Service.Auth;
|
|
using Service.Emails;
|
|
using Service.UserManagement.User;
|
|
using Shared.Application.Behaviors;
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
// Global Exception Filter
|
|
builder.Services.AddControllers(options =>
|
|
{
|
|
options.Filters.Add<GlobalExceptionFilter>();
|
|
})
|
|
.AddApplicationPart(typeof(BreweryController).Assembly);
|
|
|
|
builder.Services.AddEndpointsApiExplorer();
|
|
builder.Services.AddSwaggerGen();
|
|
builder.Services.AddOpenApi();
|
|
|
|
// Add FluentValidation
|
|
builder.Services.AddValidatorsFromAssemblyContaining<Program>();
|
|
builder.Services.AddValidatorsFromAssembly(typeof(BreweryController).Assembly);
|
|
builder.Services.AddFluentValidationAutoValidation();
|
|
|
|
// Add MediatR. Each Features.* slice's assembly is registered here as it's introduced;
|
|
// ValidationBehavior runs FluentValidation validators in the MediatR pipeline for command/query handlers.
|
|
builder.Services.AddMediatR(cfg =>
|
|
{
|
|
cfg.RegisterServicesFromAssemblyContaining<Program>();
|
|
cfg.RegisterServicesFromAssembly(typeof(BreweryController).Assembly);
|
|
cfg.AddOpenBehavior(typeof(ValidationBehavior<,>));
|
|
});
|
|
|
|
// Add health checks
|
|
builder.Services.AddHealthChecks();
|
|
|
|
// Configure logging for container output
|
|
builder.Logging.ClearProviders();
|
|
builder.Logging.AddConsole();
|
|
if (!builder.Environment.IsProduction())
|
|
{
|
|
builder.Logging.AddDebug();
|
|
}
|
|
|
|
// Configure Dependency Injection -------------------------------------------------------------------------------------
|
|
|
|
builder.Services.AddSingleton<
|
|
ISqlConnectionFactory,
|
|
DefaultSqlConnectionFactory
|
|
>();
|
|
|
|
builder.Services.AddScoped<IUserAccountRepository, UserAccountRepository>();
|
|
builder.Services.AddScoped<IAuthRepository, AuthRepository>();
|
|
builder.Services.AddFeaturesBreweries();
|
|
|
|
builder.Services.AddScoped<IUserService, UserService>();
|
|
builder.Services.AddScoped<ILoginService, LoginService>();
|
|
builder.Services.AddScoped<IRegisterService, RegisterService>();
|
|
builder.Services.AddScoped<ITokenService, TokenService>();
|
|
|
|
builder.Services.AddScoped<ITokenInfrastructure, JwtInfrastructure>();
|
|
builder.Services.AddScoped<IPasswordInfrastructure, Argon2Infrastructure>();
|
|
builder.Services.AddScoped<IEmailProvider, SmtpEmailProvider>();
|
|
builder.Services.AddScoped<IEmailTemplateProvider, EmailTemplateProvider>();
|
|
builder.Services.AddScoped<IEmailService, EmailService>();
|
|
builder.Services.AddScoped<IConfirmationService, ConfirmationService>();
|
|
|
|
// Register the exception filter
|
|
builder.Services.AddScoped<GlobalExceptionFilter>();
|
|
|
|
// Configure JWT Authentication
|
|
builder
|
|
.Services.AddAuthentication("JWT")
|
|
.AddScheme<JwtAuthenticationOptions, JwtAuthenticationHandler>(
|
|
"JWT",
|
|
options => { }
|
|
);
|
|
|
|
builder.Services.AddAuthorization();
|
|
|
|
var app = builder.Build();
|
|
|
|
app.UseSwagger();
|
|
app.UseSwaggerUI();
|
|
app.MapOpenApi();
|
|
|
|
app.UseHttpsRedirection();
|
|
|
|
app.UseAuthentication();
|
|
app.UseAuthorization();
|
|
|
|
// Health check endpoint (used by Docker health checks and orchestrators)
|
|
app.MapHealthChecks("/health");
|
|
|
|
app.MapControllers();
|
|
app.MapFallbackToController("Handle404", "NotFound");
|
|
|
|
// Graceful shutdown handling
|
|
var lifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
|
|
lifetime.ApplicationStopping.Register(() =>
|
|
{
|
|
app.Logger.LogInformation("Application is shutting down gracefully...");
|
|
});
|
|
|
|
app.Run();
|