feat(bff): POST /behandel/registrations/{id}/decide behind the behandelaar policy (refs #13)
Forwards a behandelaar's goedkeuren/afwijzen to the domain (which applies the decision and completes the workflow task). Validates the besluit vocabulary (400 on unknown) without troubling the domain. openapi.json + api-client regenerated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -103,8 +103,28 @@ app.MapGet("/behandel/werkbak", async (IDomainClient domain, CancellationToken c
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status403Forbidden);
|
||||
|
||||
// A behandelaar's beoordeling on a registration (goedkeuren/afwijzen). Forwarded to the domain, which
|
||||
// applies the decision and completes the workflow task (ADR-0013). Same medewerker/behandelaar gate.
|
||||
app.MapPost("/behandel/registrations/{id}/decide",
|
||||
async (string id, DecideRequest body, IDomainClient domain, CancellationToken ct) =>
|
||||
{
|
||||
if (!BehandelAuth.IsKnownBesluit(body.Besluit))
|
||||
return Results.BadRequest(new { error = $"Unknown besluit '{body.Besluit}'. Expected 'goedkeuren' or 'afwijzen'." });
|
||||
|
||||
await domain.DecideAsync(id, body.Besluit, ct);
|
||||
return Results.NoContent();
|
||||
})
|
||||
.RequireAuthorization(BehandelAuth.Policy)
|
||||
.Produces(StatusCodes.Status204NoContent)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status403Forbidden);
|
||||
|
||||
app.Run();
|
||||
|
||||
/// <summary>The behandelaar's decision on a registration.</summary>
|
||||
public sealed record DecideRequest(string Besluit);
|
||||
|
||||
// Behandel (medewerker-realm) authentication + authorization wiring (ADR-0013).
|
||||
internal static class BehandelAuth
|
||||
{
|
||||
@@ -112,6 +132,12 @@ internal static class BehandelAuth
|
||||
public const string Policy = "behandelaar";
|
||||
public const string BehandelaarRole = "behandelaar";
|
||||
|
||||
/// <summary>The beoordeling vocabulary the BFF accepts (case-insensitive); an unknown besluit is a
|
||||
/// 400 without troubling the domain. Mirrors the domain's <c>BeoordelingsBesluit</c>.</summary>
|
||||
public static bool IsKnownBesluit(string? besluit) =>
|
||||
string.Equals(besluit, "goedkeuren", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(besluit, "afwijzen", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>Lift Keycloak's realm roles (the nested <c>realm_access.roles</c> claim) onto the
|
||||
/// principal as role claims, so <c>RequireRole</c> can authorize on them.</summary>
|
||||
public static void AddRealmRoles(ClaimsPrincipal? principal)
|
||||
|
||||
Reference in New Issue
Block a user