Initial commit
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PowderCoating.Application.Interfaces;
|
||||
using PowderCoating.Core.Entities;
|
||||
using PowderCoating.Infrastructure.Data;
|
||||
|
||||
namespace PowderCoating.Infrastructure.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Writes one AiUsageLog row per Anthropic API call using a fresh DI scope so the insert
|
||||
/// is fully isolated from the caller's Unit-of-Work transaction. Registered as Singleton
|
||||
/// because IServiceScopeFactory is singleton-safe and we want zero allocation overhead on
|
||||
/// every AI request.
|
||||
/// </summary>
|
||||
public class AiUsageLogger : IAiUsageLogger
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
private readonly ILogger<AiUsageLogger> _logger;
|
||||
|
||||
public AiUsageLogger(IServiceScopeFactory scopeFactory, ILogger<AiUsageLogger> logger)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task LogAsync(int companyId, string userId, string feature, bool success = true, int inputLength = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
context.AiUsageLogs.Add(new AiUsageLog
|
||||
{
|
||||
CompanyId = companyId,
|
||||
UserId = userId,
|
||||
Feature = feature,
|
||||
Success = success,
|
||||
InputLength = inputLength,
|
||||
CalledAt = DateTime.UtcNow
|
||||
});
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "AI usage log write failed for company {CompanyId} feature {Feature} — non-fatal", companyId, feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user