CI / frontend (push) Successful in 2m59s
CI / backend (push) Successful in 1m27s
CI / semgrep (push) Successful in 58s
CI / e2e (push) Successful in 2m30s
CI / api-client-drift (push) Canceled after 1m14s
CI / storybook-a11y (push) Canceled after 29m8s
Stamdata: add beroepen, opleidingen (temporal), and specialismen tables to the schema-driven catalog (zero UI code). opleidingen.beroep and specialismen.beroep both reference beroepen.code — the first stamdata->stamdata references, enforced by two new StamdataRef entries in the CI gate. OpenZaak/ZGW (WP-49, slice 1 — read-only zaken): introduce IZaakSource as the cases read seam. Default LocalZaakSource reads the local SQLite store (offline); an OpenZaakZaakSource (Zgw/ client: HS256 per-call JWT, ZGW->existing-DTO mapper, paginating HTTP source) is selected behind Zgw:Enabled (default false). The FE never changes — same ApplicationSummaryDto, no api-client drift. Unit-tested with fixtures + a stub HttpMessageHandler; no live OpenZaak needed. Docs: ADR-0005, reference/openzaak-integration.md, WP-49..52 roadmap, stamdata.md update, README index rows. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
59 lines
2.9 KiB
C#
59 lines
2.9 KiB
C#
using System.Text.Json.Serialization;
|
|
using BigRegister.Api.Contracts;
|
|
|
|
namespace BigRegister.Api.Zgw;
|
|
|
|
/// <summary>
|
|
/// The subset of a ZGW Zaak (Zaken API / ZRC) the read slice needs. The full resource has
|
|
/// dozens of fields; we bind only what maps to <see cref="ApplicationSummaryDto"/>. Note the
|
|
/// two ZGW traits that force an anti-corruption layer: <see cref="Url"/> is the resource's
|
|
/// identity (not a bare id), and <see cref="Zaaktype"/> is a URL <em>into another service</em>
|
|
/// (Catalogi/ZTC) that must be resolved to a human label.
|
|
/// </summary>
|
|
public sealed record ZgwZaak(
|
|
[property: JsonPropertyName("url")] string Url,
|
|
[property: JsonPropertyName("identificatie")] string Identificatie,
|
|
[property: JsonPropertyName("zaaktype")] string Zaaktype,
|
|
[property: JsonPropertyName("startdatum")] DateOnly Startdatum,
|
|
[property: JsonPropertyName("einddatum")] DateOnly? Einddatum,
|
|
[property: JsonPropertyName("registratiedatum")] DateOnly? Registratiedatum);
|
|
|
|
/// <summary>
|
|
/// Anti-corruption map: ZGW Zaak → the existing <see cref="ApplicationSummaryDto"/> the FE
|
|
/// already renders (WP-49). This is where "URL as identity" and the cross-service zaaktype
|
|
/// join get flattened away, so nothing downstream (the FE) sees ZGW shapes.
|
|
/// </summary>
|
|
public static class ZgwZaakMapper
|
|
{
|
|
/// <summary>Last path segment of a ZGW resource URL — the uuid that identifies it.</summary>
|
|
public static string Uuid(string url) => url.TrimEnd('/').Split('/').Last();
|
|
|
|
public static ApplicationSummaryDto ToSummaryDto(ZgwZaak z, string zaaktypeLabel)
|
|
{
|
|
// ponytail: coarse status map — an open zaak (no einddatum) is In behandeling, a closed
|
|
// one is Goedgekeurd. Real fidelity (statustype/resultaat lookups) is a later slice; the
|
|
// Afgewezen path needs the resultaat resource. Enough to prove the seam end-to-end.
|
|
var status = z.Einddatum is null
|
|
? new AanvraagStatusDto("InBehandeling", Referentie: z.Identificatie, Manual: true)
|
|
: new AanvraagStatusDto("Goedgekeurd", Referentie: z.Identificatie);
|
|
|
|
var created = Iso(z.Registratiedatum ?? z.Startdatum);
|
|
var updated = Iso(z.Einddatum ?? z.Registratiedatum ?? z.Startdatum);
|
|
|
|
return new ApplicationSummaryDto(
|
|
Id: Uuid(z.Url),
|
|
Type: zaaktypeLabel,
|
|
Status: status,
|
|
DocumentIds: Array.Empty<string>(), // zaak↔document links arrive with WP-51 (DRC)
|
|
CreatedAt: created,
|
|
UpdatedAt: updated,
|
|
SubmittedAt: created,
|
|
Owner: z.Identificatie); // real initiator (rol/BSN) needs a rollen lookup — later slice
|
|
}
|
|
|
|
// Keep the wire shape identical to the local source (round-trip datetime): a ZGW date
|
|
// becomes midnight UTC so the FE's date parsing sees the same format either backend.
|
|
private static string Iso(DateOnly d) =>
|
|
d.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc).ToString("o");
|
|
}
|