using FrameworkDAL.DTO.EIPConversation; using FrameworkDAL.Query.EIPConversation.EIPInteractionSession; using GB5Shared.DTO.Framework.Login; using GB5Shared.GenerateAutoNumber; using GB5Shared.QueryExecutor; using Microsoft.Extensions.Logging; using System; using System.Threading; using System.Threading.Tasks; using static GB5Shared.GB5Constant.Constant; namespace FrameworkDAL.CustomCode.EIPConversation.EIPInteractionSession { public class EIPInteractionSessionDAL : IEIPInteractionSessionDAL { private readonly IQueryExecutor _qe; private readonly AutoNumber _autoNumber; private readonly ILogger _logger; public EIPInteractionSessionDAL(IQueryExecutor qe, AutoNumber autoNumber, ILogger logger) { _qe = qe ?? throw new ArgumentNullException(nameof(qe)); _autoNumber = autoNumber ?? throw new ArgumentNullException(nameof(autoNumber)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public async Task GetOrCreateAsync( string actorId, int tenantId, byte channelType, string flowCode, string? currentStep, LoginDTO loginDTO, CancellationToken ct = default) { try { var existing = await _qe.QuerySingleAsync( loginDTO, EIPInteractionSessionQB.GET_OPEN_BY_ACTOR, new { ActorId = actorId, TenantId = tenantId, ChannelType = channelType }, cancellationToken: ct).ConfigureAwait(false); if (existing is not null) return existing.InteractionSessionId; var auto = await _autoNumber.GetNumberAsync(1, AUTONUMBERCONSTANT.EIPINTERACTIONSESSION, loginDTO) .ConfigureAwait(false); await _qe.ExecuteAsync( loginDTO, EIPInteractionSessionQB.INSERT, new { InteractionSessionId = auto.StartNumber, TenantId = tenantId, SessionToken = Guid.NewGuid().ToString(), FlowCode = flowCode, CurrentStep = currentStep, ChannelType = channelType, ActorId = actorId, CreatedById = loginDTO.UserId, ModifiedById = loginDTO.UserId }, cancellationToken: ct).ConfigureAwait(false); return auto.StartNumber; } catch (Exception ex) { _logger.LogError(ex, "Failed to get-or-create interaction session | Actor={Actor} | Flow={Flow}", actorId, flowCode); throw; } } public async Task MarkStatusAsync( int interactionSessionId, byte sessionStatus, string? currentStep, bool completed, LoginDTO loginDTO, CancellationToken ct = default) { try { await _qe.ExecuteAsync( loginDTO, EIPInteractionSessionQB.UPDATE_STATUS, new { InteractionSessionId = interactionSessionId, SessionStatus = sessionStatus, CurrentStep = currentStep, CompletedOn = completed ? (DateTime?)DateTime.UtcNow : null, ModifiedById = loginDTO.UserId }, cancellationToken: ct).ConfigureAwait(false); } catch (Exception ex) { _logger.LogError(ex, "Failed to update interaction session status | InteractionSessionId={Id}", interactionSessionId); throw; } } } }