wip: doctor/cli/docs/api to vector db consolidation; api hardening for descriptions, tenant, and scopes; migrations and conversions of all DALs to EF v10
This commit is contained in:
@@ -20,11 +20,13 @@ public static class PointInTimeQueryEndpoints
|
||||
public static void MapPointInTimeQueryEndpoints(this IEndpointRouteBuilder app)
|
||||
{
|
||||
var group = app.MapGroup("/v1/pit/advisory")
|
||||
.WithTags("Point-in-Time Advisory");
|
||||
.WithTags("Point-in-Time Advisory")
|
||||
.RequireAuthorization("replay.token.read");
|
||||
|
||||
// GET /v1/pit/advisory/{cveId} - Query advisory state at a point in time
|
||||
group.MapGet("/{cveId}", QueryAdvisoryAsync)
|
||||
.WithName("QueryAdvisoryAtPointInTime")
|
||||
.WithDescription("Returns the advisory state for a specific CVE at a given point-in-time timestamp from the specified provider. Uses the nearest captured feed snapshot to reconstruct the advisory as it appeared at that moment.")
|
||||
.Produces<AdvisoryQueryResponse>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.ProducesProblem(StatusCodes.Status400BadRequest);
|
||||
@@ -32,45 +34,53 @@ public static class PointInTimeQueryEndpoints
|
||||
// POST /v1/pit/advisory/cross-provider - Query advisory across multiple providers
|
||||
group.MapPost("/cross-provider", QueryCrossProviderAsync)
|
||||
.WithName("QueryCrossProviderAdvisory")
|
||||
.WithDescription("Queries advisory state across multiple feed providers at a single point in time and returns per-provider results along with a consensus summary of severity and fix status.")
|
||||
.Produces<CrossProviderQueryResponse>(StatusCodes.Status200OK)
|
||||
.ProducesProblem(StatusCodes.Status400BadRequest);
|
||||
|
||||
// GET /v1/pit/advisory/{cveId}/timeline - Get advisory timeline
|
||||
group.MapGet("/{cveId}/timeline", GetAdvisoryTimelineAsync)
|
||||
.WithName("GetAdvisoryTimeline")
|
||||
.WithDescription("Returns the change timeline for a specific CVE from a given provider within an optional time range. Each entry identifies the snapshot digest and the type of change observed.")
|
||||
.Produces<AdvisoryTimelineResponse>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound);
|
||||
|
||||
// POST /v1/pit/advisory/diff - Compare advisory at two points in time
|
||||
group.MapPost("/diff", CompareAdvisoryAtTimesAsync)
|
||||
.WithName("CompareAdvisoryAtTimes")
|
||||
.WithDescription("Produces a field-level diff of a CVE advisory between two distinct points in time from the same provider, identifying severity, fix-status, and metadata changes.")
|
||||
.Produces<AdvisoryDiffResponse>(StatusCodes.Status200OK)
|
||||
.ProducesProblem(StatusCodes.Status400BadRequest);
|
||||
|
||||
var snapshotsGroup = app.MapGroup("/v1/pit/snapshots")
|
||||
.WithTags("Feed Snapshots");
|
||||
.WithTags("Feed Snapshots")
|
||||
.RequireAuthorization("replay.token.write");
|
||||
|
||||
// POST /v1/pit/snapshots - Capture a feed snapshot
|
||||
snapshotsGroup.MapPost("/", CaptureSnapshotAsync)
|
||||
.WithName("CaptureFeedSnapshot")
|
||||
.WithDescription("Captures and stores a feed snapshot for a specific provider, computing its content-addressable digest. Returns 201 Created with the digest and whether an existing snapshot was reused.")
|
||||
.Produces<SnapshotCaptureResponse>(StatusCodes.Status201Created)
|
||||
.ProducesProblem(StatusCodes.Status400BadRequest);
|
||||
|
||||
// GET /v1/pit/snapshots/{digest} - Get a snapshot by digest
|
||||
snapshotsGroup.MapGet("/{digest}", GetSnapshotAsync)
|
||||
.WithName("GetFeedSnapshot")
|
||||
.WithDescription("Returns snapshot metadata for a specific content-addressable digest including provider ID, feed type, and capture timestamp. Returns 404 if the digest is not stored.")
|
||||
.Produces<SnapshotResponse>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound);
|
||||
|
||||
// GET /v1/pit/snapshots/{digest}/verify - Verify snapshot integrity
|
||||
snapshotsGroup.MapGet("/{digest}/verify", VerifySnapshotIntegrityAsync)
|
||||
.WithName("VerifySnapshotIntegrity")
|
||||
.WithDescription("Verifies the integrity of a stored snapshot by recomputing its content digest and comparing it against the stored value. Returns a verification result with expected and actual digest values.")
|
||||
.Produces<SnapshotVerificationResponse>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound);
|
||||
|
||||
// POST /v1/pit/snapshots/bundle - Create a snapshot bundle
|
||||
snapshotsGroup.MapPost("/bundle", CreateSnapshotBundleAsync)
|
||||
.WithName("CreateSnapshotBundle")
|
||||
.WithDescription("Creates a composite snapshot bundle from multiple providers at a given point in time, returning the bundle digest, completeness flag, and the list of any missing providers.")
|
||||
.Produces<SnapshotBundleResponse>(StatusCodes.Status200OK)
|
||||
.ProducesProblem(StatusCodes.Status400BadRequest);
|
||||
}
|
||||
|
||||
@@ -24,11 +24,13 @@ public static class VerdictReplayEndpoints
|
||||
public static void MapVerdictReplayEndpoints(this IEndpointRouteBuilder app)
|
||||
{
|
||||
var group = app.MapGroup("/v1/replay/verdict")
|
||||
.WithTags("Verdict Replay");
|
||||
.WithTags("Verdict Replay")
|
||||
.RequireAuthorization("replay.token.read");
|
||||
|
||||
// POST /v1/replay/verdict - Execute verdict replay
|
||||
group.MapPost("/", ExecuteReplayAsync)
|
||||
.WithName("ExecuteVerdictReplay")
|
||||
.WithDescription("Executes a deterministic verdict replay from an audit bundle, re-evaluating the original policy with the stored inputs. Returns whether the replayed verdict matches the original, drift items, and an optional divergence report.")
|
||||
.Produces<VerdictReplayResponse>(StatusCodes.Status200OK)
|
||||
.ProducesProblem(StatusCodes.Status400BadRequest)
|
||||
.ProducesProblem(StatusCodes.Status404NotFound);
|
||||
@@ -36,18 +38,21 @@ public static class VerdictReplayEndpoints
|
||||
// POST /v1/replay/verdict/verify - Verify replay eligibility
|
||||
group.MapPost("/verify", VerifyEligibilityAsync)
|
||||
.WithName("VerifyReplayEligibility")
|
||||
.WithDescription("Checks whether an audit bundle is eligible for deterministic replay. Returns a confidence score, eligibility flags, and the expected outcome without executing the replay.")
|
||||
.Produces<ReplayEligibilityResponse>(StatusCodes.Status200OK)
|
||||
.ProducesProblem(StatusCodes.Status400BadRequest);
|
||||
|
||||
// GET /v1/replay/verdict/{manifestId}/status - Get replay status
|
||||
group.MapGet("/{manifestId}/status", GetReplayStatusAsync)
|
||||
.WithName("GetReplayStatus")
|
||||
.WithDescription("Returns the stored replay history for a given audit manifest ID including total replay count, success/failure counts, and the timestamp of the last replay.")
|
||||
.Produces<ReplayStatusResponse>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound);
|
||||
|
||||
// POST /v1/replay/verdict/compare - Compare two replay executions
|
||||
group.MapPost("/compare", CompareReplayResultsAsync)
|
||||
.WithName("CompareReplayResults")
|
||||
.WithDescription("Compares two replay execution results and produces a structured divergence report identifying field-level differences with per-divergence severity ratings.")
|
||||
.Produces<ReplayComparisonResponse>(StatusCodes.Status200OK)
|
||||
.ProducesProblem(StatusCodes.Status400BadRequest);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user