using FastEndpoints; using FrameworkBLL.EIPConversation.EIPHandlers.EIPPlayground; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Framework.ResponseStandard; using GB5Shared.FastEndPoint; using static GB5Shared.GB5Constant.Constant; namespace FrameworkSL.Endpoints.EIPConversation { /// /// POST /EIPConversation/PlaygroundRun /// /// Executes one turn of an EIP conversation flow from raw JSON, /// without touching the DB session or channel infrastructure. /// /// Request body: { FlowJson, Message, SessionStateJson } /// Response: { ResponseMessage, CurrentStepCode, IsCompleted, PhaseTrace, SessionStateJson } /// /// The caller holds the session state between turns (client-side). /// Pass the SessionStateJson from each response back in the next request. /// public class EIPPlaygroundRunEndpoint : BaseEndpoint> { private readonly IEIPPlaygroundBLL _bll; private readonly ILogger _logger; public EIPPlaygroundRunEndpoint(IEIPPlaygroundBLL bll, ILogger logger) { _bll = bll; _logger = logger; } public override void Configure() { Post("/EIPConversation/PlaygroundRun"); AllowAnonymous(); Description(b => b.WithTags("EIPConversation")); } protected override string? GetCacheKey(Parameters req, LoginDTO login) => null; protected override async Task> ExecuteAsync( Parameters req, LoginDTO login, CancellationToken ct) { var body = req.Body ?? new PlaygroundRunRequest(); _logger.LogInformation( "PlaygroundRun | User={UserId} | StepCode={Step} | HasSession={HasSession}", login.UserId, body.Message?.Length > 0 ? body.Message[..Math.Min(30, body.Message.Length)] : "(empty)", !string.IsNullOrEmpty(body.SessionStateJson)); var result = await _bll.RunAsync(body, login, ct).ConfigureAwait(false); return await GB5Shared.ResponseStandard.Response.CreateSuccessResponse( result, CacheKeyLevel.NOT_REQUIRED, login); } public record Parameters( [property: FromHeader] string? Login, [property: FromBody] PlaygroundRunRequest? Body); } }