using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; using StellaOps.Findings.Ledger.WebService.Contracts; using StellaOps.Findings.Ledger.WebService.Services; namespace StellaOps.Findings.Ledger.WebService.Endpoints; public static class EvidenceGraphEndpoints { public static void MapEvidenceGraphEndpoints(this WebApplication app) { var group = app.MapGroup("/api/v1/findings") .WithTags("Evidence Graph") .RequireAuthorization(); // GET /api/v1/findings/{findingId}/evidence-graph group.MapGet("/{findingId:guid}/evidence-graph", async Task, NotFound>> ( Guid findingId, IEvidenceGraphBuilder builder, CancellationToken ct, [FromQuery] bool includeContent = false) => { var graph = await builder.BuildAsync(findingId, ct); return graph is not null ? TypedResults.Ok(graph) : TypedResults.NotFound(); }) .WithName("GetEvidenceGraph") .WithDescription("Get evidence graph for finding visualization") .Produces(200) .Produces(404); // GET /api/v1/findings/{findingId}/evidence/{nodeId} group.MapGet("/{findingId:guid}/evidence/{nodeId}", async Task, NotFound>> ( Guid findingId, string nodeId, IEvidenceContentService contentService, CancellationToken ct) => { var content = await contentService.GetContentAsync(findingId, nodeId, ct); return content is not null ? TypedResults.Ok(content) : TypedResults.NotFound(); }) .WithName("GetEvidenceNodeContent") .WithDescription("Get raw content for an evidence node") .Produces(200) .Produces(404); } } /// /// Service for retrieving evidence node content. /// public interface IEvidenceContentService { Task GetContentAsync(Guid findingId, string nodeId, CancellationToken ct); }