- brief.machine: reducer refuses edits to locked (predefined) sections as
defense-in-depth; LetterSection gains a `locked` flag
- rich-text: paragraphs gain optional `list` kind; editor gets bullet/numbered
list buttons, keyboard shortcuts, and backspace-deletes-adjacent-chip
- placeholder chips distinguish auto-resolvable (grey) vs manual (yellow), in
both the editor and the read-only preview
- fix: preview chip now renders matching {…} braces (was a one-sided ⌗ glyph),
aligned with the editor's chip styling
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
BIG-register BFF (ASP.NET Core)
The backend that hosts the business rules for the BIG-register portal. The
frontend renders the decisions this service computes; it does not recompute them
(BFF-lite + decision DTOs — see ../docs/architecture/0001-bff-lite-decision-dtos.md).
No database, no real BRP/DUO: data is in-memory and seeded (Data/SeedData.cs),
but the endpoints, DTOs, status codes and error envelope are production-shaped.
Run
Everything (docker-compose, from repo root)
docker compose up
- App: http://localhost:4200
- Swagger UI: http://localhost:5000/swagger
Backend only (local)
cd backend
dotnet run --project src/BigRegister.Api
# → http://localhost:5000/swagger
Frontend against a local backend
npm start # ng serve, proxies /api → http://localhost:5000 (proxy.conf.json)
Tests
cd backend && dotnet test # rule unit tests + endpoint integration tests
API
| Method | Route | Purpose |
|---|---|---|
| GET | /api/dashboard-view |
registration + person + computed herregistratie decision |
| GET | /api/notes |
specialisms / aantekeningen |
| GET | /api/brp/address |
BRP address lookup (gevonden:false = no address) |
| GET | /api/duo/diplomas |
diplomas with derived profession + applicable policy questions, + manual fallback |
| GET | /api/intake/policy |
scholing threshold (config value) |
| POST | /api/registrations |
submit registration → reference, or 422 (manual diploma) |
| POST | /api/herregistraties |
submit re-registration → reference, or 422 (0 hours) |
| POST | /api/intakes |
submit intake → reference, or 422 (0 hours) |
Rejections use ProblemDetails (RFC 7807) with status 422. Every request
carries an X-Correlation-Id (set by the FE fetch adapter); the backend echoes it
into a no-PII submit-audit log line (kind, outcome, reference, correlation id)
— the seam for real structured logging / an audit store.
Versioning
Endpoints live under /api/v1. Additive changes (a new optional field) stay on
v1: the NSwag-generated client and the FE parse* boundary ignore unknown fields,
so old clients keep working. A breaking change (renamed/removed field, changed
semantics) is introduced as /api/v2 served alongside v1 until clients migrate.
Where the rules live (src/BigRegister.Api/Domain/)
Diplomas/DiplomaRules.cs— profession derivation + which policy questions apply.Registrations/HerregistratieRule.cs— eligibility + reason + status invariant.Intake/IntakePolicy.cs— scholing threshold.Submissions/SubmissionRules.cs— submit rejections + reference generation.
Typed client (NSwag)
The frontend calls this API through a generated TypeScript client. Regenerate it from the contract after a shape change:
npm run gen:api # builds backend → swagger.json → src/app/shared/infrastructure/api-client.ts
Maintainability: changing a policy is one backend change
Goal: require every Verpleegkundige diploma to confirm a Dutch skills assessment. This is a new policy question on a diploma type.
Edit one file — Domain/Diplomas/DiplomaRules.cs:
public static IReadOnlyList<PolicyQuestion> QuestionsFor(Diploma d)
{
var questions = new List<PolicyQuestion>();
if (d.Engelstalig)
questions.Add(NlTaalEngelstalig);
+ if (d.Opleiding == "verpleegkunde")
+ questions.Add(new PolicyQuestion(
+ "bekwaamheid",
+ "Heeft u in de afgelopen vijf jaar een bekwaamheidstoets afgelegd?",
+ QuestionType.JaNee));
return questions;
}
Rebuild the backend (docker compose up or dotnet run). The new question now
appears in the registration wizard for HBO-Verpleegkunde.
- No frontend change. The FE renders whatever questions the API returns.
- No client regeneration. The wire shape (
PolicyQuestionDto) is unchanged — only the data behind it.npm run gen:apiis only needed when a DTO shape changes.
Add a unit test for the new rule in tests/BigRegister.Tests/RuleTests.cs and
you're done.