Files
git.stella-ops.org/src/Findings/StellaOps.Findings.Ledger.WebService/Endpoints/EvidenceGraphEndpoints.cs
2025-12-25 23:10:09 +02:00

59 lines
2.1 KiB
C#

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<Results<Ok<EvidenceGraphResponse>, 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<EvidenceGraphResponse>(200)
.Produces(404);
// GET /api/v1/findings/{findingId}/evidence/{nodeId}
group.MapGet("/{findingId:guid}/evidence/{nodeId}", async Task<Results<Ok<object>, 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<object>(200)
.Produces(404);
}
}
/// <summary>
/// Service for retrieving evidence node content.
/// </summary>
public interface IEvidenceContentService
{
Task<object?> GetContentAsync(Guid findingId, string nodeId, CancellationToken ct);
}