refactor: rename Application → Aanvraag across the wire (Step 1/8)

The wire said Application, the domain said Aanvraag — one aggregate with
two names at every hop. Rename the backend DTOs and the /applications
route to /aanvragen, regenerate the typed client, and rename the frontend
adapter/store to match.

Renamed: ApplicationSummaryDto/DetailDto, CreateApplicationRequest,
SubmitApplicationRequest/Response → Aanvraag* equivalents;
ApplicationsAdapter/Store → AanvragenAdapter/Store;
applications.adapter.ts/applications.store.ts → aanvragen.*.

Left untouched: the admin Case/Zaak vocabulary (/admin/cases,
AdminCasesStore) — a separate read model, not part of this rename; the
internal BigRegister.Domain.Applications namespace and the Applications
EF table (renaming those needs a new EF migration, out of scope here).

Part of the dashboard-readability refactor (see the approved plan).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
eho
2026-09-04 14:33:16 +02:00
co-authored by Claude Opus 5
parent faad772f85
commit 194cccfd02
36 changed files with 400 additions and 412 deletions
@@ -8,27 +8,27 @@ using Microsoft.AspNetCore.Mvc.Testing;
namespace BigRegister.Tests;
public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture<TestWebApplicationFactory>
public class AanvraagTests(TestWebApplicationFactory factory) : IClassFixture<TestWebApplicationFactory>
{
private readonly HttpClient _client = factory.CreateClient();
private async Task<ApplicationDetailDto> Create(string type = "registratie")
private async Task<AanvraagDetailDto> Create(string type = "registratie")
{
// WP-35: one Concept per type is now server-enforced, and these tests share one DB
// (IClassFixture). Clear any leftover Concept so each test starts from a clean slate.
var existing = await List();
Assert.NotNull(existing);
foreach (var s in existing.Where(x => x.Status.Tag == "Concept"))
await _client.DeleteAsync($"/api/v1/applications/{s.Id}");
var res = await _client.PostAsJsonAsync("/api/v1/applications", new { type });
await _client.DeleteAsync($"/api/v1/aanvragen/{s.Id}");
var res = await _client.PostAsJsonAsync("/api/v1/aanvragen", new { type });
Assert.Equal(HttpStatusCode.Created, res.StatusCode);
var created = await res.Content.ReadFromJsonAsync<ApplicationDetailDto>();
var created = await res.Content.ReadFromJsonAsync<AanvraagDetailDto>();
Assert.NotNull(created);
return created;
}
private Task<List<ApplicationSummaryDto>?> List() =>
_client.GetFromJsonAsync<List<ApplicationSummaryDto>>("/api/v1/applications");
private Task<List<AanvraagSummaryDto>?> List() =>
_client.GetFromJsonAsync<List<AanvraagSummaryDto>>("/api/v1/aanvragen");
// --- Lifecycle over HTTP ---
@@ -36,7 +36,7 @@ public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture
public async Task Create_then_list_shows_a_concept_with_step_progress()
{
var a = await Create();
await _client.PutAsJsonAsync($"/api/v1/applications/{a.Id}",
await _client.PutAsJsonAsync($"/api/v1/aanvragen/{a.Id}",
new { draft = new { beroep = "arts" }, stepIndex = 1, stepCount = 4 });
var list = await List();
@@ -51,10 +51,10 @@ public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture
public async Task Draft_sync_is_readable_back_from_detail()
{
var a = await Create();
await _client.PutAsJsonAsync($"/api/v1/applications/{a.Id}",
await _client.PutAsJsonAsync($"/api/v1/aanvragen/{a.Id}",
new { draft = new { beroep = "verpleegkundige" }, stepIndex = 2, stepCount = 4 });
var detail = await _client.GetFromJsonAsync<ApplicationDetailDto>($"/api/v1/applications/{a.Id}");
var detail = await _client.GetFromJsonAsync<AanvraagDetailDto>($"/api/v1/aanvragen/{a.Id}");
Assert.NotNull(detail);
Assert.NotNull(detail.Draft);
Assert.Equal("verpleegkundige", detail.Draft.Value.GetProperty("beroep").GetString());
@@ -64,9 +64,9 @@ public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture
public async Task Submit_duo_registratie_is_in_behandeling_and_auto()
{
var a = await Create("registratie");
var res = await _client.PostAsJsonAsync($"/api/v1/applications/{a.Id}/submit", new { diplomaHerkomst = "duo" });
var res = await _client.PostAsJsonAsync($"/api/v1/aanvragen/{a.Id}/submit", new { diplomaHerkomst = "duo" });
res.EnsureSuccessStatusCode();
var body = (await res.Content.ReadFromJsonAsync<SubmitApplicationResponse>())!;
var body = (await res.Content.ReadFromJsonAsync<AanvraagIndienenResponse>())!;
Assert.StartsWith("BIG-2026-", body.Referentie);
Assert.Equal("InBehandeling", body.Status.Tag);
Assert.False(body.Status.Manual); // auto-approvable → not a manual case
@@ -76,9 +76,9 @@ public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture
public async Task Submit_handmatig_registratie_succeeds_as_manual_case()
{
var a = await Create("registratie");
var res = await _client.PostAsJsonAsync($"/api/v1/applications/{a.Id}/submit", new { diplomaHerkomst = "handmatig" });
var res = await _client.PostAsJsonAsync($"/api/v1/aanvragen/{a.Id}/submit", new { diplomaHerkomst = "handmatig" });
res.EnsureSuccessStatusCode(); // no longer a 422
var body = (await res.Content.ReadFromJsonAsync<SubmitApplicationResponse>())!;
var body = (await res.Content.ReadFromJsonAsync<AanvraagIndienenResponse>())!;
Assert.Equal("InBehandeling", body.Status.Tag);
Assert.True(body.Status.Manual);
}
@@ -87,9 +87,9 @@ public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture
public async Task Submit_herregistratie_with_zero_uren_is_afgewezen()
{
var a = await Create("herregistratie");
var res = await _client.PostAsJsonAsync($"/api/v1/applications/{a.Id}/submit", new { uren = 0 });
var res = await _client.PostAsJsonAsync($"/api/v1/aanvragen/{a.Id}/submit", new { uren = 0 });
res.EnsureSuccessStatusCode(); // the submission is accepted...
var body = (await res.Content.ReadFromJsonAsync<SubmitApplicationResponse>())!;
var body = (await res.Content.ReadFromJsonAsync<AanvraagIndienenResponse>())!;
Assert.Equal("Afgewezen", body.Status.Tag); // ...but resolves to rejected
Assert.NotNull(body.Status.Reden);
}
@@ -98,8 +98,8 @@ public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture
public async Task Submitting_twice_conflicts()
{
var a = await Create("registratie");
(await _client.PostAsJsonAsync($"/api/v1/applications/{a.Id}/submit", new { diplomaHerkomst = "duo" })).EnsureSuccessStatusCode();
var again = await _client.PostAsJsonAsync($"/api/v1/applications/{a.Id}/submit", new { diplomaHerkomst = "duo" });
(await _client.PostAsJsonAsync($"/api/v1/aanvragen/{a.Id}/submit", new { diplomaHerkomst = "duo" })).EnsureSuccessStatusCode();
var again = await _client.PostAsJsonAsync($"/api/v1/aanvragen/{a.Id}/submit", new { diplomaHerkomst = "duo" });
Assert.Equal(HttpStatusCode.Conflict, again.StatusCode);
}
@@ -109,7 +109,7 @@ public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture
public async Task Creating_a_second_concept_of_the_same_type_conflicts()
{
await Create("herregistratie");
var dup = await _client.PostAsJsonAsync("/api/v1/applications", new { type = "herregistratie" });
var dup = await _client.PostAsJsonAsync("/api/v1/aanvragen", new { type = "herregistratie" });
Assert.Equal(HttpStatusCode.Conflict, dup.StatusCode);
}
@@ -117,7 +117,7 @@ public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture
public async Task A_concept_of_a_different_type_is_allowed()
{
await Create("registratie");
var other = await _client.PostAsJsonAsync("/api/v1/applications", new { type = "herregistratie" });
var other = await _client.PostAsJsonAsync("/api/v1/aanvragen", new { type = "herregistratie" });
Assert.Equal(HttpStatusCode.Created, other.StatusCode);
}
@@ -125,8 +125,8 @@ public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture
public async Task A_new_concept_is_allowed_once_the_previous_one_is_submitted()
{
var a = await Create("registratie");
(await _client.PostAsJsonAsync($"/api/v1/applications/{a.Id}/submit", new { diplomaHerkomst = "duo" })).EnsureSuccessStatusCode();
var next = await _client.PostAsJsonAsync("/api/v1/applications", new { type = "registratie" });
(await _client.PostAsJsonAsync($"/api/v1/aanvragen/{a.Id}/submit", new { diplomaHerkomst = "duo" })).EnsureSuccessStatusCode();
var next = await _client.PostAsJsonAsync("/api/v1/aanvragen", new { type = "registratie" });
Assert.Equal(HttpStatusCode.Created, next.StatusCode);
}
@@ -134,38 +134,38 @@ public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture
public async Task Cancel_concept_removes_it()
{
var a = await Create();
Assert.Equal(HttpStatusCode.NoContent, (await _client.DeleteAsync($"/api/v1/applications/{a.Id}")).StatusCode);
Assert.Equal(HttpStatusCode.NotFound, (await _client.GetAsync($"/api/v1/applications/{a.Id}")).StatusCode);
Assert.Equal(HttpStatusCode.NoContent, (await _client.DeleteAsync($"/api/v1/aanvragen/{a.Id}")).StatusCode);
Assert.Equal(HttpStatusCode.NotFound, (await _client.GetAsync($"/api/v1/aanvragen/{a.Id}")).StatusCode);
}
[Fact]
public async Task Cancel_submitted_aanvraag_conflicts()
{
var a = await Create("registratie");
(await _client.PostAsJsonAsync($"/api/v1/applications/{a.Id}/submit", new { diplomaHerkomst = "duo" })).EnsureSuccessStatusCode();
Assert.Equal(HttpStatusCode.Conflict, (await _client.DeleteAsync($"/api/v1/applications/{a.Id}")).StatusCode);
(await _client.PostAsJsonAsync($"/api/v1/aanvragen/{a.Id}/submit", new { diplomaHerkomst = "duo" })).EnsureSuccessStatusCode();
Assert.Equal(HttpStatusCode.Conflict, (await _client.DeleteAsync($"/api/v1/aanvragen/{a.Id}")).StatusCode);
}
// --- WP-53: citizen-scoping — GET /applications must never leak across identities. ---
// --- WP-53: citizen-scoping — GET /aanvragen must never leak across identities. ---
[Fact]
public async Task Applications_are_scoped_to_the_caller_bsn()
{
var mine = await Create("intake");
var createOther = new HttpRequestMessage(HttpMethod.Post, "/api/v1/applications")
var createOther = new HttpRequestMessage(HttpMethod.Post, "/api/v1/aanvragen")
{
Content = JsonContent.Create(new { type = "intake" }),
Headers = { { "X-Subject", "999888777" } },
};
var otherRes = await _client.SendAsync(createOther);
Assert.Equal(HttpStatusCode.Created, otherRes.StatusCode);
var other = (await otherRes.Content.ReadFromJsonAsync<ApplicationDetailDto>())!;
var other = (await otherRes.Content.ReadFromJsonAsync<AanvraagDetailDto>())!;
try
{
var listOther = new HttpRequestMessage(HttpMethod.Get, "/api/v1/applications") { Headers = { { "X-Subject", "999888777" } } };
var theirCases = (await (await _client.SendAsync(listOther)).Content.ReadFromJsonAsync<List<ApplicationSummaryDto>>())!;
var listOther = new HttpRequestMessage(HttpMethod.Get, "/api/v1/aanvragen") { Headers = { { "X-Subject", "999888777" } } };
var theirCases = (await (await _client.SendAsync(listOther)).Content.ReadFromJsonAsync<List<AanvraagSummaryDto>>())!;
Assert.Contains(theirCases, c => c.Id == other.Id);
Assert.DoesNotContain(theirCases, c => c.Id == mine.Id);
@@ -175,9 +175,9 @@ public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture
}
finally
{
var deleteOther = new HttpRequestMessage(HttpMethod.Delete, $"/api/v1/applications/{other.Id}") { Headers = { { "X-Subject", "999888777" } } };
var deleteOther = new HttpRequestMessage(HttpMethod.Delete, $"/api/v1/aanvragen/{other.Id}") { Headers = { { "X-Subject", "999888777" } } };
await _client.SendAsync(deleteOther);
await _client.DeleteAsync($"/api/v1/applications/{mine.Id}");
await _client.DeleteAsync($"/api/v1/aanvragen/{mine.Id}");
}
}
@@ -205,7 +205,7 @@ public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture
var foreignDoc = await UploadAs(_client, "999888777", Guid.NewGuid().ToString());
var a = await Create("registratie");
var res = await _client.PostAsJsonAsync($"/api/v1/applications/{a.Id}/submit",
var res = await _client.PostAsJsonAsync($"/api/v1/aanvragen/{a.Id}/submit",
new { diplomaHerkomst = "duo", documents = new[] { new { categoryId = "diploma", channel = "digital", documentId = foreignDoc.DocumentId } } });
Assert.Equal(HttpStatusCode.BadRequest, res.StatusCode);
@@ -221,7 +221,7 @@ public class ApplicationTests(TestWebApplicationFactory factory) : IClassFixture
var foreignDoc = await UploadAs(_client, "999888777", Guid.NewGuid().ToString());
var a = await Create("registratie");
var res = await _client.PutAsJsonAsync($"/api/v1/applications/{a.Id}",
var res = await _client.PutAsJsonAsync($"/api/v1/aanvragen/{a.Id}",
new { draft = new { }, stepIndex = 0, stepCount = 1, documentIds = new[] { foreignDoc.DocumentId } });
Assert.Equal(HttpStatusCode.BadRequest, res.StatusCode);
}
@@ -9,7 +9,7 @@ namespace BigRegister.Tests.Acceptance;
/// <summary>
/// Behaviour-level tests for the scholing-threshold enforcement (WP-69) over
/// <c>POST /applications/{id}/submit</c> (the wizard's real path — WP-72 deleted the legacy
/// <c>POST /aanvragen/{id}/submit</c> (the wizard's real path — WP-72 deleted the legacy
/// <c>POST /intakes</c> endpoint this once also covered). Built through the <see
/// cref="Given"/> type-state builder, mirroring <see cref="BesluitLifecycleTests"/> rather
/// than the full wizard/upload dance — the builder's default owner IS <see
@@ -28,7 +28,7 @@ public class IntakeSubmissionTests(TestWebApplicationFactory factory) : IClassFi
}
private Task<HttpResponseMessage> Submit(string id, object body) =>
_client.PostAsJsonAsync($"/api/v1/applications/{id}/submit", body);
_client.PostAsJsonAsync($"/api/v1/aanvragen/{id}/submit", body);
[Fact]
public async Task Below_threshold_without_an_answer_is_rejected_and_stays_a_concept()
@@ -117,7 +117,7 @@ public class IntakeSubmissionTests(TestWebApplicationFactory factory) : IClassFi
// Then the submission is accepted and resolves to Afgewezen — not a 400.
res.EnsureSuccessStatusCode();
var body = (await res.Content.ReadFromJsonAsync<SubmitApplicationResponse>())!;
var body = (await res.Content.ReadFromJsonAsync<AanvraagIndienenResponse>())!;
Assert.Equal("Afgewezen", body.Status.Tag);
}
}
@@ -18,11 +18,11 @@ public class AdminCasesTests(TestWebApplicationFactory factory) : IClassFixture<
return req;
}
private async Task<ApplicationDetailDto> Create(string type)
private async Task<AanvraagDetailDto> Create(string type)
{
var res = await _client.PostAsJsonAsync("/api/v1/applications", new { type });
var res = await _client.PostAsJsonAsync("/api/v1/aanvragen", new { type });
Assert.Equal(HttpStatusCode.Created, res.StatusCode);
return (await res.Content.ReadFromJsonAsync<ApplicationDetailDto>())!;
return (await res.Content.ReadFromJsonAsync<AanvraagDetailDto>())!;
}
[Fact]
@@ -33,7 +33,7 @@ public class AdminCasesTests(TestWebApplicationFactory factory) : IClassFixture<
{
var list = await _client.SendAsync(Admin(HttpMethod.Get, "/api/v1/admin/cases"));
list.EnsureSuccessStatusCode();
var cases = (await list.Content.ReadFromJsonAsync<List<ApplicationSummaryDto>>())!;
var cases = (await list.Content.ReadFromJsonAsync<List<AanvraagSummaryDto>>())!;
var mine = cases.Single(x => x.Id == a.Id);
// RB-03/BIO-003: the owner is carried, but masked — it is a BSN, and this list is
// read by someone who is not the subject.
@@ -57,13 +57,13 @@ public class AdminCasesTests(TestWebApplicationFactory factory) : IClassFixture<
public async Task Admin_can_delete_a_submitted_case()
{
var a = await Create("registratie");
(await _client.PostAsJsonAsync($"/api/v1/applications/{a.Id}/submit", new { diplomaHerkomst = "duo" }))
(await _client.PostAsJsonAsync($"/api/v1/aanvragen/{a.Id}/submit", new { diplomaHerkomst = "duo" }))
.EnsureSuccessStatusCode();
// The user-facing DELETE refuses a submitted case (409); admin delete removes it.
var del = await _client.SendAsync(Admin(HttpMethod.Delete, $"/api/v1/admin/cases/{a.Id}"));
Assert.Equal(HttpStatusCode.NoContent, del.StatusCode);
Assert.Equal(HttpStatusCode.NotFound, (await _client.GetAsync($"/api/v1/applications/{a.Id}")).StatusCode);
Assert.Equal(HttpStatusCode.NotFound, (await _client.GetAsync($"/api/v1/aanvragen/{a.Id}")).StatusCode);
}
[Fact]
@@ -17,12 +17,12 @@ namespace BigRegister.Tests;
file sealed class IdMismatchZaakSource : IZaakSource
{
private readonly LocalZaakSource inner = new();
private static ApplicationSummaryDto Rekey(ApplicationSummaryDto dto) => dto with { Id = $"zaak-{dto.Id}" };
private static AanvraagSummaryDto Rekey(AanvraagSummaryDto dto) => dto with { Id = $"zaak-{dto.Id}" };
public IReadOnlyList<ApplicationSummaryDto> ListCases(DateTimeOffset now) =>
public IReadOnlyList<AanvraagSummaryDto> ListCases(DateTimeOffset now) =>
inner.ListCases(now).Select(Rekey).ToList();
public IReadOnlyList<ApplicationSummaryDto> ListMyCases(ZorgverlenerCaller caller, DateTimeOffset now) =>
public IReadOnlyList<AanvraagSummaryDto> ListMyCases(ZorgverlenerCaller caller, DateTimeOffset now) =>
inner.ListMyCases(caller, now).Select(Rekey).ToList();
public (string Referentie, AanvraagStatusDto Status, string? ZaakUrl) CreateZaak(
@@ -67,13 +67,13 @@ public class BeoordelingIdMismatchTests
using var factory = Factory();
using var client = factory.CreateClient();
var created = await client.PostAsJsonAsync("/api/v1/applications", new { type = "registratie" });
var app = (await created.Content.ReadFromJsonAsync<ApplicationDetailDto>())!;
var submit = await client.PostAsJsonAsync($"/api/v1/applications/{app.Id}/submit", new { diplomaHerkomst = "handmatig" });
var created = await client.PostAsJsonAsync("/api/v1/aanvragen", new { type = "registratie" });
var app = (await created.Content.ReadFromJsonAsync<AanvraagDetailDto>())!;
var submit = await client.PostAsJsonAsync($"/api/v1/aanvragen/{app.Id}/submit", new { diplomaHerkomst = "handmatig" });
submit.EnsureSuccessStatusCode();
var werkvoorraad = await client.SendAsync(Behandelaar(HttpMethod.Get, "/api/v1/werkvoorraad"));
var items = (await werkvoorraad.Content.ReadFromJsonAsync<List<ApplicationSummaryDto>>())!;
var items = (await werkvoorraad.Content.ReadFromJsonAsync<List<AanvraagSummaryDto>>())!;
var caseId = Assert.Single(items).Id;
// Sanity: the id divergence this test exists for is real, not accidentally absent.
Assert.NotEqual(app.Id, caseId);
@@ -35,17 +35,17 @@ public class BeoordelingTests(TestWebApplicationFactory factory) : IClassFixture
/// A manual (never auto-approved) case with one linked document, so it stays
/// InBehandeling/decidable regardless of test timing (the 8s auto-approval window
/// would otherwise make a duo-registratie/herregistratie fixture flaky).
private async Task<(ApplicationDetailDto App, string DocumentId)> CreateManualCaseWithDocument()
private async Task<(AanvraagDetailDto App, string DocumentId)> CreateManualCaseWithDocument()
{
var created = await _client.PostAsJsonAsync("/api/v1/applications", new { type = "registratie" });
var a = (await created.Content.ReadFromJsonAsync<ApplicationDetailDto>())!;
var created = await _client.PostAsJsonAsync("/api/v1/aanvragen", new { type = "registratie" });
var a = (await created.Content.ReadFromJsonAsync<AanvraagDetailDto>())!;
var localId = Guid.NewGuid().ToString();
var upload = await _client.PostAsync("/api/v1/uploads", UploadForm(localId, "diploma", "diploma.pdf"));
upload.EnsureSuccessStatusCode();
var doc = (await upload.Content.ReadFromJsonAsync<UploadResponse>())!;
var submit = await _client.PostAsJsonAsync($"/api/v1/applications/{a.Id}/submit", new
var submit = await _client.PostAsJsonAsync($"/api/v1/aanvragen/{a.Id}/submit", new
{
diplomaHerkomst = "handmatig",
documents = new[] { new { categoryId = "diploma", channel = "digital", documentId = doc.DocumentId } },
@@ -88,8 +88,8 @@ public class BeoordelingTests(TestWebApplicationFactory factory) : IClassFixture
[Fact]
public async Task Concept_and_unknown_id_are_not_found()
{
var created = await _client.PostAsJsonAsync("/api/v1/applications", new { type = "registratie" });
var concept = (await created.Content.ReadFromJsonAsync<ApplicationDetailDto>())!;
var created = await _client.PostAsJsonAsync("/api/v1/aanvragen", new { type = "registratie" });
var concept = (await created.Content.ReadFromJsonAsync<AanvraagDetailDto>())!;
try
{
var conceptRes = await _client.SendAsync(AsBehandelaar(HttpMethod.Get, $"/api/v1/beoordeling/{concept.Id}"));
@@ -100,7 +100,7 @@ public class BeoordelingTests(TestWebApplicationFactory factory) : IClassFixture
}
finally
{
await _client.DeleteAsync($"/api/v1/applications/{concept.Id}");
await _client.DeleteAsync($"/api/v1/aanvragen/{concept.Id}");
}
}
@@ -202,9 +202,9 @@ public class EndpointTests(TestWebApplicationFactory factory) : IClassFixture<Te
var doc = await Upload(Guid.NewGuid().ToString());
// Through the real submit path (RB-06 deleted POST /registrations, which was the only
// other caller of DocumentStore.Link and had no ownership guard on it).
var created = await _client.PostAsJsonAsync("/api/v1/applications", new { type = "registratie" });
var aanvraag = (await created.Content.ReadFromJsonAsync<ApplicationDetailDto>())!;
var submit = await _client.PostAsJsonAsync($"/api/v1/applications/{aanvraag.Id}/submit",
var created = await _client.PostAsJsonAsync("/api/v1/aanvragen", new { type = "registratie" });
var aanvraag = (await created.Content.ReadFromJsonAsync<AanvraagDetailDto>())!;
var submit = await _client.PostAsJsonAsync($"/api/v1/aanvragen/{aanvraag.Id}/submit",
new { diplomaHerkomst = "duo", documents = new[] { new DocumentRefDto("diploma", "digital", doc.DocumentId) } });
submit.EnsureSuccessStatusCode();
Assert.Equal(HttpStatusCode.Conflict, (await _client.DeleteAsync($"/api/v1/uploads/{doc.DocumentId}")).StatusCode);
@@ -51,16 +51,16 @@ public class FeatureFlagTests(TestWebApplicationFactory factory) : IClassFixture
{
try
{
// Off → POST /applications for a registratie is refused.
// Off → POST /aanvragen for a registratie is refused.
(await _client.SendAsync(Admin(HttpMethod.Put, $"/api/v1/admin/flags/{FeatureFlags.InschrijvingOpen}", new { enabled = false })))
.EnsureSuccessStatusCode();
var blocked = await _client.PostAsJsonAsync("/api/v1/applications", new { type = "registratie" });
var blocked = await _client.PostAsJsonAsync("/api/v1/aanvragen", new { type = "registratie" });
Assert.Equal(HttpStatusCode.Forbidden, blocked.StatusCode);
// On → allowed again.
(await _client.SendAsync(Admin(HttpMethod.Put, $"/api/v1/admin/flags/{FeatureFlags.InschrijvingOpen}", new { enabled = true })))
.EnsureSuccessStatusCode();
var ok = await _client.PostAsJsonAsync("/api/v1/applications", new { type = "registratie" });
var ok = await _client.PostAsJsonAsync("/api/v1/aanvragen", new { type = "registratie" });
Assert.Equal(HttpStatusCode.Created, ok.StatusCode);
}
finally
@@ -63,7 +63,7 @@ public class OpenZaakIntegrationTests
using var client = factory.CreateClient();
client.DefaultRequestHeaders.Add("X-Role", "admin"); // CasesAdmin gate (cases:manage)
var cases = await client.GetFromJsonAsync<List<ApplicationSummaryDto>>("/api/v1/admin/cases");
var cases = await client.GetFromJsonAsync<List<AanvraagSummaryDto>>("/api/v1/admin/cases");
Assert.NotNull(cases);
// bootstrap-catalogus.sh seeds exactly one zaak, identificatie BIG-2026-000123.
@@ -17,7 +17,7 @@ namespace BigRegister.Tests;
/// - it is named, with a reason, in <see cref="AllowList"/> below.
///
/// The allow-list is deliberately not "public routes" — most of its entries are NOT public.
/// `GET /applications/{id}` requires a caller identity and is scoped to that caller's own BSN
/// `GET /aanvragen/{id}` requires a caller identity and is scoped to that caller's own BSN
/// inline (`ctx.Zorgverlener()`), not through one of the five wrappers, which only gate the
/// coarse admin/behandelaar surfaces. Recording that here, with the actual reason, is the point
/// of BIO-016's remediation ("makes 'this endpoint is public' a decision someone wrote down")
@@ -58,12 +58,12 @@ public class RouteInventoryTests(TestWebApplicationFactory factory) : IClassFixt
new("GET", "/api/v1/uploads/{documentId}/content", "Ownership-scoped inline (RB-01/BIO-004): owning citizen, or a behandelaar via Authz.CanBeoordelen."),
new("GET", "/api/v1/uploads/status", "Ownership-scoped inline: DocumentStore.ByLocalIds filtered to ctx.Zorgverlener().Bsn."),
new("DELETE", "/api/v1/uploads/{documentId}", "Ownership-scoped inline: DocumentStore.DeleteOwned keyed by ctx.Zorgverlener().Bsn."),
new("GET", "/api/v1/applications", "Ownership-scoped inline: IZaakSource.ListMyCases(ctx.Zorgverlener(), ...)."),
new("GET", "/api/v1/applications/{id}", "Ownership-scoped inline: ApplicationStore.Get(id, ctx.Zorgverlener().Bsn)."),
new("POST", "/api/v1/applications", "Ownership-scoped inline: created under ctx.Zorgverlener().Bsn."),
new("PUT", "/api/v1/applications/{id}", "Ownership-scoped inline: ApplicationStore.SyncDraft keyed by ctx.Zorgverlener().Bsn."),
new("DELETE", "/api/v1/applications/{id}", "Ownership-scoped inline: ApplicationStore.Get/.Delete keyed by ctx.Zorgverlener().Bsn."),
new("POST", "/api/v1/applications/{id}/submit", "Ownership-scoped inline: ApplicationStore.Submit keyed by ctx.Zorgverlener().Bsn."),
new("GET", "/api/v1/aanvragen", "Ownership-scoped inline: IZaakSource.ListMyCases(ctx.Zorgverlener(), ...)."),
new("GET", "/api/v1/aanvragen/{id}", "Ownership-scoped inline: ApplicationStore.Get(id, ctx.Zorgverlener().Bsn)."),
new("POST", "/api/v1/aanvragen", "Ownership-scoped inline: created under ctx.Zorgverlener().Bsn."),
new("PUT", "/api/v1/aanvragen/{id}", "Ownership-scoped inline: ApplicationStore.SyncDraft keyed by ctx.Zorgverlener().Bsn."),
new("DELETE", "/api/v1/aanvragen/{id}", "Ownership-scoped inline: ApplicationStore.Get/.Delete keyed by ctx.Zorgverlener().Bsn."),
new("POST", "/api/v1/aanvragen/{id}/submit", "Ownership-scoped inline: ApplicationStore.Submit keyed by ctx.Zorgverlener().Bsn."),
// --- External caller, not a Principal at all. ---
new("POST", "/api/v1/zgw/notificaties", "OpenZaak's NRC, not a user: gated by a fixed-time shared-secret comparison, audited directly."),
@@ -18,11 +18,11 @@ public class WerkvoorraadTests(TestWebApplicationFactory factory) : IClassFixtur
return req;
}
private async Task<ApplicationDetailDto> CreateAndSubmitHerregistratie()
private async Task<AanvraagDetailDto> CreateAndSubmitHerregistratie()
{
var created = await _client.PostAsJsonAsync("/api/v1/applications", new { type = "herregistratie" });
var a = (await created.Content.ReadFromJsonAsync<ApplicationDetailDto>())!;
(await _client.PostAsJsonAsync($"/api/v1/applications/{a.Id}/submit", new { uren = 200 }))
var created = await _client.PostAsJsonAsync("/api/v1/aanvragen", new { type = "herregistratie" });
var a = (await created.Content.ReadFromJsonAsync<AanvraagDetailDto>())!;
(await _client.PostAsJsonAsync($"/api/v1/aanvragen/{a.Id}/submit", new { uren = 200 }))
.EnsureSuccessStatusCode();
return a;
}
@@ -35,7 +35,7 @@ public class WerkvoorraadTests(TestWebApplicationFactory factory) : IClassFixtur
{
var res = await _client.SendAsync(AsBehandelaar("/api/v1/werkvoorraad"));
res.EnsureSuccessStatusCode();
var queue = (await res.Content.ReadFromJsonAsync<List<ApplicationSummaryDto>>())!;
var queue = (await res.Content.ReadFromJsonAsync<List<AanvraagSummaryDto>>())!;
var mine = queue.Single(x => x.Id == a.Id);
Assert.Equal("InBehandeling", mine.Status.Tag);
// RB-03/BIO-003: masked, like /admin/cases — both inherit ToAdminSummaryDto.
@@ -53,18 +53,18 @@ public class WerkvoorraadTests(TestWebApplicationFactory factory) : IClassFixtur
[Fact]
public async Task Queue_excludes_concepts()
{
var created = await _client.PostAsJsonAsync("/api/v1/applications", new { type = "herregistratie" });
var a = (await created.Content.ReadFromJsonAsync<ApplicationDetailDto>())!;
var created = await _client.PostAsJsonAsync("/api/v1/aanvragen", new { type = "herregistratie" });
var a = (await created.Content.ReadFromJsonAsync<AanvraagDetailDto>())!;
try
{
var res = await _client.SendAsync(AsBehandelaar("/api/v1/werkvoorraad"));
res.EnsureSuccessStatusCode();
var queue = (await res.Content.ReadFromJsonAsync<List<ApplicationSummaryDto>>())!;
var queue = (await res.Content.ReadFromJsonAsync<List<AanvraagSummaryDto>>())!;
Assert.DoesNotContain(queue, x => x.Id == a.Id);
}
finally
{
await _client.DeleteAsync($"/api/v1/applications/{a.Id}");
await _client.DeleteAsync($"/api/v1/aanvragen/{a.Id}");
}
}
@@ -39,14 +39,14 @@ public class ZgwDivergenceTests
b.ConfigurePrimaryHttpMessageHandler(() => stub))));
}
/// <summary>Doesn't call GET /applications first (unlike ApplicationTests.Create) — under
/// <summary>Doesn't call GET /aanvragen first (unlike ApplicationTests.Create) — under
/// Zgw:Enabled=true that route goes through IZaakSource too, which this test's stub doesn't
/// need to answer since every test here uses a fresh db and creates exactly one aanvraag.</summary>
private static async Task<string> CreateConcept(HttpClient client, string type = "registratie")
{
var res = await client.PostAsJsonAsync("/api/v1/applications", new { type });
var res = await client.PostAsJsonAsync("/api/v1/aanvragen", new { type });
res.EnsureSuccessStatusCode();
var body = (await res.Content.ReadFromJsonAsync<ApplicationDetailDto>())!;
var body = (await res.Content.ReadFromJsonAsync<AanvraagDetailDto>())!;
return body.Id;
}
@@ -78,11 +78,11 @@ public class ZgwDivergenceTests
using var client = factory.CreateClient();
var id = await CreateConcept(client);
var res = await client.PostAsJsonAsync($"/api/v1/applications/{id}/submit", new { diplomaHerkomst = "duo" });
var res = await client.PostAsJsonAsync($"/api/v1/aanvragen/{id}/submit", new { diplomaHerkomst = "duo" });
// The local write is still authoritative: 200 with a real reference, not a 500.
res.EnsureSuccessStatusCode();
var body = (await res.Content.ReadFromJsonAsync<SubmitApplicationResponse>())!;
var body = (await res.Content.ReadFromJsonAsync<AanvraagIndienenResponse>())!;
Assert.NotEmpty(body.Referentie);
var stored = ApplicationStore.ListAll().Single(a => a.Id == id);
@@ -103,7 +103,7 @@ public class ZgwDivergenceTests
using var client = factory.CreateClient();
var id = await CreateConcept(client);
var res = await client.PostAsJsonAsync($"/api/v1/applications/{id}/submit", new { diplomaHerkomst = "duo" });
var res = await client.PostAsJsonAsync($"/api/v1/aanvragen/{id}/submit", new { diplomaHerkomst = "duo" });
res.EnsureSuccessStatusCode();
var stored = ApplicationStore.ListAll().Single(a => a.Id == id);
@@ -126,7 +126,7 @@ public class ZgwDivergenceTests
using var client = factory.CreateClient();
var id = await CreateConcept(client);
(await client.PostAsJsonAsync($"/api/v1/applications/{id}/submit", new { diplomaHerkomst = "duo" }))
(await client.PostAsJsonAsync($"/api/v1/aanvragen/{id}/submit", new { diplomaHerkomst = "duo" }))
.EnsureSuccessStatusCode();
var error = ApplicationStore.ListAll().Single(a => a.Id == id).ZgwError;