feat(admin): runtime feature flags (catalog-in-code, admin toggle, FE+backend)

Catalog declared in code (Domain/Features/FeatureFlags.cs, build-validated), on/off state
persisted in SQLite (FeatureFlagStore + migration). GET /flags (drives FE gating) + admin
PUT /admin/flags/{key} (new flags:manage capability + FlagsAdmin gate). Enforced end-to-end:
the `inschrijving-open` flag hides the Inschrijven nav item + dashboard action (FE) AND makes
POST /applications for a registratie 403 when off (backend). FE FeatureFlagStore mirrors
AccessStore (enabled() deny-by-default); admin toggle page at /beheer/functies in ADMIN_LINKS.
+4 backend tests, /me cap-list updated, client regenerated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
eho
2026-07-23 22:29:48 +02:00
co-authored by Claude Opus 4.8
parent ed264be714
commit 67802c68b4
28 changed files with 1154 additions and 52 deletions
+93
View File
@@ -852,6 +852,73 @@
}
}
},
"/api/v1/flags": {
"get": {
"tags": [
"BigRegister.Api, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/FeatureFlagDto"
}
}
}
}
}
}
}
},
"/api/v1/admin/flags/{key}": {
"put": {
"tags": [
"BigRegister.Api, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
],
"parameters": [
{
"name": "key",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SetFeatureFlagRequest"
}
}
},
"required": true
},
"responses": {
"204": {
"description": "No Content"
},
"404": {
"description": "Not Found"
},
"403": {
"description": "Forbidden",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
}
}
},
"/api/v1/brief": {
"get": {
"tags": [
@@ -1830,6 +1897,23 @@
},
"additionalProperties": false
},
"FeatureFlagDto": {
"type": "object",
"properties": {
"key": {
"type": "string",
"nullable": true
},
"description": {
"type": "string",
"nullable": true
},
"enabled": {
"type": "boolean"
}
},
"additionalProperties": false
},
"HerregistratieDecisionsDto": {
"type": "object",
"properties": {
@@ -2396,6 +2480,15 @@
},
"additionalProperties": false
},
"SetFeatureFlagRequest": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
}
},
"additionalProperties": false
},
"StamdataColumnDto": {
"type": "object",
"properties": {