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 <noreply@anthropic.com>
This commit is contained in:
eho
2026-08-27 14:22:26 +02:00
co-authored by Claude Opus 5
parent 436e18421b
commit d089151dbd
@@ -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<IIdentityProvider>()`, 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.