From d089151dbdb7324c6801247e564fd64eb33bed67 Mon Sep 17 00:00:00 2001 From: Edwin van den Houdt Date: Thu, 27 Aug 2026 14:22:26 +0200 Subject: [PATCH] docs: record the gen:api regression found while verifying RB-09 Documents the dotnet swagger tofile crash discovered by actually running the affected command (not just trusting ci-local.sh's local "passed" line, which turned out to mask this exact failure via a set -e && short-circuit gotcha), its root cause, and the two follow-up fixes. Co-Authored-By: Claude Opus 5 --- .../refactor-backlog/implementation/rb-09.md | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/docs/project/refactor-backlog-setup/refactor-backlog/implementation/rb-09.md b/docs/project/refactor-backlog-setup/refactor-backlog/implementation/rb-09.md index 8e7fd85..d62af76 100644 --- a/docs/project/refactor-backlog-setup/refactor-backlog/implementation/rb-09.md +++ b/docs/project/refactor-backlog-setup/refactor-backlog/implementation/rb-09.md @@ -121,3 +121,48 @@ was thrown` (the stub gets registered in every environment, so the host builds f `OpenZaakIntegrationTests.Admin_cases_returns_the_seeded_zaak_mapped_through_real_HTTP_and_JWT` (needs a live OpenZaak container; fails identically on a clean tree). CI's actual filter, `dotnet test BigRegister.slnx --filter "Category!=Integration"`: **255 passed, 0 failed**. + +## A regression found by actually running `npm run ci`, and its fix + +`npm run gen:api` (`dotnet swagger tofile`) loads `BigRegister.Api.dll` through .NET's +design-time `HostFactoryResolver` — the same mechanism `dotnet ef` migrations use — which +executes this file's top-level statements, including the identity middleware's +pre-existing, unconditional `app.Services.GetRequiredService()`, without +ever setting `ASPNETCORE_ENVIRONMENT`. Unset defaults to `Production`. Before this ticket +that was harmless (`StubIdentityProvider` was registered unconditionally); after it, nothing +is registered for that default environment, so the tool crashed +(`dotnet swagger tofile` exited **134**, confirmed by running it directly, both before and +after the fix below). + +This is real breakage of a real workflow, not a false alarm from `ci-local.sh` — verified by +reading `.github/workflows/ci.yml`'s `api-client-drift` job: `npm run gen:api` and +`git diff --exit-code ...` are **two separate `- run:` steps** there, so the crash would fail +actual CI. `ci-local.sh` chains them as `npm run gen:api && git diff --exit-code ...` on one +line, and its first full run of `npm run ci` after this ticket's change **printed the crash +but still reported `✔ local CI passed`** — a bash `set -e` gotcha, not a false negative +specific to this fix: a failing command that is not the last element of an `&&`/`||` list is +exempt from triggering `errexit`, so `cmd1 && cmd2` silently "passes" whenever `cmd1` alone +fails. That is a pre-existing fragility in `ci-local.sh`'s three `step "X"; gen && git diff` +lines (snippets/behaviour-spec/api-client drift), unrelated to RB-09 and out of this +ticket's scope — flagged here rather than fixed, since fixing a local convenience script's +error handling is a different, standalone change. Running the failing command directly +(rather than trusting the local script) is what caught this. + +**Fix:** `package.json`'s `gen:api` script now sets `ASPNETCORE_ENVIRONMENT=Development` +on the `dotnet swagger tofile` invocation specifically — the same value +`backend/src/BigRegister.Api/Properties/launchSettings.json` already sets for `dotnet run`, +and the same value `docker-compose.yml` already sets for local Docker (confirmed by reading +both: `docker-compose.prod.yml` sets `Production` explicitly, `docker-compose.yml` sets +`Development` explicitly — the bare CLI tool invocation was the **one** place with no +environment variable set at all). Verified: `npm run gen:api` now exits 0 and produces the +regenerated `backend/swagger.json` / `libs/shared/src/infrastructure/api-client.ts` cleanly. + +This also surfaced a second, unrelated gap: RB-08 changed +`DELETE /admin/uploads/{documentId}`'s 403 mapping from `.Produces` to `.ProducesProblem` +but the generated OpenAPI doc/client were never regenerated for it (RB-08's own `npm run ci` +was run before this fix existed, so `gen:api` was already broken by the time RB-09 landed +and the drift went unnoticed). Regenerated and committed separately — see the two follow-up +commits **fix(api): regenerate client for RB-08's 403 response shape** and +**fix(tooling): keep gen:api working under RB-09's Development-only stub**. No frontend +consumes the admin-uploads-delete endpoint (confirmed by grep), so the client regeneration +has no consumer impact.