Ports, schema and failing tests for the subscriber half of S-19b-2, ahead of the implementation. The subscriber now listens on the `objecten` kanaal instead of `zaken`. An Objecten notification carries no record data — only the object URL — so the record is read back through the ACL (§8.1), and the zaak-shaped surface goes away: IsZaakCreated / IsZaakStatusSet / ZaakUrl / ZaakId and ToEntry's `Resource == "status"` mapping are replaced by IsRegisterRecordWritten + ObjectUrl. The notification log now holds the projected row itself (register id, status, reference), so a rebuild is a replay with no mapping rules and no upstream reads. The migration drops the old columns rather than renaming them — EF scaffolded renames that would have carried ZGW values into columns meaning something else — and empties both tables, since a pre-slice row is neither reprojectable nor re-derivable from the new source. Red: HandleAsync recognises a register write but does not yet read or project it, so the seven projection assertions fail on an empty store.
70 lines
3.4 KiB
C#
70 lines
3.4 KiB
C#
using Microsoft.EntityFrameworkCore.Migrations;
|
|
|
|
#nullable disable
|
|
|
|
namespace Projection.ReadModel.Migrations
|
|
{
|
|
/// <summary>
|
|
/// S-19b-2 (ADR-0030): the notification log stops describing ZGW zaak events and starts holding
|
|
/// the projected register row itself (register id, status, reference).
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The old columns are dropped and the new ones added rather than renamed. EF scaffolded renames
|
|
/// (<c>resource</c> → <c>register_id</c>, <c>zaak_id</c> → <c>status</c>), which would carry ZGW
|
|
/// values into columns that mean something else entirely — "zaak"/"status" as a register id, a
|
|
/// zaak uuid as a register status — and a rebuild would then project that garbage.
|
|
///
|
|
/// Both tables are emptied instead. A pre-existing row describes a zaak event the new projector
|
|
/// cannot reproject, and the registrations behind those rows have no RegisterRecord in Objecten
|
|
/// (only approvals wrote one before this slice), so they are not re-derivable from the new source
|
|
/// either. The projection is a derived artefact (§8.4) and repopulates as register writes arrive.
|
|
/// </remarks>
|
|
public partial class ProjectionSourcedFromObjecten : Migration
|
|
{
|
|
/// <inheritdoc />
|
|
protected override void Up(MigrationBuilder migrationBuilder)
|
|
{
|
|
// ponytail: drops the pre-slice register rather than backfilling it. Fine while stacks are
|
|
// ephemeral (a fresh `docker compose up` is the norm). If a long-lived environment ever
|
|
// needs to keep them, backfill by walking Objecten's objects instead of replaying the log.
|
|
migrationBuilder.Sql("DELETE FROM processed_notifications;");
|
|
migrationBuilder.Sql("DELETE FROM register_projection;");
|
|
|
|
migrationBuilder.DropColumn(name: "actie", table: "processed_notifications");
|
|
migrationBuilder.DropColumn(name: "zaak_id", table: "processed_notifications");
|
|
migrationBuilder.DropColumn(name: "resource", table: "processed_notifications");
|
|
|
|
migrationBuilder.AddColumn<string>(
|
|
name: "register_id",
|
|
table: "processed_notifications",
|
|
type: "text",
|
|
nullable: false,
|
|
defaultValue: "");
|
|
|
|
migrationBuilder.AddColumn<string>(
|
|
name: "status",
|
|
table: "processed_notifications",
|
|
type: "text",
|
|
nullable: false,
|
|
defaultValue: "");
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
protected override void Down(MigrationBuilder migrationBuilder)
|
|
{
|
|
migrationBuilder.Sql("DELETE FROM processed_notifications;");
|
|
migrationBuilder.Sql("DELETE FROM register_projection;");
|
|
|
|
migrationBuilder.DropColumn(name: "register_id", table: "processed_notifications");
|
|
migrationBuilder.DropColumn(name: "status", table: "processed_notifications");
|
|
|
|
migrationBuilder.AddColumn<string>(
|
|
name: "actie", table: "processed_notifications", type: "text", nullable: false, defaultValue: "");
|
|
migrationBuilder.AddColumn<string>(
|
|
name: "zaak_id", table: "processed_notifications", type: "text", nullable: false, defaultValue: "");
|
|
migrationBuilder.AddColumn<string>(
|
|
name: "resource", table: "processed_notifications", type: "text", nullable: false, defaultValue: "");
|
|
}
|
|
}
|
|
}
|