using Big.Domain;
namespace Big.Application;
/// A zorgprofessional's upload of the diploma their registration is waiting for ("documenten
/// aanleveren"). is the authenticated caller (from the DigiD token, forwarded by
/// the BFF): only the registration's own bsn may provide its documents. is
/// the raw file, with its and .
public sealed record ProvideDocumentsCommand(
RegistrationId RegistrationId, string Bsn, byte[] Content, string FileName, string ContentType);
/// The outcome of a provide-documents request.
public enum ProvideDocumentsOutcome
{
/// The documents were accepted; the process's document wait was completed (if any).
Accepted,
/// 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).
NotFound,
}
///
/// 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 ): storage needs an opened zaak, and completion needs a
/// running process — a request that arrives before either still stands, storing/completing what it can.
///
public sealed class ProvideDocuments(IRegistrationStore store, IWorkflowClient workflow, IAclClient acl)
{
public async Task 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;
}
}