using FastEndpoints; using QuantEngine.Core.Interfaces; namespace QuantEngine.Web.Endpoints; public class GetCollectionStateEndpoint : EndpointWithoutRequest { private readonly ICollectionRepository _repo; public GetCollectionStateEndpoint(ICollectionRepository repo) { _repo = repo; } public override void Configure() { Get("/api/collection/state"); AllowAnonymous(); Description(d => d .Produces(200) .Produces(500)); } public override async Task HandleAsync(CancellationToken ct) { try { var state = await _repo.GetDashboardStateAsync(); await SendOkAsync(state, ct); } catch { await SendErrorsAsync(500, ct); } } } public class GetRecentRunsRequest { public int Limit { get; set; } = 20; } public class GetRecentRunsResponse { public List Runs { get; set; } = new(); public int Count { get; set; } } public class GetRecentRunsEndpoint : Endpoint { private readonly ICollectionRepository _repo; public GetRecentRunsEndpoint(ICollectionRepository repo) { _repo = repo; } public override void Configure() { Get("/api/collection/runs"); AllowAnonymous(); Description(d => d .Produces(200) .Produces(500)); } public override async Task HandleAsync(GetRecentRunsRequest req, CancellationToken ct) { try { var runs = await _repo.GetRecentRunsAsync(req.Limit); await SendOkAsync(new GetRecentRunsResponse { Runs = runs, Count = runs.Count }, ct); } catch { await SendErrorsAsync(500, ct); } } } public class GetRunSnapshotsRequest { public string RunId { get; set; } = ""; } public class GetRunSnapshotsResponse { public string RunId { get; set; } = ""; public List Snapshots { get; set; } = new(); public int Count { get; set; } } public class GetRunSnapshotsEndpoint : Endpoint { private readonly ICollectionRepository _repo; public GetRunSnapshotsEndpoint(ICollectionRepository repo) { _repo = repo; } public override void Configure() { Get("/api/collection/runs/{RunId}/snapshots"); AllowAnonymous(); Description(d => d .Produces(200) .Produces(404) .Produces(500)); } public override async Task HandleAsync(GetRunSnapshotsRequest req, CancellationToken ct) { try { var snapshots = await _repo.GetRunSnapshotsAsync(req.RunId); await SendOkAsync(new GetRunSnapshotsResponse { RunId = req.RunId, Snapshots = snapshots, Count = snapshots.Count }, ct); } catch { await SendErrorsAsync(500, ct); } } } public class GetRunErrorsRequest { public string RunId { get; set; } = ""; public int Limit { get; set; } = 50; } public class GetRunErrorsResponse { public string RunId { get; set; } = ""; public List Errors { get; set; } = new(); public int Count { get; set; } } public class GetRunErrorsEndpoint : Endpoint { private readonly ICollectionRepository _repo; public GetRunErrorsEndpoint(ICollectionRepository repo) { _repo = repo; } public override void Configure() { Get("/api/collection/runs/{RunId}/errors"); AllowAnonymous(); Description(d => d .Produces(200) .Produces(404) .Produces(500)); } public override async Task HandleAsync(GetRunErrorsRequest req, CancellationToken ct) { try { var errors = await _repo.GetRunErrorsAsync(req.RunId, req.Limit); await SendOkAsync(new GetRunErrorsResponse { RunId = req.RunId, Errors = errors, Count = errors.Count }, ct); } catch { await SendErrorsAsync(500, ct); } } } public class GetLatestSnapshotsRequest { public string Ticker { get; set; } = ""; public int Limit { get; set; } = 10; } public class GetLatestSnapshotsResponse { public string Ticker { get; set; } = ""; public List Snapshots { get; set; } = new(); public int Count { get; set; } } public class GetLatestSnapshotsEndpoint : Endpoint { private readonly ICollectionRepository _repo; public GetLatestSnapshotsEndpoint(ICollectionRepository repo) { _repo = repo; } public override void Configure() { Get("/api/collection/latest/{Ticker}"); AllowAnonymous(); Description(d => d .Produces(200) .Produces(500)); } public override async Task HandleAsync(GetLatestSnapshotsRequest req, CancellationToken ct) { try { var snapshots = await _repo.GetLatestSnapshotsForTickerAsync(req.Ticker, req.Limit); await SendOkAsync(new GetLatestSnapshotsResponse { Ticker = req.Ticker, Snapshots = snapshots, Count = snapshots.Count }, ct); } catch { await SendErrorsAsync(500, ct); } } } public class StartCollectionRunEndpoint : EndpointWithoutRequest { public override void Configure() { Post("/api/collection/run"); AllowAnonymous(); Description(d => d .Produces(202) .Produces(500)); } public override async Task HandleAsync(CancellationToken ct) { // Return 202 Accepted status code via generic status code handler await SendResultAsync(Microsoft.AspNetCore.Http.Results.Accepted()); } }