feat(behandelportal): WP-64 werkvoorraad (queue) screen
CI / changes (pull_request) Successful in 15s
CI / lint (pull_request) Successful in 57s
CI / frontend (pull_request) Successful in 2m36s
CI / storybook-a11y (pull_request) Failing after 3m14s
CI / backend (pull_request) Successful in 2m1s
CI / semgrep (pull_request) Successful in 1m10s
CI / e2e (pull_request) Successful in 3m3s
CI / api-client-drift (pull_request) Successful in 2m1s
CI / changes (pull_request) Successful in 15s
CI / lint (pull_request) Successful in 57s
CI / frontend (pull_request) Successful in 2m36s
CI / storybook-a11y (pull_request) Failing after 3m14s
CI / backend (pull_request) Successful in 2m1s
CI / semgrep (pull_request) Successful in 1m10s
CI / e2e (pull_request) Successful in 3m3s
CI / api-client-drift (pull_request) Successful in 2m1s
New GET /werkvoorraad endpoint lists aanvragen still open (Ingediend/InBehandeling), gated by the medewerker capability (CanBeoordelen) rather than the admin role — reuses the existing ApplicationSummaryDto, no new DTO. GET /me now surfaces aanvraag:beoordelen for a behandelaar so the FE can gate with the same AccessStore/capabilityGuard idiom every other page uses. FE: a behandeling domain type deliberately narrower than ssp's full AanvraagStatus union (only the two open tags — illegal states unrepresentable), composed into a werkvoorraad-list organism from existing shared/ui molecules. Replaces WP-61's scaffold placeholder as the app's real landing page. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -409,6 +409,17 @@ api.MapGet("/admin/cases", (HttpContext ctx, IZaakSource zaken) => CasesAdmin(ct
|
||||
.Produces<List<ApplicationSummaryDto>>()
|
||||
.ProducesProblem(StatusCodes.Status403Forbidden);
|
||||
|
||||
// --- Werkvoorraad (WP-64): the behandelportal's queue of aanvragen needing treatment. ---
|
||||
// Cross-owner like /admin/cases, but gated by the medewerker capability (`CanBeoordelen`,
|
||||
// WP-62) rather than the admin role, and pre-filtered to the two "still open" status tags —
|
||||
// a behandelaar never needs to see a Concept (not their business yet) or a terminal case.
|
||||
api.MapGet("/werkvoorraad", (HttpContext ctx, IZaakSource zaken) => Werkvoorraad(ctx, () =>
|
||||
Results.Ok(zaken.ListCases(DateTimeOffset.UtcNow)
|
||||
.Where(c => c.Status.Tag is "Ingediend" or "InBehandeling")
|
||||
.ToList())))
|
||||
.Produces<List<ApplicationSummaryDto>>()
|
||||
.ProducesProblem(StatusCodes.Status403Forbidden);
|
||||
|
||||
// OpenZaak's Notificaties API (NRC) calls this on every zaak event once an `abonnement` is
|
||||
// provisioned (WP-52, out-of-band — see openzaak-integration.md, no app code subscribes it).
|
||||
// The caller is NRC, not a user: no Principal, so this audits via AuthzAuditStore directly
|
||||
@@ -462,7 +473,15 @@ api.MapGet("/admin/audit", (HttpContext ctx) => CasesAdmin(ctx, () =>
|
||||
|
||||
// PRD-0002 §6: coarse, role-derived capabilities for nav/menu-level checks (NOT
|
||||
// tied to a specific brief's live status — see BriefDecisionsDto for that).
|
||||
api.MapGet("/me", (HttpContext ctx) => new MeDto(Authz.RoleCapabilities(Authz.ResolvePrincipal(ctx))))
|
||||
// WP-64: `aanvraag:beoordelen` is caller-kind-derived (CanBeoordelen), not role-derived like
|
||||
// the rest of RoleCapabilities — appended here rather than folded into that switch, since it
|
||||
// depends on CallerIdentity (medewerker rollen), not the dev X-Role stand-in.
|
||||
api.MapGet("/me", (HttpContext ctx) =>
|
||||
{
|
||||
var caps = Authz.RoleCapabilities(Authz.ResolvePrincipal(ctx)).ToList();
|
||||
if (Authz.CanBeoordelen(ctx.Caller())) caps.Add("aanvraag:beoordelen");
|
||||
return new MeDto(caps);
|
||||
})
|
||||
.Produces<MeDto>();
|
||||
|
||||
// Feature flags (WP-47). GET is readable by any principal (it drives FE gating); the toggle is
|
||||
@@ -689,6 +708,17 @@ IResult CasesAdmin(HttpContext ctx, Func<IResult> action)
|
||||
statusCode: StatusCodes.Status403Forbidden);
|
||||
}
|
||||
|
||||
// One gate for the werkvoorraad read — the enforce twin of `CanBeoordelen` (WP-62/64).
|
||||
// Unlike the other *Admin gates above, this checks the CallerIdentity directly (medewerker
|
||||
// rollen), not a role-only Principal — a zorgverlener with X-Role=admin still gets denied.
|
||||
IResult Werkvoorraad(HttpContext ctx, Func<IResult> action)
|
||||
{
|
||||
if (Authz.CanBeoordelen(ctx.Caller())) return action();
|
||||
AuditAuthz(ctx, "aanvraag:beoordelen", "werkvoorraad", false, Authz.ResolvePrincipal(ctx));
|
||||
return Results.Problem(detail: "Alleen een behandelaar mag de werkvoorraad bekijken.",
|
||||
statusCode: StatusCodes.Status403Forbidden);
|
||||
}
|
||||
|
||||
// One gate for the feature-flag toggle — the enforce twin of `flags:manage` (WP-47).
|
||||
IResult FlagsAdmin(HttpContext ctx, Func<IResult> action)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user