fix(ui): AuditLogQueryService uses scope-per-query to avoid DbContext race (#23 M7)

This commit is contained in:
Joseph Doherty
2026-05-20 21:33:38 -04:00
parent 9c955da2e7
commit fac31c6018
5 changed files with 190 additions and 16 deletions

View File

@@ -4,6 +4,7 @@ using ScadaLink.CentralUI.Auth;
using ScadaLink.CentralUI.Components.Shared;
using ScadaLink.CentralUI.ScriptAnalysis;
using ScadaLink.CentralUI.Services;
using ScadaLink.HealthMonitoring;
namespace ScadaLink.CentralUI;
@@ -30,7 +31,16 @@ public static class ServiceCollectionExtensions
// Audit Log (#23 M7-T3): CentralUI facade over IAuditLogRepository so the
// results grid can be tested with a stubbed query source.
services.AddScoped<IAuditLogQueryService, AuditLogQueryService>();
//
// Registered with an explicit factory so the IServiceScopeFactory ctor is
// always chosen — AuditLogQueryService has a second (test-seam) ctor that
// takes IAuditLogRepository directly, and both are constructor-resolvable,
// so default activation would be ambiguous. The scope-factory ctor opens a
// fresh DbContext per query, which is what keeps the page's auto-load from
// racing AuditFilterBar's site enumeration on the shared scoped context.
services.AddScoped<IAuditLogQueryService>(sp => new AuditLogQueryService(
sp.GetRequiredService<IServiceScopeFactory>(),
sp.GetRequiredService<ICentralHealthAggregator>()));
// Audit Log (#23 M7-T14 / Bundle F): server-side streaming CSV export.
// Backs the Audit Log page's Export button via GET /api/centralui/audit/export.