test(acl): approval writes the RegisterRecord to Objecten (refs #149)

Ports and failing tests for the Objecten hop, ahead of the implementation:

- IRegisterRecordGateway + RegisterRecord — the Application-side port; the
  record mirrors the objecttype schema registered in S-18c (ADR-0027).
- AclService takes the port but does not yet call it, so the approval test
  fails on an empty upsert list.
- ObjectenGateway is a shell throwing NotImplementedException; its tests pin
  the contract: resolve the objecttype by name, search by data attribute,
  POST when absent / PATCH when present, static Token auth per API, the CRS
  headers the geo API requires, and a surfaced error body.

Also splits S-19 (#20) into #149/#150 in BACKLOG.md — the approval-side write
and the projection re-sourcing are independently deployable (CLAUDE.md §13).
This commit is contained in:
not
2026-08-14 09:16:23 +02:00
parent d37d4c96c6
commit 66f8322580
9 changed files with 318 additions and 5 deletions
@@ -0,0 +1,10 @@
using Acl.Application;
namespace Acl.Infrastructure;
/// <summary>The only code that talks to the Objecten API (ADR-0028).</summary>
public sealed class ObjectenGateway(HttpClient http, ObjectenOptions options, IClock clock) : IRegisterRecordGateway
{
public Task UpsertAsync(RegisterRecord record, CancellationToken ct = default) =>
throw new NotImplementedException();
}
@@ -0,0 +1,20 @@
namespace Acl.Infrastructure;
/// <summary>
/// Connection + credential config for the Objecten and Objecttypen APIs. Both authenticate with a
/// static <c>Authorization: Token …</c> (they are not ZGW JWT APIs), so there is no client-id/secret
/// pair as with OpenZaak.
/// </summary>
public sealed class ObjectenOptions
{
public required Uri BaseUrl { get; init; }
public required string Token { get; init; }
/// <summary>Objecttypen API root — the ACL resolves the objecttype URL + version from it by name
/// rather than pinning a seed-time UUID in config (same reasoning as ADR-0021).</summary>
public required Uri ObjecttypenBaseUrl { get; init; }
public required string ObjecttypenToken { get; init; }
/// <summary>The objecttype the register record is written as (S-18c registers "RegisterRecord").</summary>
public required string ObjecttypeName { get; init; }
}