IAclClient.StoreDiplomaAsync + AclHttpClient (base64 JSON to the ACL /documenten endpoint). ProvideDocuments stores the uploaded bytes against the zaak (when opened) before completing WachtOpDocumenten; the domain endpoint accepts the file base64-encoded. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
55 lines
2.8 KiB
C#
55 lines
2.8 KiB
C#
using Big.Domain;
|
|
|
|
namespace Big.Application;
|
|
|
|
/// <summary>A zorgprofessional's upload of the diploma their registration is waiting for ("documenten
|
|
/// aanleveren"). <paramref name="Bsn"/> is the authenticated caller (from the DigiD token, forwarded by
|
|
/// the BFF): only the registration's own bsn may provide its documents. <paramref name="Content"/> is
|
|
/// the raw file, with its <paramref name="FileName"/> and <paramref name="ContentType"/>.</summary>
|
|
public sealed record ProvideDocumentsCommand(
|
|
RegistrationId RegistrationId, string Bsn, byte[] Content, string FileName, string ContentType);
|
|
|
|
/// <summary>The outcome of a provide-documents request.</summary>
|
|
public enum ProvideDocumentsOutcome
|
|
{
|
|
/// <summary>The documents were accepted; the process's document wait was completed (if any).</summary>
|
|
Accepted,
|
|
|
|
/// <summary>No registration with that id belongs to the caller — unknown, or owned by someone else
|
|
/// (the two are deliberately indistinguishable, so the endpoint reveals neither).</summary>
|
|
NotFound,
|
|
}
|
|
|
|
/// <summary>
|
|
/// The provide-documents use case (S-10a/S-10b): a zorgprofessional uploads the diploma their
|
|
/// registration is parked waiting for. The document is stored in ZGW via the ACL (§8.1), then the
|
|
/// WachtOpDocumenten task is completed so the registratie process leaves the 30-day wait and continues
|
|
/// to beoordeling (ADR-0017). Owner-scoped by bsn. Both steps are best-effort about missing preconditions
|
|
/// (mirroring <see cref="WithdrawRegistration"/>): storage needs an opened zaak, and completion needs a
|
|
/// running process — a request that arrives before either still stands, storing/completing what it can.
|
|
/// </summary>
|
|
public sealed class ProvideDocuments(IRegistrationStore store, IWorkflowClient workflow, IAclClient acl)
|
|
{
|
|
public async Task<ProvideDocumentsOutcome> HandleAsync(ProvideDocumentsCommand command, CancellationToken ct = default)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(command);
|
|
|
|
var registration = await store.GetAsync(command.RegistrationId, ct);
|
|
|
|
// Unknown, or not the caller's registration: report NotFound either way (don't reveal which).
|
|
if (registration is null || registration.Bsn != command.Bsn)
|
|
return ProvideDocumentsOutcome.NotFound;
|
|
|
|
// Store the diploma against the zaak (once it is opened) — the ACL is the only ZGW caller (§8.1).
|
|
if (registration.ZaakUrl is not null)
|
|
await acl.StoreDiplomaAsync(
|
|
registration.ZaakUrl, command.Content, command.FileName, command.ContentType, ct);
|
|
|
|
// Complete the document wait (if a process is running) so beoordeling can proceed.
|
|
if (registration.ProcessInstanceId is not null)
|
|
await workflow.CompleteDocumentWaitAsync(registration.ProcessInstanceId, ct);
|
|
|
|
return ProvideDocumentsOutcome.Accepted;
|
|
}
|
|
}
|