using KArtSell.Modules.ModelOperations.ShadowRun.Events;
using Microsoft.Extensions.Logging;
namespace KArtSell.Host.Consumers;
///
/// Creates approval queue entries when shadow run passes all validation gates.
/// Idempotent: INSERT ... ON CONFLICT DO NOTHING ensures no duplicates.
/// Triggers: Approval workflow notification to model owner/manager.
///
public sealed class ApprovalQueueConsumer : IInboxConsumer
{
private readonly ILogger _logger;
public ApprovalQueueConsumer(ILogger logger)
{
_logger = logger;
}
public async Task HandleAsync(ShadowRunCompletedEvent message, CancellationToken cancellationToken = default)
{
try
{
// Only create approval queue if all gates passed
if (!message.AllGatesPassed)
{
_logger.LogInformation(
"Shadow run {RunId} failed gates; skipping approval queue",
message.RunId);
return;
}
_logger.LogInformation(
"Creating approval queue entry for shadow run {RunId}, model {ModelId}",
message.RunId, message.ModelId);
// TODO: Implement database insert to approval_queue table
// INSERT INTO approval_queue (run_id, model_id, status, requested_at)
// VALUES (@runId, @modelId, 'Pending', @now)
// ON CONFLICT (run_id) DO NOTHING; -- Idempotent
// Simulated: In production, this would call a repository or query service
await Task.Delay(10, cancellationToken); // Simulate DB work
_logger.LogInformation(
"Approval queue entry created for {RunId}",
message.RunId);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to create approval queue entry for {RunId}", message.RunId);
throw; // Let Hangfire classify
}
}
}