diff --git a/src/ParcelRegistry.Projections.Integration/IntegrationContext.cs b/src/ParcelRegistry.Projections.Integration/IntegrationContext.cs index 72d31c92..fe34f1ec 100644 --- a/src/ParcelRegistry.Projections.Integration/IntegrationContext.cs +++ b/src/ParcelRegistry.Projections.Integration/IntegrationContext.cs @@ -2,7 +2,6 @@ { using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner; using Microsoft.EntityFrameworkCore; - using ParcelLatestItem; using ParcelLatestItemV2; using ParcelRegistry.Infrastructure; using ParcelVersion; @@ -11,9 +10,7 @@ public class IntegrationContext : RunnerDbContext { public override string ProjectionStateSchema => Schema.Integration; - public DbSet ParcelLatestItems => Set(); public DbSet ParcelVersions => Set(); - public DbSet ParcelLatestItemAddresses => Set(); public DbSet ParcelVersionAddresses => Set(); public DbSet ParcelLatestItemsV2 => Set(); diff --git a/src/ParcelRegistry.Projections.Integration/Migrations/20241121085725_RemoveLatestItemV1.Designer.cs b/src/ParcelRegistry.Projections.Integration/Migrations/20241121085725_RemoveLatestItemV1.Designer.cs new file mode 100644 index 00000000..94003008 --- /dev/null +++ b/src/ParcelRegistry.Projections.Integration/Migrations/20241121085725_RemoveLatestItemV1.Designer.cs @@ -0,0 +1,281 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NetTopologySuite.Geometries; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using ParcelRegistry.Projections.Integration; + +#nullable disable + +namespace ParcelRegistry.Projections.Integration.Migrations +{ + [DbContext(typeof(IntegrationContext))] + [Migration("20241121085725_RemoveLatestItemV1")] + partial class RemoveLatestItemV1 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.ProjectionStates.ProjectionStateItem", b => + { + b.Property("Name") + .HasColumnType("text"); + + b.Property("DesiredState") + .HasColumnType("text"); + + b.Property("DesiredStateChangedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ErrorMessage") + .HasColumnType("text"); + + b.Property("Position") + .HasColumnType("bigint"); + + b.HasKey("Name"); + + b.ToTable("ProjectionStates", "integration_parcel"); + }); + + modelBuilder.Entity("ParcelRegistry.Projections.Integration.ParcelLatestItemV2.ParcelLatestItemV2", b => + { + b.Property("ParcelId") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("parcel_id"); + + b.Property("CaPaKey") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar") + .HasColumnName("capakey"); + + b.Property("Geometry") + .IsRequired() + .HasColumnType("geometry") + .HasColumnName("geometry"); + + b.Property("IsRemoved") + .HasColumnType("boolean") + .HasColumnName("is_removed"); + + b.Property("Namespace") + .IsRequired() + .HasColumnType("text") + .HasColumnName("namespace"); + + b.Property("OsloStatus") + .IsRequired() + .HasColumnType("text") + .HasColumnName("oslo_status"); + + b.Property("Puri") + .IsRequired() + .HasColumnType("text") + .HasColumnName("puri"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text") + .HasColumnName("status"); + + b.Property("VersionAsString") + .IsRequired() + .HasColumnType("text") + .HasColumnName("version_as_string"); + + b.Property("VersionTimestampAsDateTimeOffset") + .HasColumnType("timestamp with time zone") + .HasColumnName("version_timestamp"); + + b.HasKey("ParcelId"); + + b.HasIndex("CaPaKey"); + + b.HasIndex("Geometry"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("Geometry"), "GIST"); + + b.HasIndex("IsRemoved"); + + b.HasIndex("OsloStatus"); + + b.HasIndex("Status"); + + b.HasIndex("IsRemoved", "Status"); + + b.ToTable("parcel_latest_items_v2", "integration_parcel"); + }); + + modelBuilder.Entity("ParcelRegistry.Projections.Integration.ParcelLatestItemV2.ParcelLatestItemV2Address", b => + { + b.Property("ParcelId") + .HasColumnType("uuid") + .HasColumnName("parcel_id"); + + b.Property("AddressPersistentLocalId") + .HasColumnType("integer") + .HasColumnName("address_persistent_local_id"); + + b.Property("CaPaKey") + .IsRequired() + .HasColumnType("text") + .HasColumnName("capakey"); + + b.Property("Count") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(1); + + b.HasKey("ParcelId", "AddressPersistentLocalId"); + + b.HasIndex("AddressPersistentLocalId"); + + b.HasIndex("CaPaKey"); + + b.HasIndex("ParcelId"); + + b.ToTable("parcel_latest_item_addresses_v2", "integration_parcel"); + }); + + modelBuilder.Entity("ParcelRegistry.Projections.Integration.ParcelVersion.ParcelVersion", b => + { + b.Property("Position") + .HasColumnType("bigint") + .HasColumnName("position"); + + b.Property("ParcelId") + .HasColumnType("uuid") + .HasColumnName("parcel_id"); + + b.Property("CaPaKey") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar") + .HasColumnName("capakey"); + + b.Property("CreatedOnAsString") + .IsRequired() + .HasColumnType("text") + .HasColumnName("created_on_as_string"); + + b.Property("CreatedOnTimestampAsDateTimeOffset") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_on_timestamp"); + + b.Property("Geometry") + .HasColumnType("geometry") + .HasColumnName("geometry"); + + b.Property("IsRemoved") + .HasColumnType("boolean") + .HasColumnName("is_removed"); + + b.Property("Namespace") + .IsRequired() + .HasColumnType("text") + .HasColumnName("namespace"); + + b.Property("OsloStatus") + .HasColumnType("text") + .HasColumnName("oslo_status"); + + b.Property("Puri") + .IsRequired() + .HasColumnType("text") + .HasColumnName("puri"); + + b.Property("Status") + .HasColumnType("text") + .HasColumnName("status"); + + b.Property("Type") + .IsRequired() + .HasColumnType("text") + .HasColumnName("type"); + + b.Property("VersionAsString") + .IsRequired() + .HasColumnType("text") + .HasColumnName("version_as_string"); + + b.Property("VersionTimestampAsDateTimeOffset") + .HasColumnType("timestamp with time zone") + .HasColumnName("version_timestamp"); + + b.HasKey("Position", "ParcelId"); + + b.HasIndex("CaPaKey"); + + b.HasIndex("Geometry"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("Geometry"), "GIST"); + + b.HasIndex("IsRemoved"); + + b.HasIndex("OsloStatus"); + + b.HasIndex("ParcelId"); + + b.HasIndex("Status"); + + b.HasIndex("Type"); + + b.HasIndex("VersionTimestampAsDateTimeOffset"); + + b.ToTable("parcel_versions", "integration_parcel"); + }); + + modelBuilder.Entity("ParcelRegistry.Projections.Integration.ParcelVersion.ParcelVersionAddress", b => + { + b.Property("Position") + .HasColumnType("bigint") + .HasColumnName("position"); + + b.Property("ParcelId") + .HasColumnType("uuid") + .HasColumnName("parcel_id"); + + b.Property("AddressPersistentLocalId") + .HasColumnType("integer") + .HasColumnName("address_persistent_local_id"); + + b.Property("CaPaKey") + .IsRequired() + .HasColumnType("text") + .HasColumnName("capakey"); + + b.Property("Count") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(1) + .HasColumnName("count"); + + b.HasKey("Position", "ParcelId", "AddressPersistentLocalId"); + + b.HasIndex("AddressPersistentLocalId"); + + b.HasIndex("CaPaKey"); + + b.HasIndex("ParcelId"); + + b.HasIndex("Position"); + + b.ToTable("parcel_version_addresses", "integration_parcel"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/ParcelRegistry.Projections.Integration/Migrations/20241121085725_RemoveLatestItemV1.cs b/src/ParcelRegistry.Projections.Integration/Migrations/20241121085725_RemoveLatestItemV1.cs new file mode 100644 index 00000000..64e86fb7 --- /dev/null +++ b/src/ParcelRegistry.Projections.Integration/Migrations/20241121085725_RemoveLatestItemV1.cs @@ -0,0 +1,119 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using NetTopologySuite.Geometries; + +#nullable disable + +namespace ParcelRegistry.Projections.Integration.Migrations +{ + /// + public partial class RemoveLatestItemV1 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "parcel_latest_item_addresses", + schema: "integration_parcel"); + + migrationBuilder.DropTable( + name: "parcel_latest_items", + schema: "integration_parcel"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "parcel_latest_item_addresses", + schema: "integration_parcel", + columns: table => new + { + parcel_id = table.Column(type: "uuid", nullable: false), + address_persistent_local_id = table.Column(type: "integer", nullable: false), + capakey = table.Column(type: "text", nullable: false), + Count = table.Column(type: "integer", nullable: false, defaultValue: 1) + }, + constraints: table => + { + table.PrimaryKey("PK_parcel_latest_item_addresses", x => new { x.parcel_id, x.address_persistent_local_id }); + }); + + migrationBuilder.CreateTable( + name: "parcel_latest_items", + schema: "integration_parcel", + columns: table => new + { + parcel_id = table.Column(type: "uuid", nullable: false), + capakey = table.Column(type: "varchar", maxLength: 20, nullable: false), + geometry = table.Column(type: "geometry", nullable: false), + is_removed = table.Column(type: "boolean", nullable: false), + @namespace = table.Column(name: "namespace", type: "text", nullable: false), + oslo_status = table.Column(type: "text", nullable: false), + puri = table.Column(type: "text", nullable: false), + status = table.Column(type: "text", nullable: false), + version_as_string = table.Column(type: "text", nullable: false), + version_timestamp = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_parcel_latest_items", x => x.parcel_id); + }); + + migrationBuilder.CreateIndex( + name: "IX_parcel_latest_item_addresses_address_persistent_local_id", + schema: "integration_parcel", + table: "parcel_latest_item_addresses", + column: "address_persistent_local_id"); + + migrationBuilder.CreateIndex( + name: "IX_parcel_latest_item_addresses_capakey", + schema: "integration_parcel", + table: "parcel_latest_item_addresses", + column: "capakey"); + + migrationBuilder.CreateIndex( + name: "IX_parcel_latest_item_addresses_parcel_id", + schema: "integration_parcel", + table: "parcel_latest_item_addresses", + column: "parcel_id"); + + migrationBuilder.CreateIndex( + name: "IX_parcel_latest_items_capakey", + schema: "integration_parcel", + table: "parcel_latest_items", + column: "capakey"); + + migrationBuilder.CreateIndex( + name: "IX_parcel_latest_items_geometry", + schema: "integration_parcel", + table: "parcel_latest_items", + column: "geometry") + .Annotation("Npgsql:IndexMethod", "GIST"); + + migrationBuilder.CreateIndex( + name: "IX_parcel_latest_items_is_removed", + schema: "integration_parcel", + table: "parcel_latest_items", + column: "is_removed"); + + migrationBuilder.CreateIndex( + name: "IX_parcel_latest_items_is_removed_status", + schema: "integration_parcel", + table: "parcel_latest_items", + columns: new[] { "is_removed", "status" }); + + migrationBuilder.CreateIndex( + name: "IX_parcel_latest_items_oslo_status", + schema: "integration_parcel", + table: "parcel_latest_items", + column: "oslo_status"); + + migrationBuilder.CreateIndex( + name: "IX_parcel_latest_items_status", + schema: "integration_parcel", + table: "parcel_latest_items", + column: "status"); + } + } +} diff --git a/src/ParcelRegistry.Projections.Integration/Migrations/IntegrationContextModelSnapshot.cs b/src/ParcelRegistry.Projections.Integration/Migrations/IntegrationContextModelSnapshot.cs index 63e0f3f0..4b755513 100644 --- a/src/ParcelRegistry.Projections.Integration/Migrations/IntegrationContextModelSnapshot.cs +++ b/src/ParcelRegistry.Projections.Integration/Migrations/IntegrationContextModelSnapshot.cs @@ -46,107 +46,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("ProjectionStates", "integration_parcel"); }); - modelBuilder.Entity("ParcelRegistry.Projections.Integration.ParcelLatestItem.ParcelLatestItem", b => - { - b.Property("ParcelId") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("parcel_id"); - - b.Property("CaPaKey") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("varchar") - .HasColumnName("capakey"); - - b.Property("Geometry") - .IsRequired() - .HasColumnType("geometry") - .HasColumnName("geometry"); - - b.Property("IsRemoved") - .HasColumnType("boolean") - .HasColumnName("is_removed"); - - b.Property("Namespace") - .IsRequired() - .HasColumnType("text") - .HasColumnName("namespace"); - - b.Property("OsloStatus") - .IsRequired() - .HasColumnType("text") - .HasColumnName("oslo_status"); - - b.Property("Puri") - .IsRequired() - .HasColumnType("text") - .HasColumnName("puri"); - - b.Property("Status") - .IsRequired() - .HasColumnType("text") - .HasColumnName("status"); - - b.Property("VersionAsString") - .IsRequired() - .HasColumnType("text") - .HasColumnName("version_as_string"); - - b.Property("VersionTimestampAsDateTimeOffset") - .HasColumnType("timestamp with time zone") - .HasColumnName("version_timestamp"); - - b.HasKey("ParcelId"); - - b.HasIndex("CaPaKey"); - - b.HasIndex("Geometry"); - - NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("Geometry"), "GIST"); - - b.HasIndex("IsRemoved"); - - b.HasIndex("OsloStatus"); - - b.HasIndex("Status"); - - b.HasIndex("IsRemoved", "Status"); - - b.ToTable("parcel_latest_items", "integration_parcel"); - }); - - modelBuilder.Entity("ParcelRegistry.Projections.Integration.ParcelLatestItem.ParcelLatestItemAddress", b => - { - b.Property("ParcelId") - .HasColumnType("uuid") - .HasColumnName("parcel_id"); - - b.Property("AddressPersistentLocalId") - .HasColumnType("integer") - .HasColumnName("address_persistent_local_id"); - - b.Property("CaPaKey") - .IsRequired() - .HasColumnType("text") - .HasColumnName("capakey"); - - b.Property("Count") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(1); - - b.HasKey("ParcelId", "AddressPersistentLocalId"); - - b.HasIndex("AddressPersistentLocalId"); - - b.HasIndex("CaPaKey"); - - b.HasIndex("ParcelId"); - - b.ToTable("parcel_latest_item_addresses", "integration_parcel"); - }); - modelBuilder.Entity("ParcelRegistry.Projections.Integration.ParcelLatestItemV2.ParcelLatestItemV2", b => { b.Property("ParcelId") diff --git a/src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItem.cs b/src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItem.cs deleted file mode 100644 index 631f4be4..00000000 --- a/src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItem.cs +++ /dev/null @@ -1,132 +0,0 @@ -namespace ParcelRegistry.Projections.Integration.ParcelLatestItem -{ - using System; - using Be.Vlaanderen.Basisregisters.GrAr.Common; - using Be.Vlaanderen.Basisregisters.Utilities; - using Microsoft.EntityFrameworkCore; - using Microsoft.EntityFrameworkCore.Metadata.Builders; - using NetTopologySuite.Geometries; - using NodaTime; - using ParcelRegistry.Infrastructure; - - public sealed class ParcelLatestItem - { - public const string VersionTimestampBackingPropertyName = nameof(VersionTimestampAsDateTimeOffset); - - public Guid ParcelId { get; set; } - public string CaPaKey { get; set; } - public string Status { get; set; } - public string OsloStatus { get; set; } - public Geometry Geometry { get; set; } - - public string Puri { get; set; } - public string Namespace { get; set; } - - public bool IsRemoved { get; set; } - - public string VersionAsString { get; set; } - private DateTimeOffset VersionTimestampAsDateTimeOffset { get; set; } - - public Instant VersionTimestamp - { - get => Instant.FromDateTimeOffset(VersionTimestampAsDateTimeOffset); - set - { - VersionTimestampAsDateTimeOffset = value.ToDateTimeOffset(); - VersionAsString = new Rfc3339SerializableDateTimeOffset(value.ToBelgianDateTimeOffset()).ToString(); - } - } - - public ParcelLatestItem( - Guid parcelId, - string caPaKey, - string status, - string osloStatus, - Geometry geometry, - string puri, - string ns, - bool isRemoved, - Instant versionTimestamp) - { - ParcelId = parcelId; - CaPaKey = caPaKey; - Status = status; - OsloStatus = osloStatus; - Geometry = geometry; - Puri = puri; - Namespace = ns; - IsRemoved = isRemoved; - VersionTimestamp = versionTimestamp; - } - - // This needs to be here to please EF - protected ParcelLatestItem() - { } - } - - public sealed class ParcelLatestItemConfiguration : IEntityTypeConfiguration - { - public void Configure(EntityTypeBuilder builder) - { - builder - .ToTable("parcel_latest_items", Schema.Integration) - .HasKey(parcel => parcel.ParcelId); - - builder - .Property(parcel => parcel.ParcelId) - .HasColumnName("parcel_id"); - - builder - .Property(parcel => parcel.CaPaKey) - .HasColumnName("capakey") - .HasColumnType("varchar") - .HasMaxLength(20) - .IsRequired(); - - builder - .Property(parcel => parcel.Status) - .HasColumnName("status") - .IsRequired(); - - builder - .Property(parcel => parcel.OsloStatus) - .HasColumnName("oslo_status") - .IsRequired(); - - builder - .Property(parcel => parcel.Puri) - .HasColumnName("puri") - .IsRequired(); - - builder - .Property(parcel => parcel.Namespace) - .HasColumnName("namespace") - .IsRequired(); - - builder - .Property(parcel => parcel.IsRemoved) - .HasColumnName("is_removed") - .HasColumnType("boolean") - .IsRequired(); - - builder - .Property(parcel => parcel.Geometry) - .HasColumnName("geometry") - .IsRequired(); - - builder.Property(parcel => parcel.VersionAsString).HasColumnName("version_as_string"); - builder.Property(ParcelLatestItem.VersionTimestampBackingPropertyName).HasColumnName("version_timestamp"); - - builder.Ignore(parcel => parcel.VersionTimestamp); - - builder.HasIndex(parcel => parcel.CaPaKey); - builder.HasIndex(parcel => parcel.Status); - builder.HasIndex(parcel => parcel.OsloStatus); - builder.HasIndex(parcel => parcel.IsRemoved); - builder.HasIndex(x => new { x.IsRemoved, x.Status }); - builder - .HasIndex(parcel => parcel.Geometry) - .HasMethod("GIST"); - } - } -} diff --git a/src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItemAddress.cs b/src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItemAddress.cs deleted file mode 100644 index db8e71d6..00000000 --- a/src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItemAddress.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace ParcelRegistry.Projections.Integration.ParcelLatestItem -{ - using System; - using Microsoft.EntityFrameworkCore; - using Microsoft.EntityFrameworkCore.Metadata.Builders; - using ParcelRegistry.Infrastructure; - - public sealed class ParcelLatestItemAddress - { - public Guid ParcelId { get; set; } - public int AddressPersistentLocalId { get; set; } - public string CaPaKey { get; set; } - public int Count { get; set; } - - public ParcelLatestItemAddress(Guid parcelId, int addressPersistentLocalId, string caPaKey) - { - ParcelId = parcelId; - AddressPersistentLocalId = addressPersistentLocalId; - CaPaKey = caPaKey; - Count = 1; - } - - // Needed for EF - protected ParcelLatestItemAddress() - { } - } - - public sealed class ParcelLatestItemAddressConfiguration : IEntityTypeConfiguration - { - public void Configure(EntityTypeBuilder builder) - { - builder - .ToTable("parcel_latest_item_addresses", Schema.Integration) - .HasKey(e => new { e.ParcelId, e.AddressPersistentLocalId }); - - builder.Property(e => e.ParcelId) - .HasColumnName("parcel_id") - .IsRequired(); - - builder.Property(e => e.AddressPersistentLocalId) - .HasColumnName("address_persistent_local_id") - .IsRequired(); - - builder.Property(e => e.CaPaKey) - .HasColumnName("capakey") - .IsRequired(); - - builder.Property(e => e.Count) - .HasDefaultValue(1); - - builder.HasIndex(x => x.ParcelId); - builder.HasIndex(x => x.AddressPersistentLocalId); - builder.HasIndex(x => x.CaPaKey); - } - } -} diff --git a/src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItemExtensions.cs b/src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItemExtensions.cs deleted file mode 100644 index 9be46c84..00000000 --- a/src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItemExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace ParcelRegistry.Projections.Integration.ParcelLatestItem -{ - using System; - using System.Threading; - using System.Threading.Tasks; - using Be.Vlaanderen.Basisregisters.GrAr.Legacy.Perceel; - using Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector; - using Parcel; - - public static class ParcelLatestItemExtensions - { - public static async Task FindAndUpdateParcel( - this IntegrationContext context, - Guid parcelId, - Action updateFunc, - CancellationToken ct) - { - var latestItem = await context - .ParcelLatestItems - .FindAsync(parcelId, cancellationToken: ct); - - if (latestItem == null) - throw DatabaseItemNotFound(parcelId); - - updateFunc(latestItem); - - return latestItem; - } - - private static ProjectionItemNotFoundException DatabaseItemNotFound(Guid parcelId) - => new ProjectionItemNotFoundException(parcelId.ToString("D")); - } -} diff --git a/src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItemProjections.cs b/src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItemProjections.cs deleted file mode 100644 index d9624d02..00000000 --- a/src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItemProjections.cs +++ /dev/null @@ -1,220 +0,0 @@ -namespace ParcelRegistry.Projections.Integration.ParcelLatestItem -{ - using System; - using System.Threading; - using System.Threading.Tasks; - using Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector; - using Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore; - using Converters; - using Infrastructure; - using Microsoft.EntityFrameworkCore; - using Microsoft.Extensions.Options; - using NodaTime; - using Parcel; - using Parcel.Events; - - [ConnectedProjectionName("Integratie perceel latest item")] - [ConnectedProjectionDescription("Projectie die de laatste perceel data voor de integratie database bijhoudt.")] - public sealed class ParcelLatestItemProjections : ConnectedProjection - { - public ParcelLatestItemProjections(IOptions options) - { - When>(async (context, message, ct) => - { - await context - .ParcelLatestItems - .AddAsync(new ParcelLatestItem( - message.Message.ParcelId, - message.Message.CaPaKey, - message.Message.ParcelStatus, - ParcelStatus.Parse(message.Message.ParcelStatus).ConvertFromParcelStatus(), - ParcelMapper.MapExtendedWkbGeometryToGeometry(message.Message.ExtendedWkbGeometry), - $"{options.Value.Namespace}/{message.Message.CaPaKey}", - options.Value.Namespace, - message.Message.IsRemoved, - message.Message.Provenance.Timestamp), ct); - - foreach (var addressPersistentLocalId in message.Message.AddressPersistentLocalIds) - { - await context - .ParcelLatestItemAddresses - .AddAsync(new ParcelLatestItemAddress( - message.Message.ParcelId, - addressPersistentLocalId, - message.Message.CaPaKey), ct); - } - }); - - When>(async (context, message, ct) => - { - await context - .ParcelLatestItems - .AddAsync(new ParcelLatestItem( - message.Message.ParcelId, - message.Message.CaPaKey, - ParcelStatus.Realized, - ParcelStatus.Realized.ConvertFromParcelStatus(), - ParcelMapper.MapExtendedWkbGeometryToGeometry(message.Message.ExtendedWkbGeometry), - $"{options.Value.Namespace}/{message.Message.CaPaKey}", - options.Value.Namespace, - false, - message.Message.Provenance.Timestamp), ct); - }); - - When>(async (context, message, ct) => - { - await context.FindAndUpdateParcel( - message.Message.ParcelId, - parcel => - { - parcel.Geometry = ParcelMapper.MapExtendedWkbGeometryToGeometry(message.Message.ExtendedWkbGeometry); - UpdateVersionTimestamp(parcel, message.Message.Provenance.Timestamp); - }, ct); - }); - - When>(async (context, message, ct) => - { - await context.FindAndUpdateParcel( - message.Message.ParcelId, - parcel => - { - parcel.Status = ParcelStatus.Realized; - parcel.OsloStatus = ParcelStatus.Realized.ConvertFromParcelStatus(); - parcel.Geometry = ParcelMapper.MapExtendedWkbGeometryToGeometry(message.Message.ExtendedWkbGeometry); - UpdateVersionTimestamp(parcel, message.Message.Provenance.Timestamp); - }, ct); - }); - - When>(async (context, message, ct) => - { - await context.FindAndUpdateParcel( - message.Message.ParcelId, - parcel => - { - parcel.Status = ParcelStatus.Retired; - parcel.OsloStatus = ParcelStatus.Retired.ConvertFromParcelStatus(); - UpdateVersionTimestamp(parcel, message.Message.Provenance.Timestamp); - }, ct); - }); - - When>(async (context, message, ct) => - { - await AddParcelAddress(context, message.Message.ParcelId, message.Message.CaPaKey, message.Message.AddressPersistentLocalId, ct); - }); - - When>(async (context, message, ct) => - { - await RemoveParcelAddress(context, message.Message.ParcelId, message.Message.PreviousAddressPersistentLocalId, ct); - await AddParcelAddress(context, message.Message.ParcelId, message.Message.CaPaKey, message.Message.NewAddressPersistentLocalId, ct); - }); - - When>(async (context, message, ct) => - { - var previousAddress = await context - .ParcelLatestItemAddresses - .FindAsync([message.Message.ParcelId, message.Message.PreviousAddressPersistentLocalId], cancellationToken: ct); - - if (previousAddress is not null && previousAddress.Count == 1) - { - context.ParcelLatestItemAddresses.Remove(previousAddress); - } - else if (previousAddress is not null) - { - previousAddress.Count -= 1; - } - - var newAddress = await context - .ParcelLatestItemAddresses - .FindAsync([message.Message.ParcelId, message.Message.NewAddressPersistentLocalId], cancellationToken: ct); - - if (newAddress is null || context.Entry(newAddress).State == EntityState.Deleted) - { - await context - .ParcelLatestItemAddresses - .AddAsync(new ParcelLatestItemAddress( - message.Message.ParcelId, - message.Message.NewAddressPersistentLocalId, - message.Message.CaPaKey), ct); - } - else - { - newAddress.Count += 1; - } - }); - - When>(async (context, message, ct) => - { - foreach (var addressPersistentLocalId in message.Message.DetachedAddressPersistentLocalIds) - { - await RemoveParcelAddress(context, message.Message.ParcelId, addressPersistentLocalId, ct); - } - - foreach (var addressPersistentLocalId in message.Message.AttachedAddressPersistentLocalIds) - { - await AddParcelAddress(context, message.Message.ParcelId, message.Message.CaPaKey, addressPersistentLocalId, ct); - } - }); - - When>(async (context, message, ct) => - { - await RemoveParcelAddress(context, message.Message.ParcelId, message.Message.AddressPersistentLocalId, ct); - }); - - When>(async (context, message, ct) => - { - await RemoveParcelAddress(context, message.Message.ParcelId, message.Message.AddressPersistentLocalId, ct); - }); - - When>(async (context, message, ct) => - { - await RemoveParcelAddress(context, message.Message.ParcelId, message.Message.AddressPersistentLocalId, ct); - }); - - When>(async (context, message, ct) => - { - await RemoveParcelAddress(context, message.Message.ParcelId, message.Message.AddressPersistentLocalId, ct); - }); - } - - private static async Task RemoveParcelAddress( - IntegrationContext context, - Guid parcelId, - int addressPersistentLocalId, - CancellationToken ct) - { - var latestItemAddress = await context - .ParcelLatestItemAddresses - .FindAsync(new object?[] { parcelId, addressPersistentLocalId }, cancellationToken: ct); - - if (latestItemAddress is not null) - { - context.ParcelLatestItemAddresses.Remove(latestItemAddress); - } - } - - private static async Task AddParcelAddress( - IntegrationContext context, - Guid parcelId, - string caPaKey, - int addressPersistentLocalId, - CancellationToken ct) - { - var newAddress = await context - .ParcelLatestItemAddresses - .FindAsync([parcelId, addressPersistentLocalId], cancellationToken: ct); - - if (newAddress is null || context.Entry(newAddress).State == EntityState.Deleted) - { - await context - .ParcelLatestItemAddresses - .AddAsync(new ParcelLatestItemAddress( - parcelId, - addressPersistentLocalId, - caPaKey), ct); - } - } - - private static void UpdateVersionTimestamp(ParcelLatestItem parcel, Instant versionTimestamp) - => parcel.VersionTimestamp = versionTimestamp; - } -} diff --git a/src/ParcelRegistry.Projector/Infrastructure/Modules/ApiModule.cs b/src/ParcelRegistry.Projector/Infrastructure/Modules/ApiModule.cs index 5cf95c59..ffaa7aad 100644 --- a/src/ParcelRegistry.Projector/Infrastructure/Modules/ApiModule.cs +++ b/src/ParcelRegistry.Projector/Infrastructure/Modules/ApiModule.cs @@ -19,7 +19,6 @@ namespace ParcelRegistry.Projector.Infrastructure.Modules using ParcelRegistry.Projections.Extract.ParcelExtract; using ParcelRegistry.Projections.Integration; using ParcelRegistry.Projections.Integration.Infrastructure; - using ParcelRegistry.Projections.Integration.ParcelLatestItem; using ParcelRegistry.Projections.Integration.ParcelLatestItemV2; using ParcelRegistry.Projections.Integration.ParcelVersion; using ParcelRegistry.Projections.LastChangedList; @@ -133,9 +132,6 @@ private void RegisterIntegrationProjections(ContainerBuilder builder) .RegisterProjectionMigrator( _configuration, _loggerFactory) - .RegisterProjections( - context => new ParcelLatestItemProjections(context.Resolve>()), - ConnectedProjectionSettings.Default) .RegisterProjections( context => new ParcelLatestItemV2Projections(context.Resolve>()), ConnectedProjectionSettings.Default) diff --git a/test/ParcelRegistry.Tests/ProjectionTests/Integration/ParcelLatestItemProjectionTests-Readdress.cs b/test/ParcelRegistry.Tests/ProjectionTests/Integration/ParcelLatestItemProjectionTests-Readdress.cs index 9225081d..2cbac44f 100644 --- a/test/ParcelRegistry.Tests/ProjectionTests/Integration/ParcelLatestItemProjectionTests-Readdress.cs +++ b/test/ParcelRegistry.Tests/ProjectionTests/Integration/ParcelLatestItemProjectionTests-Readdress.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using AutoFixture; using Builders; + using EventExtensions; using Fixtures; using FluentAssertions; using Parcel; @@ -20,6 +21,7 @@ public async Task GivenOnlyPreviousParcelAddressRelationExistsWithCountOne_ThenR _fixture.Create(), newAddressPersistentLocalId: new AddressPersistentLocalId(parcelAddressWasAttachedV2.AddressPersistentLocalId + 1), previousAddressPersistentLocalId: new AddressPersistentLocalId(parcelAddressWasAttachedV2.AddressPersistentLocalId)); + @event.SetFixtureProvenance(_fixture); await Sut .Given( @@ -28,12 +30,16 @@ await Sut @event) .Then(async context => { - var previousRelation = await context.ParcelLatestItemAddresses.FindAsync( + var latestItem = await context.ParcelLatestItemsV2.FindAsync(@event.ParcelId); + latestItem.Should().NotBeNull(); + latestItem!.VersionTimestamp.Should().Be(@event.Provenance.Timestamp); + + var previousRelation = await context.ParcelLatestItemV2Addresses.FindAsync( @event.ParcelId, @event.PreviousAddressPersistentLocalId); previousRelation.Should().BeNull(); - var newRelation = await context.ParcelLatestItemAddresses.FindAsync( + var newRelation = await context.ParcelLatestItemV2Addresses.FindAsync( @event.ParcelId, @event.NewAddressPersistentLocalId); newRelation.Should().NotBeNull(); @@ -51,12 +57,14 @@ public async Task GivenPreviousParcelAddressRelationExistsWithCountTwo_ThenCount _fixture.Create(), newAddressPersistentLocalId: new AddressPersistentLocalId(parcelAddressWasAttachedV2.AddressPersistentLocalId), previousAddressPersistentLocalId: new AddressPersistentLocalId(parcelAddressWasAttachedV2.AddressPersistentLocalId + 100)); + eventToAddPreviousRelationASecondTime.SetFixtureProvenance(_fixture); var @event = new ParcelAddressWasReplacedBecauseAddressWasReaddressed( _fixture.Create(), _fixture.Create(), newAddressPersistentLocalId: new AddressPersistentLocalId(parcelAddressWasAttachedV2.AddressPersistentLocalId + 101), previousAddressPersistentLocalId: new AddressPersistentLocalId(parcelAddressWasAttachedV2.AddressPersistentLocalId)); + @event.SetFixtureProvenance(_fixture); await Sut .Given( @@ -66,13 +74,17 @@ await Sut @event) .Then(async context => { - var previousRelation = await context.ParcelLatestItemAddresses.FindAsync( + var latestItem = await context.ParcelLatestItemsV2.FindAsync(@event.ParcelId); + latestItem.Should().NotBeNull(); + latestItem!.VersionTimestamp.Should().Be(@event.Provenance.Timestamp); + + var previousRelation = await context.ParcelLatestItemV2Addresses.FindAsync( @event.ParcelId, @event.PreviousAddressPersistentLocalId); previousRelation.Should().NotBeNull(); previousRelation!.Count.Should().Be(1); - var newRelation = await context.ParcelLatestItemAddresses.FindAsync( + var newRelation = await context.ParcelLatestItemV2Addresses.FindAsync( @event.ParcelId, @event.NewAddressPersistentLocalId); newRelation.Should().NotBeNull(); @@ -92,6 +104,7 @@ public async Task GivenNewParcelAddressRelationsExists_ThenCountIsIncrementedByO _fixture.Create(), newAddressPersistentLocalId: new AddressPersistentLocalId(newParcelAddressWasAttachedV2.AddressPersistentLocalId), previousAddressPersistentLocalId: new AddressPersistentLocalId(previousParcelAddressWasAttachedV2.AddressPersistentLocalId)); + @event.SetFixtureProvenance(_fixture); await Sut .Given( @@ -101,12 +114,16 @@ await Sut @event) .Then(async context => { - var previousRelation = await context.ParcelLatestItemAddresses.FindAsync( + var latestItem = await context.ParcelLatestItemsV2.FindAsync(@event.ParcelId); + latestItem.Should().NotBeNull(); + latestItem!.VersionTimestamp.Should().Be(@event.Provenance.Timestamp); + + var previousRelation = await context.ParcelLatestItemV2Addresses.FindAsync( @event.ParcelId, @event.PreviousAddressPersistentLocalId); previousRelation.Should().BeNull(); - var newRelation = await context.ParcelLatestItemAddresses.FindAsync( + var newRelation = await context.ParcelLatestItemV2Addresses.FindAsync( @event.ParcelId, @event.NewAddressPersistentLocalId); newRelation.Should().NotBeNull(); @@ -158,7 +175,7 @@ await Sut { foreach (var addressPersistentLocalId in attachedAddressPersistentLocalIds) { - var parcelAddressRelation = await context.ParcelLatestItemAddresses.FindAsync( + var parcelAddressRelation = await context.ParcelLatestItemV2Addresses.FindAsync( @event.ParcelId, addressPersistentLocalId); @@ -168,7 +185,7 @@ await Sut foreach (var addressPersistentLocalId in detachedAddressPersistentLocalIds) { - var parcelAddressRelation = await context.ParcelLatestItemAddresses.FindAsync( + var parcelAddressRelation = await context.ParcelLatestItemV2Addresses.FindAsync( @event.ParcelId, addressPersistentLocalId); diff --git a/test/ParcelRegistry.Tests/ProjectionTests/Integration/ParcelLatestItemProjectionTests.cs b/test/ParcelRegistry.Tests/ProjectionTests/Integration/ParcelLatestItemProjectionTests.cs index 17eb674c..55f696c7 100644 --- a/test/ParcelRegistry.Tests/ProjectionTests/Integration/ParcelLatestItemProjectionTests.cs +++ b/test/ParcelRegistry.Tests/ProjectionTests/Integration/ParcelLatestItemProjectionTests.cs @@ -7,16 +7,17 @@ using Be.Vlaanderen.Basisregisters.GrAr.Provenance; using Be.Vlaanderen.Basisregisters.Utilities; using Be.Vlaanderen.Basisregisters.Utilities.HexByteConvertor; + using EventExtensions; using Fixtures; using FluentAssertions; using Microsoft.Extensions.Options; using Parcel; using Parcel.Events; using Projections.Integration.Infrastructure; - using Projections.Integration.ParcelLatestItem; + using Projections.Integration.ParcelLatestItemV2; using Xunit; - public partial class ParcelLatestItemProjectionTests : IntegrationProjectionTest + public partial class ParcelLatestItemProjectionTests : IntegrationProjectionTest { private readonly Fixture _fixture; private const string Namespace = "https://data.vlaanderen.be/id/perceel"; @@ -32,7 +33,7 @@ public ParcelLatestItemProjectionTests() } [Fact] - public async Task WhenParcelWasMigrated() + public async Task GivenParcelWasMigrated() { var message = _fixture.Create(); @@ -41,7 +42,7 @@ await Sut.Given(message) { var geometry = WKBReaderFactory.Create().Read(message.ExtendedWkbGeometry.ToByteArray()); - var latestItem = await context.ParcelLatestItems.FindAsync(message.ParcelId); + var latestItem = await context.ParcelLatestItemsV2.FindAsync(message.ParcelId); latestItem.Should().NotBeNull(); latestItem!.CaPaKey.Should().Be(message.CaPaKey); latestItem.Status.Should().Be(ParcelStatus.Parse(message.ParcelStatus)); @@ -57,7 +58,7 @@ await Sut.Given(message) foreach (var addressPersistentLocalId in message.AddressPersistentLocalIds) { await context - .ParcelLatestItemAddresses + .ParcelLatestItemV2Addresses .FindAsync(message.ParcelId, addressPersistentLocalId); latestItem.Should().NotBeNull(); latestItem.CaPaKey.Should().Be(message.CaPaKey); @@ -66,7 +67,7 @@ await context } [Fact] - public async Task WhenParcelIsImported() + public async Task GivenParcelIsImported() { var message = _fixture.Create(); @@ -75,7 +76,7 @@ await Sut.Given(message) { var geometry = WKBReaderFactory.Create().Read(message.ExtendedWkbGeometry.ToByteArray()); - var latestItem = await context.ParcelLatestItems.FindAsync(message.ParcelId); + var latestItem = await context.ParcelLatestItemsV2.FindAsync(message.ParcelId); latestItem.Should().NotBeNull(); latestItem!.CaPaKey.Should().Be(message.CaPaKey); latestItem.Status.Should().Be(ParcelStatus.Realized); @@ -91,7 +92,7 @@ await Sut.Given(message) } [Fact] - public async Task WhenParcelGeometryWasChanged() + public async Task GivenParcelGeometryWasChanged() { var parcelWasImported = _fixture.Create(); var message = new ParcelGeometryWasChanged( @@ -106,7 +107,7 @@ await Sut { var geometry = WKBReaderFactory.Create().Read(message.ExtendedWkbGeometry.ToByteArray()); - var latestItem = await context.ParcelLatestItems.FindAsync(message.ParcelId); + var latestItem = await context.ParcelLatestItemsV2.FindAsync(message.ParcelId); latestItem.Should().NotBeNull(); latestItem!.VersionTimestamp.Should().Be(message.Provenance.Timestamp); latestItem.VersionAsString.Should() @@ -116,7 +117,7 @@ await Sut } [Fact] - public async Task WhenParcelWasCorrectedFromRetiredToRealized() + public async Task GivenParcelWasCorrectedFromRetiredToRealized() { var message = _fixture.Create(); @@ -126,7 +127,7 @@ await Sut { var geometry = WKBReaderFactory.Create().Read(message.ExtendedWkbGeometry.ToByteArray()); - var latestItem = await context.ParcelLatestItems.FindAsync(message.ParcelId); + var latestItem = await context.ParcelLatestItemsV2.FindAsync(message.ParcelId); latestItem.Should().NotBeNull(); latestItem!.Status.Should().Be(ParcelStatus.Realized); latestItem.OsloStatus.Should().Be("Gerealiseerd"); @@ -138,7 +139,7 @@ await Sut } [Fact] - public async Task WhenParcelWasRetiredV2() + public async Task GivenParcelWasRetiredV2() { var message = _fixture.Create(); @@ -146,7 +147,7 @@ await Sut .Given(_fixture.Create(), message) .Then(async context => { - var latestItem = await context.ParcelLatestItems.FindAsync(message.ParcelId); + var latestItem = await context.ParcelLatestItemsV2.FindAsync(message.ParcelId); latestItem.Should().NotBeNull(); latestItem!.Status.Should().Be(ParcelStatus.Retired); latestItem.OsloStatus.Should().Be("Gehistoreerd"); @@ -158,7 +159,7 @@ await Sut } [Fact] - public async Task WhenParcelAddressWasAttachedV2() + public async Task GivenParcelAddressWasAttachedV2() { var message = _fixture.Create(); @@ -166,86 +167,110 @@ await Sut .Given(_fixture.Create(), message) .Then(async context => { - var latestItem = await context.ParcelLatestItemAddresses.FindAsync(message.ParcelId, message.AddressPersistentLocalId); + var latestItem = await context.ParcelLatestItemsV2.FindAsync(message.ParcelId); latestItem.Should().NotBeNull(); - latestItem!.CaPaKey.Should().Be(message.CaPaKey); + latestItem!.VersionTimestamp.Should().Be(message.Provenance.Timestamp); + + var latestItemAddress = await context.ParcelLatestItemV2Addresses.FindAsync(message.ParcelId, message.AddressPersistentLocalId); + latestItemAddress.Should().NotBeNull(); + latestItemAddress!.CaPaKey.Should().Be(message.CaPaKey); }); } [Fact] - public async Task WhenParcelAddressWasDetachedV2() + public async Task GivenParcelAddressWasDetachedV2() { var attached = _fixture.Create(); var message = new ParcelAddressWasDetachedV2( new ParcelId(attached.ParcelId), new VbrCaPaKey(attached.CaPaKey), new AddressPersistentLocalId(attached.AddressPersistentLocalId)); + message.SetFixtureProvenance(_fixture); await Sut .Given(_fixture.Create(), attached, message) .Then(async context => { - var latestItem = await context.ParcelLatestItemAddresses.FindAsync(message.ParcelId, message.AddressPersistentLocalId); - latestItem.Should().BeNull(); + var latestItem = await context.ParcelLatestItemsV2.FindAsync(message.ParcelId); + latestItem.Should().NotBeNull(); + latestItem!.VersionTimestamp.Should().Be(message.Provenance.Timestamp); + + var latestItemAddress = await context.ParcelLatestItemV2Addresses.FindAsync(message.ParcelId, message.AddressPersistentLocalId); + latestItemAddress.Should().BeNull(); }); } [Fact] - public async Task WhenParcelAddressWasDetachedBecauseAddressWasRejected() + public async Task GivenParcelAddressWasDetachedBecauseAddressWasRejected() { var attached = _fixture.Create(); var message = new ParcelAddressWasDetachedBecauseAddressWasRejected( new ParcelId(attached.ParcelId), new VbrCaPaKey(attached.CaPaKey), new AddressPersistentLocalId(attached.AddressPersistentLocalId)); + message.SetFixtureProvenance(_fixture); await Sut .Given(_fixture.Create(), attached, message) .Then(async context => { - var latestItem = await context.ParcelLatestItemAddresses.FindAsync(message.ParcelId, message.AddressPersistentLocalId); - latestItem.Should().BeNull(); + var latestItem = await context.ParcelLatestItemsV2.FindAsync(message.ParcelId); + latestItem.Should().NotBeNull(); + latestItem!.VersionTimestamp.Should().Be(message.Provenance.Timestamp); + + var latestItemAddress = await context.ParcelLatestItemV2Addresses.FindAsync(message.ParcelId, message.AddressPersistentLocalId); + latestItemAddress.Should().BeNull(); }); } [Fact] - public async Task WhenParcelAddressWasDetachedBecauseAddressWasRemoved() + public async Task GivenParcelAddressWasDetachedBecauseAddressWasRemoved() { var attached = _fixture.Create(); var message = new ParcelAddressWasDetachedBecauseAddressWasRemoved( new ParcelId(attached.ParcelId), new VbrCaPaKey(attached.CaPaKey), new AddressPersistentLocalId(attached.AddressPersistentLocalId)); + message.SetFixtureProvenance(_fixture); await Sut .Given(_fixture.Create(), attached, message) .Then(async context => { - var latestItem = await context.ParcelLatestItemAddresses.FindAsync(message.ParcelId, message.AddressPersistentLocalId); - latestItem.Should().BeNull(); + var latestItem = await context.ParcelLatestItemsV2.FindAsync(message.ParcelId); + latestItem.Should().NotBeNull(); + latestItem!.VersionTimestamp.Should().Be(message.Provenance.Timestamp); + + var latestItemAddress = await context.ParcelLatestItemV2Addresses.FindAsync(message.ParcelId, message.AddressPersistentLocalId); + latestItemAddress.Should().BeNull(); }); } [Fact] - public async Task WhenParcelAddressWasDetachedBecauseAddressWasRetired() + public async Task GivenParcelAddressWasDetachedBecauseAddressWasRetired() { var attached = _fixture.Create(); var message = new ParcelAddressWasDetachedBecauseAddressWasRetired( new ParcelId(attached.ParcelId), new VbrCaPaKey(attached.CaPaKey), new AddressPersistentLocalId(attached.AddressPersistentLocalId)); + message.SetFixtureProvenance(_fixture); await Sut .Given(_fixture.Create(), attached, message) .Then(async context => { - var latestItem = await context.ParcelLatestItemAddresses.FindAsync(message.ParcelId, message.AddressPersistentLocalId); - latestItem.Should().BeNull(); + var latestItem = await context.ParcelLatestItemsV2.FindAsync(message.ParcelId); + latestItem.Should().NotBeNull(); + latestItem!.VersionTimestamp.Should().Be(message.Provenance.Timestamp); + + var latestItemAddress = await context.ParcelLatestItemV2Addresses.FindAsync(message.ParcelId, message.AddressPersistentLocalId); + latestItemAddress.Should().BeNull(); }); } [Fact] - public async Task WhenParcelAddressWasReplacedBecauseOfMunicipalityMerger() + public async Task GivenParcelAddressWasReplacedBecauseOfMunicipalityMerger() { var attached = _fixture.Create(); @@ -254,21 +279,26 @@ public async Task WhenParcelAddressWasReplacedBecauseOfMunicipalityMerger() new VbrCaPaKey(attached.CaPaKey), new AddressPersistentLocalId(attached.AddressPersistentLocalId + 1), new AddressPersistentLocalId(attached.AddressPersistentLocalId)); + message.SetFixtureProvenance(_fixture); await Sut .Given(_fixture.Create(), message) .Then(async context => { - var previousLatestItem = await context.ParcelLatestItemAddresses.FindAsync(message.ParcelId, message.PreviousAddressPersistentLocalId); - previousLatestItem.Should().BeNull(); + var latestItem = await context.ParcelLatestItemsV2.FindAsync(message.ParcelId); + latestItem.Should().NotBeNull(); + latestItem!.VersionTimestamp.Should().Be(message.Provenance.Timestamp); + + var previousAddressLatestItem = await context.ParcelLatestItemV2Addresses.FindAsync(message.ParcelId, message.PreviousAddressPersistentLocalId); + previousAddressLatestItem.Should().BeNull(); - var newLatestItem = await context.ParcelLatestItemAddresses.FindAsync(message.ParcelId, message.NewAddressPersistentLocalId); - newLatestItem.Should().NotBeNull(); - newLatestItem!.CaPaKey.Should().Be(message.CaPaKey); + var newAddressLatestItem = await context.ParcelLatestItemV2Addresses.FindAsync(message.ParcelId, message.NewAddressPersistentLocalId); + newAddressLatestItem.Should().NotBeNull(); + newAddressLatestItem!.CaPaKey.Should().Be(message.CaPaKey); }); } - protected override ParcelLatestItemProjections CreateProjection() + protected override ParcelLatestItemV2Projections CreateProjection() => new(new OptionsWrapper(new IntegrationOptions{Namespace = Namespace })); } }