diff --git a/backend/src/BigRegister.Api/Domain/Diplomas/DiplomaRules.cs b/backend/src/BigRegister.Api/Domain/Diplomas/DiplomaRules.cs
index cc2a2bc..effe9b8 100644
--- a/backend/src/BigRegister.Api/Domain/Diplomas/DiplomaRules.cs
+++ b/backend/src/BigRegister.Api/Domain/Diplomas/DiplomaRules.cs
@@ -19,44 +19,20 @@ public static class DiplomaRules
/// Professions a user may declare for a manual (unlisted) diploma.
public static IReadOnlyList ManualProfessions() => Professions.All();
- // --- Policy questions (geldigheidsvragen) ---
-
- private static readonly PolicyQuestion NlTaalEngelstalig = new(
- "nl-taalvaardigheid",
- "Uw opleiding was Engelstalig. Beheerst u de Nederlandse taal op het vereiste niveau (B2)?",
- QuestionType.JaNee);
-
- private static readonly PolicyQuestion NlTaalManual = new(
- "nl-taalvaardigheid",
- "Beheerst u de Nederlandse taal op het vereiste niveau (B2)?",
- QuestionType.JaNee);
-
- private static readonly PolicyQuestion DiplomaErkend = new(
- "diploma-erkend",
- "Is uw diploma erkend door de Nederlandse overheid (bijv. via Nuffic)?",
- QuestionType.JaNee);
-
- private static readonly PolicyQuestion Toelichting = new(
- "toelichting",
- "Geef een korte toelichting op uw diploma en opleiding.",
- QuestionType.Tekst);
-
///
- /// RULE: an English-language diploma requires proof of Dutch proficiency (B2).
- /// Add a question here to apply it to a (set of) diploma(s) — a single backend
- /// change, no frontend change.
+ /// RULE: an English-language diploma requires proof of Dutch proficiency (B2). Which
+ /// question applies is the rule; its wording is stamdata in .
///
public static IReadOnlyList QuestionsFor(Diploma d)
{
var questions = new List();
if (d.Engelstalig)
- questions.Add(NlTaalEngelstalig);
+ questions.Add(PolicyQuestions.NlTaalEngelstalig);
return questions;
}
///
/// RULE: a manual diploma is unverified, so the strictest (maximal) set applies.
///
- public static IReadOnlyList ManualQuestions() =>
- new[] { NlTaalManual, DiplomaErkend, Toelichting };
+ public static IReadOnlyList ManualQuestions() => PolicyQuestions.ManualSet;
}
diff --git a/backend/src/BigRegister.Api/Stamdata/PolicyQuestions.cs b/backend/src/BigRegister.Api/Stamdata/PolicyQuestions.cs
new file mode 100644
index 0000000..f496fd9
--- /dev/null
+++ b/backend/src/BigRegister.Api/Stamdata/PolicyQuestions.cs
@@ -0,0 +1,45 @@
+using BigRegister.Domain.Diplomas;
+
+namespace BigRegister.Stamdata;
+
+///
+/// BUSINESS-EDITABLE STAMDATA (config-as-code). The geldigheidsvragen (policy questions)
+/// shown for a diploma, and their exact wording. This is the text the business tunes.
+///
+/// Change it by editing this file and opening a PR — NOT via a production database. The
+/// compiler catches shape/type mistakes; StamdataValidationTests catches the rest
+/// (blank ids/wording, duplicate ids). See ADR-0004.
+///
+/// This is DATA, not logic: WHICH questions apply to which diploma (English → B2, manual →
+/// maximal set) is a rule and stays in DiplomaRules.
+///
+public static class PolicyQuestions
+{
+ public static readonly PolicyQuestion NlTaalEngelstalig = new(
+ "nl-taalvaardigheid",
+ "Uw opleiding was Engelstalig. Beheerst u de Nederlandse taal op het vereiste niveau (B2)?",
+ QuestionType.JaNee);
+
+ public static readonly PolicyQuestion NlTaalManual = new(
+ "nl-taalvaardigheid",
+ "Beheerst u de Nederlandse taal op het vereiste niveau (B2)?",
+ QuestionType.JaNee);
+
+ public static readonly PolicyQuestion DiplomaErkend = new(
+ "diploma-erkend",
+ "Is uw diploma erkend door de Nederlandse overheid (bijv. via Nuffic)?",
+ QuestionType.JaNee);
+
+ public static readonly PolicyQuestion Toelichting = new(
+ "toelichting",
+ "Geef een korte toelichting op uw diploma en opleiding.",
+ QuestionType.Tekst);
+
+ /// The maximal set applied to an unverified (manual) diploma.
+ public static readonly IReadOnlyList ManualSet =
+ new[] { NlTaalManual, DiplomaErkend, Toelichting };
+
+ /// Every question defined here — used by the stamdata validation gate.
+ public static readonly IReadOnlyList All =
+ new[] { NlTaalEngelstalig, NlTaalManual, DiplomaErkend, Toelichting };
+}
diff --git a/backend/tests/BigRegister.Tests/StamdataValidationTests.cs b/backend/tests/BigRegister.Tests/StamdataValidationTests.cs
index aa927f7..6b440f5 100644
--- a/backend/tests/BigRegister.Tests/StamdataValidationTests.cs
+++ b/backend/tests/BigRegister.Tests/StamdataValidationTests.cs
@@ -38,4 +38,21 @@ public class StamdataValidationTests
Assert.NotEmpty(professions);
Assert.Equal(professions.Count, professions.Distinct().Count());
}
+
+ [Fact]
+ public void Every_policy_question_has_an_id_and_wording()
+ {
+ Assert.All(PolicyQuestions.All, q =>
+ {
+ Assert.False(string.IsNullOrWhiteSpace(q.Id), "A policy question has a blank id.");
+ Assert.False(string.IsNullOrWhiteSpace(q.Vraag), $"Policy question '{q.Id}' has blank wording.");
+ });
+ }
+
+ [Fact]
+ public void Manual_question_set_has_distinct_ids() // no field is asked twice
+ {
+ var ids = PolicyQuestions.ManualSet.Select(q => q.Id).ToList();
+ Assert.Equal(ids.Count, ids.Distinct().Count());
+ }
}
diff --git a/docs/reference/architecture/0004-stamdata-as-code.md b/docs/reference/architecture/0004-stamdata-as-code.md
index a69f5ab..7dde07c 100644
--- a/docs/reference/architecture/0004-stamdata-as-code.md
+++ b/docs/reference/architecture/0004-stamdata-as-code.md
@@ -75,7 +75,8 @@ everyone. Stamdata (the rules and reference tables the whole register runs on) s
- **−** A change needs the PR pipeline — not instant, and a non-developer may need dev
assistance to edit C# (mitigated later by a low-code editor that emits a PR, or by a
data-file format if hand-editing ergonomics ever outweigh maximal compile-time safety).
-- **Pilot shipped with this ADR:** the profession↔diploma map extracted to
- `Stamdata/Professions.cs`, `DiplomaRules` refactored to consume it (behaviour unchanged),
- and `StamdataValidationTests` added. Policy-question text and document-category
- definitions follow the same pattern as obvious next steps; not moved yet.
+- **Shipped with this ADR:** the profession↔diploma map (`Stamdata/Professions.cs`) and the
+ policy-question wording (`Stamdata/PolicyQuestions.cs`) extracted from `DiplomaRules`,
+ which now consumes both (behaviour unchanged), guarded by `StamdataValidationTests`.
+ Document-category definitions follow the same pattern as the obvious next step; not moved
+ yet.