feat(ai): centralize durable usage
Add a content-free usage ledger with legacy backfill. Reserve Workspace and durable Strategy/CV work before execution so deleted history or duplicate admission cannot reset limits.
This commit is contained in:
@@ -51,6 +51,9 @@ public sealed class CvProcessingOperationTests
|
||||
Assert.Equal(CvProcessingQueue.TaskType, operation.TaskType);
|
||||
Assert.Equal(CvProcessingQueue.SubjectType, operation.SubjectType);
|
||||
Assert.DoesNotContain("Ada", operation.SubjectId ?? string.Empty, StringComparison.OrdinalIgnoreCase);
|
||||
var usage = Assert.Single(await db.AiUsageRecords.IgnoreQueryFilters().ToListAsync());
|
||||
Assert.Equal(operation.Id.ToString("D"), usage.SourceId);
|
||||
Assert.Equal(AiUsageMeter.ReservationFor(CvProcessingQueue.TaskType).EstimatedTokens, usage.EstimatedTokenCount);
|
||||
}
|
||||
|
||||
Assert.True(await fixture.Provider.GetRequiredService<AiOperationWorker>().RunOnceAsync(default));
|
||||
@@ -68,6 +71,8 @@ public sealed class CvProcessingOperationTests
|
||||
Assert.Null(user.ProfileCvStructureJson);
|
||||
Assert.Null(user.CurrentCvExtractionRunId);
|
||||
Assert.Equal("operation_succeeded", (await db.UserNotifications.IgnoreQueryFilters().SingleAsync()).Kind);
|
||||
Assert.Equal(AiUsageMeter.ReservationFor(CvProcessingQueue.TaskType).EstimatedTokens,
|
||||
(await db.AiUsageRecords.IgnoreQueryFilters().SingleAsync()).EstimatedTokenCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,6 +268,7 @@ public sealed class CvProcessingOperationTests
|
||||
services.AddSingleton<AiPrivacyPolicy>();
|
||||
services.AddSingleton<AiOperationExecutionScope>();
|
||||
services.AddScoped<UserOperationStore>();
|
||||
services.AddScoped<AiUsageMeter>();
|
||||
services.AddScoped<AiOperationAdmission>();
|
||||
services.AddScoped<ICvProcessingQueue, CvProcessingQueue>();
|
||||
services.AddTransient<ProfileCvController>();
|
||||
|
||||
Reference in New Issue
Block a user