feat(stamdata): admin stamdata maintenance editor (beheer)

Realizes ADR-0004's "future low-code editor that commits a PR": an
admin-only stamdata maintenance editor built on the stamdata-as-code
foundation.

Backend: `professions` moves from a hardcoded C# dictionary to an embedded
`professions.json` data-file (typed as `ProfessionMapping`) with valid-time
(geldigVan/geldigTot, half-open). A generic, reflection-driven
StamdataCatalog/StamdataTable/StamdataFile describes every table so one
endpoint pair + one grid editor serve all of them; add a table in one line.
Two read-only, admin-gated endpoints (GET /stamdata, GET /stamdata/{table}
?peildatum=) — no runtime write path. Generic build gate
`Every_catalog_table_is_valid` (keys non-blank, no overlapping validity,
well-formed windows).

Frontend: new `beheer` context (route beheer/stamdata, capabilityGuard
'stamdata:edit'). A schema-driven grid editor edits rows locally; download()
emits {table}.json for the admin to commit as a reviewed PR (no mutation
command — the CI build + StamdataValidationTests stay the authority).

Full gate GREEN both sides; gen:api leaves no drift; new stamdata story
passes axe. See WP-29 + ADR-0004.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
eho
2026-07-21 13:43:51 +02:00
co-authored by Claude Opus 4.8
parent c459fa0a60
commit 0e77faf351
32 changed files with 7822 additions and 2284 deletions
+160
View File
@@ -127,6 +127,89 @@
}
}
},
"/api/v1/stamdata": {
"get": {
"tags": [
"BigRegister.Api, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
],
"operationId": "stamdataTables",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/StamdataTableSummaryDto"
}
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
}
}
},
"/api/v1/stamdata/{table}": {
"get": {
"tags": [
"BigRegister.Api, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
],
"operationId": "stamdataTable",
"parameters": [
{
"name": "table",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "peildatum",
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/StamdataTableDto"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
},
"404": {
"description": "Not Found"
}
}
}
},
"/api/v1/registrations": {
"post": {
"tags": [
@@ -2178,6 +2261,83 @@
},
"additionalProperties": false
},
"StamdataColumnDto": {
"type": "object",
"properties": {
"name": {
"type": "string",
"nullable": true
},
"type": {
"type": "string",
"nullable": true
},
"isKey": {
"type": "boolean"
},
"options": {
"type": "array",
"items": {
"type": "string"
},
"nullable": true
}
},
"additionalProperties": false
},
"StamdataTableDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"nullable": true
},
"label": {
"type": "string",
"nullable": true
},
"columns": {
"type": "array",
"items": {
"$ref": "#/components/schemas/StamdataColumnDto"
},
"nullable": true
},
"temporal": {
"type": "boolean"
},
"rows": {
"type": "array",
"items": { },
"nullable": true
}
},
"additionalProperties": false
},
"StamdataTableSummaryDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"nullable": true
},
"label": {
"type": "string",
"nullable": true
},
"columns": {
"type": "array",
"items": {
"$ref": "#/components/schemas/StamdataColumnDto"
},
"nullable": true
},
"temporal": {
"type": "boolean"
}
},
"additionalProperties": false
},
"SubOrgSummaryDto": {
"type": "object",
"properties": {