using Hangfire; using IncidentOps.Domain.Entities; using IncidentOps.Domain.Enums; using IncidentOps.Infrastructure.Data.Repositories; using IncidentOps.Infrastructure.Jobs; using Microsoft.Extensions.Logging; namespace IncidentOps.Worker.Jobs; public class EscalateIfUnackedJob : IEscalateIfUnackedJob { private readonly IIncidentEventRepository _incidentEventRepository; private readonly IBackgroundJobClient _backgroundJobClient; private readonly ILogger _logger; public EscalateIfUnackedJob( IIncidentEventRepository incidentEventRepository, IBackgroundJobClient backgroundJobClient, ILogger logger) { _incidentEventRepository = incidentEventRepository; _backgroundJobClient = backgroundJobClient; _logger = logger; } public async Task ExecuteAsync(Guid incidentId, int step) { _logger.LogInformation("Checking escalation for incident {IncidentId}, step {Step}", incidentId, step); using var connection = new Npgsql.NpgsqlConnection( Environment.GetEnvironmentVariable("ConnectionStrings__Postgres") ?? ""); var incident = await Dapper.SqlMapper.QuerySingleOrDefaultAsync( connection, "SELECT * FROM incidents WHERE id = @Id", new { Id = incidentId }); if (incident == null) { _logger.LogWarning("Incident {IncidentId} not found for escalation", incidentId); return; } if (incident.Status != IncidentStatus.Triggered) { _logger.LogInformation("Incident {IncidentId} is no longer in Triggered state, skipping escalation", incidentId); return; } // Record escalation event await _incidentEventRepository.CreateAsync(new IncidentEvent { Id = Guid.NewGuid(), IncidentId = incidentId, EventType = IncidentEventType.EscalationTriggered, Payload = $"{{\"step\": {step}}}", CreatedAt = DateTime.UtcNow }); _logger.LogInformation("Escalation triggered for incident {IncidentId}, step {Step}", incidentId, step); // TODO: Implement secondary notification targets or on-call escalation // For now, just log the escalation } }