using System.Net.Http.Json; namespace Bff.Api; /// What the self-service submit returns to the portal (the domain's registration id + status). public sealed record SubmitAccepted(string RegistrationId, string Status); /// A projection row as the projection-api serves it. Bsn/NaamPlaceholder are /// read but never surfaced by the openbaar endpoint (public-safe filtering, ADR-0010/S-09). public sealed record ProjectionEntry(string Id, string Status, string? Bsn, string? NaamPlaceholder); /// A public-safe openbaar register row — only non-sensitive fields leave the BFF. public sealed record OpenbaarEntry(string Id, string Status); /// Port to the Domain Service (§8.3: the BFF is the portals' only backend; it fans out). public interface IDomainClient { Task SubmitRegistrationAsync(string bsn, CancellationToken ct = default); } /// Port to the read projection. public interface IProjectionClient { Task> GetRegisterAsync(CancellationToken ct = default); } /// Calls the Domain Service's POST /registrations. public sealed class DomainClient(HttpClient http) : IDomainClient { public async Task SubmitRegistrationAsync(string bsn, CancellationToken ct = default) { using var response = await http.PostAsJsonAsync("registrations", new { bsn }, ct); response.EnsureSuccessStatusCode(); var dto = await response.Content.ReadFromJsonAsync(ct) ?? throw new InvalidOperationException("The Domain Service returned an empty registration response."); return new SubmitAccepted(dto.RegistrationId, dto.Status); } private sealed record DomainResponse(string RegistrationId, string Status, string? ZaakUrl); } /// Calls the projection-api's GET /register. public sealed class ProjectionClient(HttpClient http) : IProjectionClient { public async Task> GetRegisterAsync(CancellationToken ct = default) => await http.GetFromJsonAsync>("register", ct) ?? []; }