diff --git a/services/domain/Big.Application/Ports.cs b/services/domain/Big.Application/Ports.cs
index 8e74b72..b89ac82 100644
--- a/services/domain/Big.Application/Ports.cs
+++ b/services/domain/Big.Application/Ports.cs
@@ -11,10 +11,12 @@ public interface IWorkflowClient
{
///
/// Start one registratie process instance for the given registration, carrying the
- /// registration id so the OpenZaakAanmaken external task can be correlated back to its
- /// aggregate. Returns the process instance id.
+ /// registration id (so the OpenZaakAanmaken external task can be correlated back to its
+ /// aggregate) and the diploma origin (so the workflow's DMN can route foreign diplomas through
+ /// CBGV-advies, S-13). Returns the process instance id.
///
- Task StartRegistrationProcessAsync(RegistrationId registrationId, CancellationToken ct = default);
+ Task StartRegistrationProcessAsync(
+ RegistrationId registrationId, DiplomaOrigin diplomaOrigin, CancellationToken ct = default);
///
/// Cancel a running registratie process on withdrawal (S-11): correlate the
diff --git a/services/domain/Big.Application/SubmitRegistration.cs b/services/domain/Big.Application/SubmitRegistration.cs
index 3e2f55f..1f70e9e 100644
--- a/services/domain/Big.Application/SubmitRegistration.cs
+++ b/services/domain/Big.Application/SubmitRegistration.cs
@@ -2,8 +2,10 @@ using Big.Domain;
namespace Big.Application;
-/// A zorgprofessional's request to register, in domain language. No ZGW concepts.
-public sealed record SubmitRegistrationCommand(string Bsn);
+/// A zorgprofessional's request to register, in domain language. No ZGW concepts. The
+/// diploma origin defaults to domestic (the DigiD path); a foreign (eIDAS) submission sets it to
+/// so the workflow's DMN routes it through CBGV-advies (S-13).
+public sealed record SubmitRegistrationCommand(string Bsn, DiplomaOrigin DiplomaOrigin = DiplomaOrigin.Binnenlands);
///
/// The submit use case: create the aggregate (INGEDIEND), persist it,
@@ -18,13 +20,14 @@ public sealed class SubmitRegistration(IRegistrationStore store, IWorkflowClient
{
ArgumentNullException.ThrowIfNull(command);
- var registration = Registration.Submit(command.Bsn);
+ var registration = Registration.Submit(command.Bsn, command.DiplomaOrigin);
// Persist before starting the process so the worker can correlate the OpenZaakAanmaken
// job back to an aggregate that already exists (ADR-0009).
await store.SaveAsync(registration, ct);
- var processInstanceId = await workflow.StartRegistrationProcessAsync(registration.Id, ct);
+ var processInstanceId = await workflow.StartRegistrationProcessAsync(
+ registration.Id, registration.DiplomaOrigin, ct);
registration.RecordProcessStarted(processInstanceId);
await store.SaveAsync(registration, ct);
diff --git a/services/domain/Big.Domain/DiplomaOrigin.cs b/services/domain/Big.Domain/DiplomaOrigin.cs
new file mode 100644
index 0000000..74812dc
--- /dev/null
+++ b/services/domain/Big.Domain/DiplomaOrigin.cs
@@ -0,0 +1,17 @@
+namespace Big.Domain;
+
+///
+/// Where a zorgprofessional's diploma was issued. It is the input to the diploma-eligibility decision
+/// (S-13): a (foreign) diploma routes the registratie through an extra
+/// CBGV-advies assessment step, a (domestic) one goes straight to beoordeling.
+/// The decision itself lives in the workflow's DMN, not here (ADR-0016); the domain only carries the
+/// origin and hands it to the process as a start variable.
+///
+public enum DiplomaOrigin
+{
+ /// A Dutch (domestic) diploma. Default for a registration submitted via DigiD.
+ Binnenlands,
+
+ /// A foreign diploma (e.g. an eIDAS submission). Triggers the CBGV-advies step.
+ Buitenlands,
+}
diff --git a/services/domain/Big.Domain/Registration.cs b/services/domain/Big.Domain/Registration.cs
index 4b29eab..51f20cf 100644
--- a/services/domain/Big.Domain/Registration.cs
+++ b/services/domain/Big.Domain/Registration.cs
@@ -7,10 +7,11 @@ namespace Big.Domain;
///
public sealed class Registration
{
- private Registration(RegistrationId id, string bsn)
+ private Registration(RegistrationId id, string bsn, DiplomaOrigin diplomaOrigin)
{
Id = id;
Bsn = bsn;
+ DiplomaOrigin = diplomaOrigin;
Status = RegistrationStatus.Ingediend;
}
@@ -20,6 +21,10 @@ public sealed class Registration
/// as the domain payload; the domain never constructs ZGW concepts from it (§8.1).
public string Bsn { get; }
+ /// Where the diploma was issued. Rides along to the process as a start variable and
+ /// drives the diploma-eligibility DMN's foreign→CBGV-advies routing (S-13, ADR-0016).
+ public DiplomaOrigin DiplomaOrigin { get; }
+
public RegistrationStatus Status { get; private set; }
/// The Flowable process instance driving this registration, once started.
@@ -28,11 +33,13 @@ public sealed class Registration
/// The zaak the ACL opened for this registration, once the external task has run.
public Uri? ZaakUrl { get; private set; }
- /// Submit a new registration. It begins in .
- public static Registration Submit(string bsn)
+ /// Submit a new registration. It begins in .
+ /// The diploma origin defaults to — the common DigiD path;
+ /// a foreign (eIDAS) submission passes .
+ public static Registration Submit(string bsn, DiplomaOrigin diplomaOrigin = DiplomaOrigin.Binnenlands)
{
ArgumentException.ThrowIfNullOrWhiteSpace(bsn);
- return new Registration(RegistrationId.New(), bsn);
+ return new Registration(RegistrationId.New(), bsn, diplomaOrigin);
}
/// Record that the registratie workflow process has been started for this registration.
diff --git a/services/domain/Big.Infrastructure/FlowableWorkflowClient.cs b/services/domain/Big.Infrastructure/FlowableWorkflowClient.cs
index d8933e2..1d825c8 100644
--- a/services/domain/Big.Infrastructure/FlowableWorkflowClient.cs
+++ b/services/domain/Big.Infrastructure/FlowableWorkflowClient.cs
@@ -28,7 +28,8 @@ public sealed class FlowableWorkflowClient(HttpClient http, FlowableOptions opti
private const string BesluitVariable = "besluit";
private const string IngetrokkenMessage = "RegistratieIngetrokken";
- public async Task StartRegistrationProcessAsync(RegistrationId registrationId, CancellationToken ct = default)
+ public async Task StartRegistrationProcessAsync(
+ RegistrationId registrationId, DiplomaOrigin diplomaOrigin, CancellationToken ct = default)
{
var request = new StartProcessRequest(
ProcessDefinitionKey,
diff --git a/services/domain/Big.Tests/Fakes.cs b/services/domain/Big.Tests/Fakes.cs
index 539f554..e9c6953 100644
--- a/services/domain/Big.Tests/Fakes.cs
+++ b/services/domain/Big.Tests/Fakes.cs
@@ -32,12 +32,15 @@ internal sealed class FakeWorkflowClient(string processInstanceId = "proc-1", Ac
: IWorkflowClient
{
public RegistrationId? StartedFor { get; private set; }
+ public DiplomaOrigin? StartedWithOrigin { get; private set; }
public string? WithdrawnProcessInstanceId { get; private set; }
- public Task StartRegistrationProcessAsync(RegistrationId registrationId, CancellationToken ct = default)
+ public Task StartRegistrationProcessAsync(
+ RegistrationId registrationId, DiplomaOrigin diplomaOrigin, CancellationToken ct = default)
{
onStart?.Invoke(registrationId);
StartedFor = registrationId;
+ StartedWithOrigin = diplomaOrigin;
return Task.FromResult(processInstanceId);
}
diff --git a/services/domain/Big.Tests/FlowableWorkflowClientTests.cs b/services/domain/Big.Tests/FlowableWorkflowClientTests.cs
index d852e11..b67d9d7 100644
--- a/services/domain/Big.Tests/FlowableWorkflowClientTests.cs
+++ b/services/domain/Big.Tests/FlowableWorkflowClientTests.cs
@@ -24,7 +24,7 @@ public class FlowableWorkflowClientTests
var client = Client(capture.Responds(HttpStatusCode.Created, """{"id":"pi-1"}"""));
var rid = RegistrationId.New();
- var pid = await client.StartRegistrationProcessAsync(rid);
+ var pid = await client.StartRegistrationProcessAsync(rid, DiplomaOrigin.Binnenlands);
Assert.Equal("pi-1", pid);
Assert.Equal(HttpMethod.Post, capture.Seen!.Method);
@@ -38,6 +38,22 @@ public class FlowableWorkflowClientTests
Assert.Contains($"\"value\":\"{rid}\"", capture.Body);
}
+ [Theory]
+ [InlineData(DiplomaOrigin.Binnenlands, "Binnenlands")]
+ [InlineData(DiplomaOrigin.Buitenlands, "Buitenlands")]
+ public async Task Start_posts_the_diploma_origin_as_a_process_variable(DiplomaOrigin origin, string expected)
+ {
+ // The diploma origin rides along as a start variable so the workflow's DMN can route foreign
+ // diplomas through CBGV-advies (S-13, ADR-0016).
+ var capture = new RequestCapture();
+ var client = Client(capture.Responds(HttpStatusCode.Created, """{"id":"pi-1"}"""));
+
+ await client.StartRegistrationProcessAsync(RegistrationId.New(), origin);
+
+ Assert.Contains("\"name\":\"diplomaOrigin\"", capture.Body);
+ Assert.Contains($"\"value\":\"{expected}\"", capture.Body);
+ }
+
[Fact]
public async Task Start_uses_the_configured_worker_credentials_and_defaults()
{
@@ -125,7 +141,7 @@ public class FlowableWorkflowClientTests
var client = Client(capture.Responds(HttpStatusCode.InternalServerError));
await Assert.ThrowsAsync(
- () => client.StartRegistrationProcessAsync(RegistrationId.New()));
+ () => client.StartRegistrationProcessAsync(RegistrationId.New(), DiplomaOrigin.Binnenlands));
}
[Fact]
@@ -135,7 +151,7 @@ public class FlowableWorkflowClientTests
var client = Client(capture.Responds(HttpStatusCode.Created, "null"));
var ex = await Assert.ThrowsAsync(
- () => client.StartRegistrationProcessAsync(RegistrationId.New()));
+ () => client.StartRegistrationProcessAsync(RegistrationId.New(), DiplomaOrigin.Binnenlands));
Assert.Contains("empty process-instance", ex.Message);
}
diff --git a/tests/acceptance/Support/InMemoryDomainPorts.cs b/tests/acceptance/Support/InMemoryDomainPorts.cs
index 4926b21..af07de0 100644
--- a/tests/acceptance/Support/InMemoryDomainPorts.cs
+++ b/tests/acceptance/Support/InMemoryDomainPorts.cs
@@ -12,11 +12,14 @@ public sealed class InMemoryWorkflowClient : IWorkflowClient
public const string StartedProcessInstanceId = "proc-acc-1";
public RegistrationId? StartedFor { get; private set; }
+ public DiplomaOrigin? StartedWithOrigin { get; private set; }
public string? WithdrawnProcessInstanceId { get; private set; }
- public Task StartRegistrationProcessAsync(RegistrationId registrationId, CancellationToken ct = default)
+ public Task StartRegistrationProcessAsync(
+ RegistrationId registrationId, DiplomaOrigin diplomaOrigin, CancellationToken ct = default)
{
StartedFor = registrationId;
+ StartedWithOrigin = diplomaOrigin;
return Task.FromResult(StartedProcessInstanceId);
}