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:
@@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using StellaOps.Auth.ServerIntegration.Tenancy;
|
||||
using StellaOps.Findings.Ledger.WebService.Contracts;
|
||||
using StellaOps.Findings.Ledger.WebService.Services;
|
||||
|
||||
@@ -17,13 +18,15 @@ public static class WebhookEndpoints
|
||||
public static void MapWebhookEndpoints(this IEndpointRouteBuilder app)
|
||||
{
|
||||
var group = app.MapGroup("/api/v1/scoring/webhooks")
|
||||
.WithTags("Webhooks");
|
||||
.WithTags("Webhooks")
|
||||
.RequireTenant();
|
||||
|
||||
// POST /api/v1/scoring/webhooks - Register webhook
|
||||
// Rate limit: 10/min (via API Gateway)
|
||||
group.MapPost("/", RegisterWebhook)
|
||||
.WithName("RegisterScoringWebhook")
|
||||
.WithDescription("Register a webhook for score change notifications")
|
||||
.WithSummary("Register a webhook for score change notifications")
|
||||
.WithDescription("Registers an HTTPS callback URL to receive score change notifications. Supports optional HMAC-SHA256 signing via a shared secret, finding pattern filters, minimum score change threshold, and bucket transition triggers. The webhook is activated immediately upon registration.")
|
||||
.Produces<WebhookResponse>(StatusCodes.Status201Created)
|
||||
.ProducesValidationProblem()
|
||||
.RequireAuthorization(ScoringAdminPolicy);
|
||||
@@ -32,7 +35,8 @@ public static class WebhookEndpoints
|
||||
// Rate limit: 10/min (via API Gateway)
|
||||
group.MapGet("/", ListWebhooks)
|
||||
.WithName("ListScoringWebhooks")
|
||||
.WithDescription("List all registered webhooks")
|
||||
.WithSummary("List all registered webhooks")
|
||||
.WithDescription("Returns all currently registered score change webhooks with their configuration, including URL, filter patterns, minimum score change threshold, and creation timestamp. Secrets are not returned in responses.")
|
||||
.Produces<WebhookListResponse>(StatusCodes.Status200OK)
|
||||
.RequireAuthorization(ScoringAdminPolicy);
|
||||
|
||||
@@ -40,7 +44,8 @@ public static class WebhookEndpoints
|
||||
// Rate limit: 10/min (via API Gateway)
|
||||
group.MapGet("/{id:guid}", GetWebhook)
|
||||
.WithName("GetScoringWebhook")
|
||||
.WithDescription("Get a specific webhook by ID")
|
||||
.WithSummary("Get a specific webhook by ID")
|
||||
.WithDescription("Returns the configuration of a specific webhook by its UUID. Inactive webhooks (soft-deleted) return 404. Secrets are not included in the response body.")
|
||||
.Produces<WebhookResponse>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.RequireAuthorization(ScoringAdminPolicy);
|
||||
@@ -49,7 +54,8 @@ public static class WebhookEndpoints
|
||||
// Rate limit: 10/min (via API Gateway)
|
||||
group.MapPut("/{id:guid}", UpdateWebhook)
|
||||
.WithName("UpdateScoringWebhook")
|
||||
.WithDescription("Update a webhook configuration")
|
||||
.WithSummary("Update a webhook configuration")
|
||||
.WithDescription("Replaces the full configuration of an existing webhook. All fields in the request body are applied as-is; partial updates are not supported. To update a secret, supply the new secret value; omitting the secret field retains the existing secret.")
|
||||
.Produces<WebhookResponse>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.ProducesValidationProblem()
|
||||
@@ -59,7 +65,8 @@ public static class WebhookEndpoints
|
||||
// Rate limit: 10/min (via API Gateway)
|
||||
group.MapDelete("/{id:guid}", DeleteWebhook)
|
||||
.WithName("DeleteScoringWebhook")
|
||||
.WithDescription("Delete a webhook")
|
||||
.WithSummary("Delete a webhook")
|
||||
.WithDescription("Permanently removes a webhook registration by its UUID. No further score change notifications will be delivered to the associated URL after deletion. Returns 204 on success, 404 if the webhook does not exist.")
|
||||
.Produces(StatusCodes.Status204NoContent)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.RequireAuthorization(ScoringAdminPolicy);
|
||||
@@ -67,7 +74,8 @@ public static class WebhookEndpoints
|
||||
|
||||
private static Results<Created<WebhookResponse>, ValidationProblem> RegisterWebhook(
|
||||
[FromBody] RegisterWebhookRequest request,
|
||||
[FromServices] IWebhookStore store)
|
||||
[FromServices] IWebhookStore store,
|
||||
[FromServices] IStellaOpsTenantAccessor tenantAccessor)
|
||||
{
|
||||
// Validate URL
|
||||
if (!Uri.TryCreate(request.Url, UriKind.Absolute, out var uri) ||
|
||||
@@ -86,7 +94,8 @@ public static class WebhookEndpoints
|
||||
}
|
||||
|
||||
private static Ok<WebhookListResponse> ListWebhooks(
|
||||
[FromServices] IWebhookStore store)
|
||||
[FromServices] IWebhookStore store,
|
||||
[FromServices] IStellaOpsTenantAccessor tenantAccessor)
|
||||
{
|
||||
var webhooks = store.List();
|
||||
var response = new WebhookListResponse
|
||||
@@ -100,7 +109,8 @@ public static class WebhookEndpoints
|
||||
|
||||
private static Results<Ok<WebhookResponse>, NotFound> GetWebhook(
|
||||
Guid id,
|
||||
[FromServices] IWebhookStore store)
|
||||
[FromServices] IWebhookStore store,
|
||||
[FromServices] IStellaOpsTenantAccessor tenantAccessor)
|
||||
{
|
||||
var webhook = store.Get(id);
|
||||
if (webhook is null || !webhook.IsActive)
|
||||
@@ -114,7 +124,8 @@ public static class WebhookEndpoints
|
||||
private static Results<Ok<WebhookResponse>, NotFound, ValidationProblem> UpdateWebhook(
|
||||
Guid id,
|
||||
[FromBody] RegisterWebhookRequest request,
|
||||
[FromServices] IWebhookStore store)
|
||||
[FromServices] IWebhookStore store,
|
||||
[FromServices] IStellaOpsTenantAccessor tenantAccessor)
|
||||
{
|
||||
// Validate URL
|
||||
if (!Uri.TryCreate(request.Url, UriKind.Absolute, out var uri) ||
|
||||
@@ -137,7 +148,8 @@ public static class WebhookEndpoints
|
||||
|
||||
private static Results<NoContent, NotFound> DeleteWebhook(
|
||||
Guid id,
|
||||
[FromServices] IWebhookStore store)
|
||||
[FromServices] IWebhookStore store,
|
||||
[FromServices] IStellaOpsTenantAccessor tenantAccessor)
|
||||
{
|
||||
if (!store.Delete(id))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user