using FastEndpoints; using Microsoft.Extensions.Logging; namespace KArtSell.Host.Features.ShadowRun; /// /// GET /api/shadow-runs/{run_id} /// Poll shadow run status and retrieve results. /// Returns 200 with status (in progress) or 200 with metrics (complete). /// public sealed class GetShadowRunPollingEndpoint : Endpoint { private GetShadowRunQuery? _query; private ILogger? _logger; private static readonly Action LogPolling = LoggerMessage.Define( LogLevel.Debug, new EventId(1, nameof(LogPolling)), "Polling shadow run {RunId}"); private static readonly Action LogNotFound = LoggerMessage.Define( LogLevel.Information, new EventId(2, nameof(LogNotFound)), "Shadow run {RunId} not found"); public override void Configure() { Get("/api/shadow-runs/{RunId}"); AllowAnonymous(); // TODO: Add RBAC } public override async Task HandleAsync(GetShadowRunPollingRequest req, CancellationToken ct) { _query = Resolve(); _logger = Resolve>(); LogPolling(_logger, req.RunId, null); var result = await _query.GetAsync(req.RunId, ct); if (result == null) { LogNotFound(_logger, req.RunId, null); ThrowError($"Shadow run {req.RunId} not found", 404); return; } HttpContext.Response.StatusCode = 200; await HttpContext.Response.WriteAsJsonAsync(result, ct); } } public sealed record GetShadowRunPollingRequest(Guid RunId);