feat(bff): committed OpenAPI contract + drift guard (refs #8)
Document typed responses (202 SubmitAccepted / 400 / 401 on self-service; 200 OpenbaarEntry[] on openbaar) so the generated spec carries real schemas for S-08's client. A document transformer clears the auto-populated servers block so the spec is host-independent and deterministic. Commit services/bff/openapi.json and add a test asserting it matches the served /openapi/v1.json (fails on drift). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,7 +27,14 @@ builder.Services.AddHttpClient<IDomainClient, DomainClient>(c => c.BaseAddress =
|
||||
builder.Services.AddHttpClient<IProjectionClient, ProjectionClient>(c => c.BaseAddress = new Uri(projectionBaseUrl));
|
||||
|
||||
builder.Services.AddHealthChecks();
|
||||
builder.Services.AddOpenApi();
|
||||
// Clear the auto-populated `servers` block so the committed spec is stable regardless of the host
|
||||
// the doc was generated from (the client sets its own base URL). Keeps the drift guard deterministic.
|
||||
builder.Services.AddOpenApi(options =>
|
||||
options.AddDocumentTransformer((document, _, _) =>
|
||||
{
|
||||
document.Servers?.Clear();
|
||||
return Task.CompletedTask;
|
||||
}));
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
@@ -47,14 +54,19 @@ app.MapPost("/self-service/registrations", async (ClaimsPrincipal user, IDomainC
|
||||
|
||||
var accepted = await domain.SubmitRegistrationAsync(bsn, ct);
|
||||
return Results.Accepted($"/self-service/registrations/{accepted.RegistrationId}", accepted);
|
||||
}).RequireAuthorization();
|
||||
})
|
||||
.RequireAuthorization()
|
||||
.Produces<SubmitAccepted>(StatusCodes.Status202Accepted)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.Produces(StatusCodes.Status401Unauthorized);
|
||||
|
||||
// Openbaar register: an anonymous public lookup that exposes only public-safe fields (S-09).
|
||||
app.MapGet("/openbaar/register", async (string? q, IProjectionClient projection, CancellationToken ct) =>
|
||||
{
|
||||
var entries = await projection.GetRegisterAsync(ct);
|
||||
return Results.Ok(OpenbaarProjection.PublicView(entries, q));
|
||||
});
|
||||
})
|
||||
.Produces<IReadOnlyList<OpenbaarEntry>>(StatusCodes.Status200OK);
|
||||
|
||||
app.Run();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user