Files
atomic-design-poc/backend/README.md
Edwin van den Houdt cf570a8132 Add ASP.NET Core backend hosting business rules; FE consumes via typed client
Move the authoritative business rules off the frontend into a real backend,
realising the BFF-lite + decision-DTO design (ADR-0001) that until now lived
only in static mock JSON.

Backend (backend/):
- ASP.NET Core (.NET 10) minimal API, contract-first, Swagger UI at /swagger.
- DDD Domain/ rules layer: profession derivation + applicable policy questions
  (DiplomaRules), herregistratie eligibility + reason (HerregistratieRule),
  scholing threshold (IntakePolicy), submit rejections + reference generation
  (SubmissionRules). In-memory seeded data, ProblemDetails (RFC 7807) errors.
- 27 xUnit tests: rule units + endpoint integration incl. BRP no-address and
  DUO not-found fallbacks and 422 submit paths.

Frontend (only infrastructure/ + contracts/ change, as the architecture promised):
- NSwag-generated typed client (api-client.ts), routed through Angular HttpClient
  via a small fetch adapter so the ?scenario= interceptor still applies.
- GET adapters use resource({ loader: client.x }); submit commands call the client
  and map ProblemDetails -> err. The hardcoded uren==0 / manual-diploma rules are
  deleted (now server-side). Domain, stores, UI and format validators unchanged.
- Deleted the now-dead public/mock/*.json.

Tooling/docs:
- npm start proxies /api -> backend; npm run gen:api regenerates the client;
  docker compose up runs both (bind mounts use :z for SELinux/Fedora).
- backend/README.md walkthrough: adding a policy question is a one-file backend
  change, no FE change, no client regen. Updated CLAUDE.md + ARCHITECTURE.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 20:05:53 +02:00

3.5 KiB

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

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.

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 fileDomain/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:api is 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.