using FastEndpoints; using FrameworkBLL.EIPConversation.EIPHandlers.EIPConversationBLL; using FrameworkDAL.DTO.EIPConversation; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Framework.ResponseStandard; using GB5Shared.FastEndPoint; using Microsoft.Extensions.Logging; using System.Diagnostics; using static GB5Shared.GB5Constant.Constant; namespace FrameworkSL.Endpoints.EIPConversation { /// /// PHASE 1 – Channel Reception Endpoint /// Entry point for external channels (WhatsApp, Web, Telegram, SMS). /// Performs minimal validation and forwards to BLL. /// public class ReceiveEIPConversation : BaseEndpoint> { private readonly IEIPConversationBLL _conversationService; private readonly ILogger _logger; public ReceiveEIPConversation( IEIPConversationBLL conversationService, ILogger logger) { _conversationService = conversationService; _logger = logger; } public override void Configure() { Post("/EIPConversation/Receive"); AllowAnonymous(); // Webhook entry } public record ReceiveEIPConversationParameters( [property: FromHeader] string Login, [property: FromBody] EIPConversationDTO Payload ); protected override async Task> ExecuteAsync( ReceiveEIPConversationParameters req, LoginDTO loginDTO, CancellationToken ct) { var correlationId = Guid.NewGuid().ToString("N"); var stopwatch = Stopwatch.StartNew(); try { if (req.Payload == null) throw new ArgumentNullException(nameof(req.Payload)); _logger.LogInformation( "EIP START | CorrelationId={CorrelationId} | Tenant={Tenant} | Channel={Channel} | User={User} | Message={Message}", correlationId, req.Payload.TenantId, req.Payload.ChannelType, req.Payload.UserIdentifier, req.Payload.Message); // Forward to BLL (Phase 2 onwards) var result = await _conversationService .HandleIncomingConversationAsync(req.Payload, loginDTO!, ct); stopwatch.Stop(); _logger.LogInformation( "PHASE1 COMPLETE | CorrelationId={CorrelationId} | DurationMs={Duration}", correlationId, stopwatch.ElapsedMilliseconds); _logger.LogInformation( "EIP END | CorrelationId={CorrelationId} | Tenant={Tenant} | FinalStep={Step}", correlationId, req.Payload.TenantId, result?.CurrentStepCode); return await GB5Shared.ResponseStandard.Response .CreateSuccessResponse(result, CacheKeyLevel.NOT_REQUIRED, loginDTO); } catch (Exception ex) { stopwatch.Stop(); _logger.LogError( ex, "PHASE1 ERROR | CorrelationId={CorrelationId} | Tenant={Tenant} | DurationMs={Duration}", correlationId, req?.Payload?.TenantId, stopwatch.ElapsedMilliseconds); return await GB5Shared.ResponseStandard.Response .CreateExceptionError( ex, CacheKeyLevel.NOT_REQUIRED, loginDTO, ex.Message, 500); } } } }