@@ -6,11 +6,15 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using ROLAC.API.Data;
|
||||
using ROLAC.API.Data.Interceptors;
|
||||
using ROLAC.API.Data.Logging;
|
||||
using ROLAC.API.Entities;
|
||||
using ROLAC.API.Json;
|
||||
using ROLAC.API.Middleware;
|
||||
using ROLAC.API.Services;
|
||||
using ROLAC.API.Services.Logging;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
var config = builder.Configuration;
|
||||
@@ -19,10 +23,31 @@ var config = builder.Configuration;
|
||||
// Database
|
||||
// ---------------------------------------------------------------------------
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
builder.Services.AddScoped<CurrentUserAccessor>();
|
||||
builder.Services.AddScoped<AuditSaveChangesInterceptor>();
|
||||
builder.Services.AddScoped<AuditLogInterceptor>();
|
||||
builder.Services.AddDbContext<AppDbContext>((sp, opt) =>
|
||||
opt.UseNpgsql(config.GetConnectionString("DefaultConnection"))
|
||||
.AddInterceptors(sp.GetRequiredService<AuditSaveChangesInterceptor>()));
|
||||
.AddInterceptors(
|
||||
sp.GetRequiredService<AuditSaveChangesInterceptor>(),
|
||||
sp.GetRequiredService<AuditLogInterceptor>()));
|
||||
|
||||
// Dedicated context for log writes — NO interceptors and a silent logger factory, so persisting
|
||||
// a log row produces no log events the DB sink would pick up (breaks recursion / log-storms).
|
||||
builder.Services.AddDbContext<LogDbContext>(opt =>
|
||||
opt.UseNpgsql(config.GetConnectionString("DefaultConnection"))
|
||||
.UseLoggerFactory(NullLoggerFactory.Instance));
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// System + audit logging (custom EF DB sink)
|
||||
// ---------------------------------------------------------------------------
|
||||
builder.Services.Configure<DatabaseLoggerOptions>(config.GetSection("Logging:Database"));
|
||||
builder.Services.AddSingleton<SystemLogQueue>();
|
||||
builder.Services.AddSingleton<ILoggerProvider, DbLoggerProvider>();
|
||||
builder.Services.AddHostedService<LogWriterBackgroundService>();
|
||||
builder.Services.AddScoped<IAuditLogger, AuditLogger>();
|
||||
builder.Services.AddScoped<ISystemLogQueryService, SystemLogQueryService>();
|
||||
builder.Services.AddScoped<IAuditLogQueryService, AuditLogQueryService>();
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Identity (API-only — no cookie auth; JWT is the default scheme)
|
||||
@@ -200,6 +225,10 @@ app.UseForwardedHeaders(new ForwardedHeadersOptions
|
||||
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
|
||||
});
|
||||
|
||||
// First in the pipeline: catch every unhandled exception, log it to SystemLogs, and return
|
||||
// a clean problem+json. Placed after UseForwardedHeaders so the logged client IP is correct.
|
||||
app.UseMiddleware<ExceptionHandlingMiddleware>();
|
||||
|
||||
// Apply migrations + seed on startup
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user