From 09aa75d6e12317816a44b2ad91af201948ab5ee1 Mon Sep 17 00:00:00 2001
From: ArneD <dumarey.arne@gmail.com>
Date: Thu, 21 Nov 2024 09:59:00 +0100
Subject: [PATCH] feat(integration): remove v1 tables GAWR-6666

---
 .../IntegrationContext.cs                     |   3 -
 ...41121085725_RemoveLatestItemV1.Designer.cs | 281 ++++++++++++++++++
 .../20241121085725_RemoveLatestItemV1.cs      | 119 ++++++++
 .../IntegrationContextModelSnapshot.cs        | 101 -------
 .../ParcelLatestItem/ParcelLatestItem.cs      | 132 --------
 .../ParcelLatestItemAddress.cs                |  56 ----
 .../ParcelLatestItemExtensions.cs             |  33 --
 .../ParcelLatestItemProjections.cs            | 220 --------------
 .../Infrastructure/Modules/ApiModule.cs       |   4 -
 ...rcelLatestItemProjectionTests-Readdress.cs |  33 +-
 .../ParcelLatestItemProjectionTests.cs        | 100 ++++---
 11 files changed, 490 insertions(+), 592 deletions(-)
 create mode 100644 src/ParcelRegistry.Projections.Integration/Migrations/20241121085725_RemoveLatestItemV1.Designer.cs
 create mode 100644 src/ParcelRegistry.Projections.Integration/Migrations/20241121085725_RemoveLatestItemV1.cs
 delete mode 100644 src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItem.cs
 delete mode 100644 src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItemAddress.cs
 delete mode 100644 src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItemExtensions.cs
 delete mode 100644 src/ParcelRegistry.Projections.Integration/ParcelLatestItem/ParcelLatestItemProjections.cs

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<IntegrationContext>
     {
         public override string ProjectionStateSchema => Schema.Integration;
 
-        public DbSet<ParcelLatestItem.ParcelLatestItem> ParcelLatestItems => Set<ParcelLatestItem.ParcelLatestItem>();
         public DbSet<ParcelVersion.ParcelVersion> ParcelVersions => Set<ParcelVersion.ParcelVersion>();
-        public DbSet<ParcelLatestItemAddress> ParcelLatestItemAddresses => Set<ParcelLatestItemAddress>();
         public DbSet<ParcelVersionAddress> ParcelVersionAddresses => Set<ParcelVersionAddress>();
 
         public DbSet<ParcelLatestItemV2.ParcelLatestItemV2> ParcelLatestItemsV2 => Set<ParcelLatestItemV2.ParcelLatestItemV2>();
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 @@
+// <auto-generated />
+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
+    {
+        /// <inheritdoc />
+        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<string>("Name")
+                        .HasColumnType("text");
+
+                    b.Property<string>("DesiredState")
+                        .HasColumnType("text");
+
+                    b.Property<DateTimeOffset?>("DesiredStateChangedAt")
+                        .HasColumnType("timestamp with time zone");
+
+                    b.Property<string>("ErrorMessage")
+                        .HasColumnType("text");
+
+                    b.Property<long>("Position")
+                        .HasColumnType("bigint");
+
+                    b.HasKey("Name");
+
+                    b.ToTable("ProjectionStates", "integration_parcel");
+                });
+
+            modelBuilder.Entity("ParcelRegistry.Projections.Integration.ParcelLatestItemV2.ParcelLatestItemV2", b =>
+                {
+                    b.Property<Guid>("ParcelId")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("uuid")
+                        .HasColumnName("parcel_id");
+
+                    b.Property<string>("CaPaKey")
+                        .IsRequired()
+                        .HasMaxLength(20)
+                        .HasColumnType("varchar")
+                        .HasColumnName("capakey");
+
+                    b.Property<Geometry>("Geometry")
+                        .IsRequired()
+                        .HasColumnType("geometry")
+                        .HasColumnName("geometry");
+
+                    b.Property<bool>("IsRemoved")
+                        .HasColumnType("boolean")
+                        .HasColumnName("is_removed");
+
+                    b.Property<string>("Namespace")
+                        .IsRequired()
+                        .HasColumnType("text")
+                        .HasColumnName("namespace");
+
+                    b.Property<string>("OsloStatus")
+                        .IsRequired()
+                        .HasColumnType("text")
+                        .HasColumnName("oslo_status");
+
+                    b.Property<string>("Puri")
+                        .IsRequired()
+                        .HasColumnType("text")
+                        .HasColumnName("puri");
+
+                    b.Property<string>("Status")
+                        .IsRequired()
+                        .HasColumnType("text")
+                        .HasColumnName("status");
+
+                    b.Property<string>("VersionAsString")
+                        .IsRequired()
+                        .HasColumnType("text")
+                        .HasColumnName("version_as_string");
+
+                    b.Property<DateTimeOffset>("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<Guid>("ParcelId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("parcel_id");
+
+                    b.Property<int>("AddressPersistentLocalId")
+                        .HasColumnType("integer")
+                        .HasColumnName("address_persistent_local_id");
+
+                    b.Property<string>("CaPaKey")
+                        .IsRequired()
+                        .HasColumnType("text")
+                        .HasColumnName("capakey");
+
+                    b.Property<int>("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<long>("Position")
+                        .HasColumnType("bigint")
+                        .HasColumnName("position");
+
+                    b.Property<Guid>("ParcelId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("parcel_id");
+
+                    b.Property<string>("CaPaKey")
+                        .IsRequired()
+                        .HasMaxLength(20)
+                        .HasColumnType("varchar")
+                        .HasColumnName("capakey");
+
+                    b.Property<string>("CreatedOnAsString")
+                        .IsRequired()
+                        .HasColumnType("text")
+                        .HasColumnName("created_on_as_string");
+
+                    b.Property<DateTimeOffset>("CreatedOnTimestampAsDateTimeOffset")
+                        .HasColumnType("timestamp with time zone")
+                        .HasColumnName("created_on_timestamp");
+
+                    b.Property<Geometry>("Geometry")
+                        .HasColumnType("geometry")
+                        .HasColumnName("geometry");
+
+                    b.Property<bool>("IsRemoved")
+                        .HasColumnType("boolean")
+                        .HasColumnName("is_removed");
+
+                    b.Property<string>("Namespace")
+                        .IsRequired()
+                        .HasColumnType("text")
+                        .HasColumnName("namespace");
+
+                    b.Property<string>("OsloStatus")
+                        .HasColumnType("text")
+                        .HasColumnName("oslo_status");
+
+                    b.Property<string>("Puri")
+                        .IsRequired()
+                        .HasColumnType("text")
+                        .HasColumnName("puri");
+
+                    b.Property<string>("Status")
+                        .HasColumnType("text")
+                        .HasColumnName("status");
+
+                    b.Property<string>("Type")
+                        .IsRequired()
+                        .HasColumnType("text")
+                        .HasColumnName("type");
+
+                    b.Property<string>("VersionAsString")
+                        .IsRequired()
+                        .HasColumnType("text")
+                        .HasColumnName("version_as_string");
+
+                    b.Property<DateTimeOffset>("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<long>("Position")
+                        .HasColumnType("bigint")
+                        .HasColumnName("position");
+
+                    b.Property<Guid>("ParcelId")
+                        .HasColumnType("uuid")
+                        .HasColumnName("parcel_id");
+
+                    b.Property<int>("AddressPersistentLocalId")
+                        .HasColumnType("integer")
+                        .HasColumnName("address_persistent_local_id");
+
+                    b.Property<string>("CaPaKey")
+                        .IsRequired()
+                        .HasColumnType("text")
+                        .HasColumnName("capakey");
+
+                    b.Property<int>("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
+{
+    /// <inheritdoc />
+    public partial class RemoveLatestItemV1 : Migration
+    {
+        /// <inheritdoc />
+        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");
+        }
+
+        /// <inheritdoc />
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.CreateTable(
+                name: "parcel_latest_item_addresses",
+                schema: "integration_parcel",
+                columns: table => new
+                {
+                    parcel_id = table.Column<Guid>(type: "uuid", nullable: false),
+                    address_persistent_local_id = table.Column<int>(type: "integer", nullable: false),
+                    capakey = table.Column<string>(type: "text", nullable: false),
+                    Count = table.Column<int>(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<Guid>(type: "uuid", nullable: false),
+                    capakey = table.Column<string>(type: "varchar", maxLength: 20, nullable: false),
+                    geometry = table.Column<Geometry>(type: "geometry", nullable: false),
+                    is_removed = table.Column<bool>(type: "boolean", nullable: false),
+                    @namespace = table.Column<string>(name: "namespace", type: "text", nullable: false),
+                    oslo_status = table.Column<string>(type: "text", nullable: false),
+                    puri = table.Column<string>(type: "text", nullable: false),
+                    status = table.Column<string>(type: "text", nullable: false),
+                    version_as_string = table.Column<string>(type: "text", nullable: false),
+                    version_timestamp = table.Column<DateTimeOffset>(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<Guid>("ParcelId")
-                        .ValueGeneratedOnAdd()
-                        .HasColumnType("uuid")
-                        .HasColumnName("parcel_id");
-
-                    b.Property<string>("CaPaKey")
-                        .IsRequired()
-                        .HasMaxLength(20)
-                        .HasColumnType("varchar")
-                        .HasColumnName("capakey");
-
-                    b.Property<Geometry>("Geometry")
-                        .IsRequired()
-                        .HasColumnType("geometry")
-                        .HasColumnName("geometry");
-
-                    b.Property<bool>("IsRemoved")
-                        .HasColumnType("boolean")
-                        .HasColumnName("is_removed");
-
-                    b.Property<string>("Namespace")
-                        .IsRequired()
-                        .HasColumnType("text")
-                        .HasColumnName("namespace");
-
-                    b.Property<string>("OsloStatus")
-                        .IsRequired()
-                        .HasColumnType("text")
-                        .HasColumnName("oslo_status");
-
-                    b.Property<string>("Puri")
-                        .IsRequired()
-                        .HasColumnType("text")
-                        .HasColumnName("puri");
-
-                    b.Property<string>("Status")
-                        .IsRequired()
-                        .HasColumnType("text")
-                        .HasColumnName("status");
-
-                    b.Property<string>("VersionAsString")
-                        .IsRequired()
-                        .HasColumnType("text")
-                        .HasColumnName("version_as_string");
-
-                    b.Property<DateTimeOffset>("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<Guid>("ParcelId")
-                        .HasColumnType("uuid")
-                        .HasColumnName("parcel_id");
-
-                    b.Property<int>("AddressPersistentLocalId")
-                        .HasColumnType("integer")
-                        .HasColumnName("address_persistent_local_id");
-
-                    b.Property<string>("CaPaKey")
-                        .IsRequired()
-                        .HasColumnType("text")
-                        .HasColumnName("capakey");
-
-                    b.Property<int>("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<Guid>("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<ParcelLatestItem>
-    {
-        public void Configure(EntityTypeBuilder<ParcelLatestItem> 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<ParcelLatestItemAddress>
-    {
-        public void Configure(EntityTypeBuilder<ParcelLatestItemAddress> 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<ParcelLatestItem> FindAndUpdateParcel(
-            this IntegrationContext context,
-            Guid parcelId,
-            Action<ParcelLatestItem> 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<ParcelLatestItemProjections> DatabaseItemNotFound(Guid parcelId)
-            => new ProjectionItemNotFoundException<ParcelLatestItemProjections>(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<IntegrationContext>
-    {
-        public ParcelLatestItemProjections(IOptions<IntegrationOptions> options)
-        {
-            When<Envelope<ParcelWasMigrated>>(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<Envelope<ParcelWasImported>>(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<Envelope<ParcelGeometryWasChanged>>(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<Envelope<ParcelWasCorrectedFromRetiredToRealized>>(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<Envelope<ParcelWasRetiredV2>>(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<Envelope<ParcelAddressWasAttachedV2>>(async (context, message, ct) =>
-            {
-                await AddParcelAddress(context, message.Message.ParcelId, message.Message.CaPaKey, message.Message.AddressPersistentLocalId, ct);
-            });
-
-            When<Envelope<ParcelAddressWasReplacedBecauseOfMunicipalityMerger>>(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<Envelope<ParcelAddressWasReplacedBecauseAddressWasReaddressed>>(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<Envelope<ParcelAddressesWereReaddressed>>(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<Envelope<ParcelAddressWasDetachedV2>>(async (context, message, ct) =>
-            {
-                await RemoveParcelAddress(context, message.Message.ParcelId, message.Message.AddressPersistentLocalId, ct);
-            });
-
-            When<Envelope<ParcelAddressWasDetachedBecauseAddressWasRejected>>(async (context, message, ct) =>
-            {
-                await RemoveParcelAddress(context, message.Message.ParcelId, message.Message.AddressPersistentLocalId, ct);
-            });
-
-            When<Envelope<ParcelAddressWasDetachedBecauseAddressWasRemoved>>(async (context, message, ct) =>
-            {
-                await RemoveParcelAddress(context, message.Message.ParcelId, message.Message.AddressPersistentLocalId, ct);
-            });
-
-            When<Envelope<ParcelAddressWasDetachedBecauseAddressWasRetired>>(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<IntegrationContextMigrationFactory>(
                     _configuration,
                     _loggerFactory)
-                .RegisterProjections<ParcelLatestItemProjections, IntegrationContext>(
-                    context => new ParcelLatestItemProjections(context.Resolve<IOptions<IntegrationOptions>>()),
-                    ConnectedProjectionSettings.Default)
                 .RegisterProjections<ParcelLatestItemV2Projections, IntegrationContext>(
                     context => new ParcelLatestItemV2Projections(context.Resolve<IOptions<IntegrationOptions>>()),
                     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<VbrCaPaKey>(),
                 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<VbrCaPaKey>(),
                 newAddressPersistentLocalId: new AddressPersistentLocalId(parcelAddressWasAttachedV2.AddressPersistentLocalId),
                 previousAddressPersistentLocalId: new AddressPersistentLocalId(parcelAddressWasAttachedV2.AddressPersistentLocalId + 100));
+            eventToAddPreviousRelationASecondTime.SetFixtureProvenance(_fixture);
 
             var @event = new ParcelAddressWasReplacedBecauseAddressWasReaddressed(
                 _fixture.Create<ParcelId>(),
                 _fixture.Create<VbrCaPaKey>(),
                 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<VbrCaPaKey>(),
                 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<ParcelLatestItemProjections>
+    public partial class ParcelLatestItemProjectionTests : IntegrationProjectionTest<ParcelLatestItemV2Projections>
     {
         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<ParcelWasMigrated>();
 
@@ -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<ParcelWasImported>();
 
@@ -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<ParcelWasImported>();
             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<ParcelWasCorrectedFromRetiredToRealized>();
 
@@ -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<ParcelWasRetiredV2>();
 
@@ -146,7 +147,7 @@ await Sut
                 .Given(_fixture.Create<ParcelWasImported>(), 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<ParcelAddressWasAttachedV2>();
 
@@ -166,86 +167,110 @@ await Sut
                 .Given(_fixture.Create<ParcelWasImported>(), 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<ParcelAddressWasAttachedV2>();
             var message = new ParcelAddressWasDetachedV2(
                 new ParcelId(attached.ParcelId),
                 new VbrCaPaKey(attached.CaPaKey),
                 new AddressPersistentLocalId(attached.AddressPersistentLocalId));
+            message.SetFixtureProvenance(_fixture);
 
             await Sut
                 .Given(_fixture.Create<ParcelWasImported>(), 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<ParcelAddressWasAttachedV2>();
             var message = new ParcelAddressWasDetachedBecauseAddressWasRejected(
                 new ParcelId(attached.ParcelId),
                 new VbrCaPaKey(attached.CaPaKey),
                 new AddressPersistentLocalId(attached.AddressPersistentLocalId));
+            message.SetFixtureProvenance(_fixture);
 
             await Sut
                 .Given(_fixture.Create<ParcelWasImported>(), 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<ParcelAddressWasAttachedV2>();
             var message = new ParcelAddressWasDetachedBecauseAddressWasRemoved(
                 new ParcelId(attached.ParcelId),
                 new VbrCaPaKey(attached.CaPaKey),
                 new AddressPersistentLocalId(attached.AddressPersistentLocalId));
+            message.SetFixtureProvenance(_fixture);
 
             await Sut
                 .Given(_fixture.Create<ParcelWasImported>(), 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<ParcelAddressWasAttachedV2>();
             var message = new ParcelAddressWasDetachedBecauseAddressWasRetired(
                 new ParcelId(attached.ParcelId),
                 new VbrCaPaKey(attached.CaPaKey),
                 new AddressPersistentLocalId(attached.AddressPersistentLocalId));
+            message.SetFixtureProvenance(_fixture);
 
             await Sut
                 .Given(_fixture.Create<ParcelWasImported>(), 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<ParcelAddressWasAttachedV2>();
 
@@ -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<ParcelWasImported>(), 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<IntegrationOptions>(new IntegrationOptions{Namespace = Namespace }));
     }
 }