From 5e68ea16c8ad450eec045b8f4e1d285ed773f1c0 Mon Sep 17 00:00:00 2001
From: Timo Notheisen <65653426+tnotheis@users.noreply.github.com>
Date: Wed, 4 Oct 2023 12:49:26 +0200
Subject: [PATCH] Save all datawallet modification payloads of a push in a
single blob (#315)
* feat: add property to DatawalletModification
* feat: add migration
* chore: code cleanup
* chore: add words to dictionary
* feat: update FinalizeSyncRun handler
* feat: update PushDatawalletModifications handler
* feat: update GetModifications handler
* refactor: no hyphens in guids
* test: fix compiler error
* fix: make new column fix length and unicode
* chore: formatting of migration
* test: fix compiler error
* ci: ignore audit issue
* test: fix tests
* chore: remove log message
* chore: fix PR comments
* test: remove logger parameter from tests
* chore: formatting
---
.ci/runAdminUiChecks.sh | 2 +-
Backbone.sln.DotSettings | 3 +
.../PushDatawalletModifications/Handler.cs | 29 +-
.../Queries/GetModifications/Handler.cs | 56 +-
.../Commands/FinalizeSyncRun/Handler.cs | 20 +-
.../Entities/Datawallet.cs | 11 +-
.../Entities/DatawalletModification.cs | 8 +-
...opertyToDatawalletModification.Designer.cs | 321 +++++++++
...ferencePropertyToDatawalletModification.cs | 32 +
.../SynchronizationDbContextModelSnapshot.cs | 629 +++++++++---------
...opertyToDatawalletModification.Designer.cs | 321 +++++++++
...ferencePropertyToDatawalletModification.cs | 32 +
.../ApplicationDbContextModelSnapshot.cs | 629 +++++++++---------
...lletModificationEntityTypeConfiguration.cs | 1 +
.../Database/SynchronizationDbContext.cs | 2 +-
.../DatawalletExtensions.cs | 2 +-
.../DatawalletModificationBuilder.cs | 92 ---
.../HandlerTests.cs | 2 +-
.../HandlerTests.cs | 9 +-
.../DatawalletTests.cs | 2 +-
20 files changed, 1442 insertions(+), 761 deletions(-)
create mode 100644 Modules/Synchronization/src/Synchronization.Infrastructure.Database.Postgres/Migrations/20231004081756_AddBlobReferencePropertyToDatawalletModification.Designer.cs
create mode 100644 Modules/Synchronization/src/Synchronization.Infrastructure.Database.Postgres/Migrations/20231004081756_AddBlobReferencePropertyToDatawalletModification.cs
create mode 100644 Modules/Synchronization/src/Synchronization.Infrastructure.Database.SqlServer/Migrations/20231004081751_AddBlobReferencePropertyToDatawalletModification.Designer.cs
create mode 100644 Modules/Synchronization/src/Synchronization.Infrastructure.Database.SqlServer/Migrations/20231004081751_AddBlobReferencePropertyToDatawalletModification.cs
delete mode 100644 Modules/Synchronization/test/Synchronization.Application.Tests/DatawalletModificationBuilder.cs
diff --git a/.ci/runAdminUiChecks.sh b/.ci/runAdminUiChecks.sh
index 8e95df858a..13c7c8e011 100755
--- a/.ci/runAdminUiChecks.sh
+++ b/.ci/runAdminUiChecks.sh
@@ -7,5 +7,5 @@ npm ci
npx eslint --ext ts ./src
npx prettier --check .
npx license-check --ignorePackages adminui@0.0.0
-npx better-npm-audit audit
+npx better-npm-audit audit --exclude 1094239
cd $INITIAL_DIR
diff --git a/Backbone.sln.DotSettings b/Backbone.sln.DotSettings
index 5e89dd8135..52d8326d25 100644
--- a/Backbone.sln.DotSettings
+++ b/Backbone.sln.DotSettings
@@ -27,6 +27,9 @@
ignore("skipping_due_to_required_backbone_changes"),ignore("skipping_due_to_required_adminAPI_changes")
True
True
+ True
+ True
+ True
True
True
True
diff --git a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/Handler.cs b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/Handler.cs
index 57a33bef98..cfc6dd7a99 100644
--- a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/Handler.cs
+++ b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/Handler.cs
@@ -1,4 +1,5 @@
-using AutoMapper;
+using System.Text.Json;
+using AutoMapper;
using Backbone.Modules.Synchronization.Application.Datawallets.DTOs;
using Backbone.Modules.Synchronization.Application.Infrastructure;
using Backbone.Modules.Synchronization.Application.IntegrationEvents.Outgoing;
@@ -89,18 +90,20 @@ private void EnsureSufficientSupportedDatawalletVersion()
private async Task CreateModifications()
{
- var newModifications = _request.Modifications.Select(CreateModification);
+ var blobName = Guid.NewGuid().ToString("N");
+
+ var newModifications = _request.Modifications.Select(m => CreateModification(m, blobName));
_dbContext.Set().Update(_datawallet);
var modificationsArray = newModifications.ToArray();
- await Save(modificationsArray);
+ await Save(modificationsArray, blobName);
_modifications = modificationsArray;
}
- private DatawalletModification CreateModification(PushDatawalletModificationItem modificationDto)
+ private DatawalletModification CreateModification(PushDatawalletModificationItem modificationDto, string blobReference)
{
return _datawallet.AddModification(
_mapper.Map(modificationDto.Type),
@@ -109,7 +112,8 @@ private DatawalletModification CreateModification(PushDatawalletModificationItem
modificationDto.ObjectIdentifier,
modificationDto.PayloadCategory,
modificationDto.EncryptedPayload,
- _activeDevice
+ _activeDevice,
+ blobReference
);
}
@@ -125,14 +129,17 @@ private void BuildResponse()
_response = new PushDatawalletModificationsResponse { Modifications = responseItems, NewIndex = responseItems.Max(i => i.Index) };
}
- private async Task Save(DatawalletModification[] modifications)
+ private async Task Save(DatawalletModification[] modifications, string blobName)
{
await _dbContext.Set().AddRangeAsync(modifications, _cancellationToken);
- foreach (var newModification in modifications)
- {
- if (newModification.EncryptedPayload != null)
- _blobStorage.Add(_blobOptions.RootFolder, newModification.Id, newModification.EncryptedPayload);
- }
+
+ var payloads = modifications
+ .Where(newModification => newModification.EncryptedPayload != null)
+ .ToDictionary(m => m.Index, m => m.EncryptedPayload);
+
+ var blobContent = JsonSerializer.SerializeToUtf8Bytes(payloads);
+
+ _blobStorage.Add(_blobOptions.RootFolder, blobName, blobContent);
await _blobStorage.SaveAsync();
diff --git a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Queries/GetModifications/Handler.cs b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Queries/GetModifications/Handler.cs
index 4cb02afed2..bc4bab7dd5 100644
--- a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Queries/GetModifications/Handler.cs
+++ b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Queries/GetModifications/Handler.cs
@@ -1,4 +1,5 @@
-using AutoMapper;
+using System.Text.Json;
+using AutoMapper;
using Backbone.Modules.Synchronization.Application.Datawallets.DTOs;
using Backbone.Modules.Synchronization.Application.Infrastructure;
using Backbone.Modules.Synchronization.Domain.Entities;
@@ -6,6 +7,7 @@
using Enmeshed.BuildingBlocks.Application.Abstractions.Infrastructure.Persistence.BlobStorage;
using Enmeshed.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext;
using Enmeshed.DevelopmentKit.Identity.ValueObjects;
+using Enmeshed.Tooling.Extensions;
using MediatR;
using Microsoft.Extensions.Options;
@@ -39,27 +41,59 @@ public async Task Handle(GetModificationsQuery request
var dbPaginationResult = await _dbContext.GetDatawalletModifications(_activeIdentity, request.LocalIndex, request.PaginationFilter, cancellationToken);
- var dtos = _mapper.Map>(dbPaginationResult.ItemsOnPage).ToArray();
-
- await FillEncryptedPayloads(dtos);
+ var dtos = await MapToDtos(dbPaginationResult.ItemsOnPage);
return new GetModificationsResponse(dtos, request.PaginationFilter, dbPaginationResult.TotalNumberOfItems);
}
- private async Task FillEncryptedPayloads(IEnumerable modifications)
+ private async Task> MapToDtos(IEnumerable modifications)
{
- await Task.WhenAll(modifications.Select(FillEncryptedPayload));
+ var datawalletModifications = modifications as DatawalletModification[] ?? modifications.ToArray();
+
+ var blobReferences = datawalletModifications.Where(m => !m.BlobReference.IsNullOrEmpty()).Select(m => m.BlobReference).Distinct();
+ var blobs = await Task.WhenAll(blobReferences.Select(r =>
+ {
+ try
+ {
+ return _blobStorage.FindAsync(_blobOptions.RootFolder, r);
+ }
+ catch (NotFoundException)
+ {
+ throw new Exception($"Blob with reference '{r}' not found.");
+ }
+ }));
+
+ var payloads = blobs
+ .Select(b => JsonSerializer.Deserialize>(b))
+ .SelectMany(b => b)
+ .ToDictionary(b => b.Key, b => b.Value);
+
+ var mappingTasks = datawalletModifications.Select(m => MapToDto(m, payloads));
+
+ return (await Task.WhenAll(mappingTasks)).ToList();
}
- private async Task FillEncryptedPayload(DatawalletModificationDTO datawalletModification)
+ private async Task MapToDto(DatawalletModification modification, Dictionary payloads)
{
- try
+ var dto = _mapper.Map(modification);
+
+ if (modification.BlobReference.IsNullOrEmpty())
{
- datawalletModification.EncryptedPayload = await _blobStorage.FindAsync(_blobOptions.RootFolder, datawalletModification.Id);
+ try
+ {
+ dto.EncryptedPayload = await _blobStorage.FindAsync(_blobOptions.RootFolder, modification.Id);
+ }
+ catch (NotFoundException)
+ {
+ // blob not found means that there is no payload for this modification
+ }
}
- catch (NotFoundException)
+ else
{
- // if the payload was not found, it means that the modification had no payload
+ payloads.TryGetValue(modification.Index, out var payload);
+ dto.EncryptedPayload = payload;
}
+
+ return dto;
}
}
diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/Handler.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/Handler.cs
index 663d5e8295..8017470ec2 100644
--- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/Handler.cs
+++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/Handler.cs
@@ -1,4 +1,5 @@
-using AutoMapper;
+using System.Text.Json;
+using AutoMapper;
using Backbone.Modules.Synchronization.Application.Datawallets.DTOs;
using Backbone.Modules.Synchronization.Application.Infrastructure;
using Backbone.Modules.Synchronization.Application.IntegrationEvents.Outgoing;
@@ -15,7 +16,8 @@
namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.FinalizeSyncRun;
-public class Handler : IRequestHandler, IRequestHandler
+public class Handler : IRequestHandler,
+ IRequestHandler
{
private readonly DeviceId _activeDevice;
private readonly IdentityAddress _activeIdentity;
@@ -136,7 +138,10 @@ private List AddModificationsToDatawallet(List();
+ var blobName = Guid.NewGuid().ToString("N");
+
var newModifications = new List();
+ var payloads = new Dictionary();
foreach (var modificationDto in modifications)
{
var newModification = _datawallet.AddModification(
@@ -146,14 +151,17 @@ private List AddModificationsToDatawallet(List Version)
throw new DomainException(DomainErrors.Datawallet.DatawalletVersionOfModificationTooHigh(Version, datawalletVersionOfModification));
var indexOfNewModification = Modifications.Count > 0 ? Modifications.Max(m => m.Index) + 1 : 0;
- var newModification = new DatawalletModification(this, datawalletVersionOfModification, indexOfNewModification, type, collection, objectIdentifier, payloadCategory, encryptedPayload, createdByDevice);
+
+ var newModification = new DatawalletModification(this, datawalletVersionOfModification, indexOfNewModification, type, collection, objectIdentifier, payloadCategory, encryptedPayload, createdByDevice, blobReference);
Modifications.Add(newModification);
return newModification;
}
- public DatawalletModification AddModification(DatawalletModification modification)
- {
- Modifications.Add(modification);
- return modification;
- }
-
public class DatawalletVersion : SimpleValueObject
{
public DatawalletVersion(ushort value) : base(value) { }
diff --git a/Modules/Synchronization/src/Synchronization.Domain/Entities/DatawalletModification.cs b/Modules/Synchronization/src/Synchronization.Domain/Entities/DatawalletModification.cs
index 21c3c40e5b..b9692e9e48 100644
--- a/Modules/Synchronization/src/Synchronization.Domain/Entities/DatawalletModification.cs
+++ b/Modules/Synchronization/src/Synchronization.Domain/Entities/DatawalletModification.cs
@@ -6,10 +6,12 @@ namespace Backbone.Modules.Synchronization.Domain.Entities;
public class DatawalletModification
{
#pragma warning disable CS8618
- private DatawalletModification() { }
+ private DatawalletModification()
+ {
+ }
#pragma warning restore CS8618
- public DatawalletModification(Datawallet datawallet, Datawallet.DatawalletVersion datawalletVersion, long index, DatawalletModificationType type, string collection, string objectIdentifier, string payloadCategory, byte[] encryptedPayload, DeviceId createdByDevice)
+ public DatawalletModification(Datawallet datawallet, Datawallet.DatawalletVersion datawalletVersion, long index, DatawalletModificationType type, string collection, string objectIdentifier, string payloadCategory, byte[] encryptedPayload, DeviceId createdByDevice, string blobReference)
{
Id = DatawalletModificationId.New();
@@ -26,6 +28,7 @@ public DatawalletModification(Datawallet datawallet, Datawallet.DatawalletVersio
CreatedAt = SystemTime.UtcNow;
CreatedByDevice = createdByDevice;
+ BlobReference = blobReference;
}
public DatawalletModificationId Id { get; }
@@ -40,6 +43,7 @@ public DatawalletModification(Datawallet datawallet, Datawallet.DatawalletVersio
public string Collection { get; }
public DatawalletModificationType Type { get; }
public byte[]? EncryptedPayload { get; }
+ public string BlobReference { get; }
}
public enum DatawalletModificationType
diff --git a/Modules/Synchronization/src/Synchronization.Infrastructure.Database.Postgres/Migrations/20231004081756_AddBlobReferencePropertyToDatawalletModification.Designer.cs b/Modules/Synchronization/src/Synchronization.Infrastructure.Database.Postgres/Migrations/20231004081756_AddBlobReferencePropertyToDatawalletModification.Designer.cs
new file mode 100644
index 0000000000..11005fa517
--- /dev/null
+++ b/Modules/Synchronization/src/Synchronization.Infrastructure.Database.Postgres/Migrations/20231004081756_AddBlobReferencePropertyToDatawalletModification.Designer.cs
@@ -0,0 +1,321 @@
+//
+using System;
+using Backbone.Modules.Synchronization.Infrastructure.Persistence.Database;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace Backbone.Modules.Synchronization.Infrastructure.Database.Postgres.Migrations
+{
+ [DbContext(typeof(SynchronizationDbContext))]
+ [Migration("20231004081756_AddBlobReferencePropertyToDatawalletModification")]
+ partial class AddBlobReferencePropertyToDatawalletModification
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("Owner")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("character(36)")
+ .IsFixedLength();
+
+ b.Property("Version")
+ .IsUnicode(false)
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Owner")
+ .IsUnique();
+
+ b.ToTable("Datawallets");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.DatawalletModification", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("BlobReference")
+ .IsRequired()
+ .HasMaxLength(32)
+ .IsUnicode(false)
+ .HasColumnType("character(32)")
+ .IsFixedLength();
+
+ b.Property("Collection")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreatedBy")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("character(36)")
+ .IsFixedLength();
+
+ b.Property("CreatedByDevice")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("DatawalletId")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("DatawalletVersion")
+ .IsUnicode(false)
+ .HasColumnType("integer");
+
+ b.Property("Index")
+ .HasColumnType("bigint");
+
+ b.Property("ObjectIdentifier")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("character varying(100)");
+
+ b.Property("PayloadCategory")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("Type")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("DatawalletId");
+
+ b.HasIndex("CreatedBy", "Index")
+ .IsUnique();
+
+ b.ToTable("DatawalletModifications");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Index")
+ .HasColumnType("bigint");
+
+ b.Property("Owner")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("character(36)")
+ .IsFixedLength();
+
+ b.Property("Payload")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("SyncErrorCount")
+ .HasColumnType("smallint");
+
+ b.Property("SyncRunId")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("Type")
+ .HasMaxLength(50)
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SyncRunId");
+
+ b.HasIndex("Owner", "Index")
+ .IsUnique();
+
+ b.HasIndex("Owner", "SyncRunId");
+
+ b.ToTable("ExternalEvents");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncError", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("ErrorCode")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("ExternalEventId")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("SyncRunId")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.HasKey("Id");
+
+ b.HasIndex("ExternalEventId");
+
+ b.HasIndex("SyncRunId", "ExternalEventId")
+ .IsUnique();
+
+ b.ToTable("SyncErrors");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreatedBy")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("character(36)")
+ .IsFixedLength();
+
+ b.Property("CreatedByDevice")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("EventCount")
+ .HasColumnType("integer");
+
+ b.Property("ExpiresAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("FinalizedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Index")
+ .HasColumnType("bigint");
+
+ b.Property("Type")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("CreatedBy", "FinalizedAt");
+
+ b.HasIndex("CreatedBy", "Index")
+ .IsUnique();
+
+ b.ToTable("SyncRuns");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.DatawalletModification", b =>
+ {
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", "Datawallet")
+ .WithMany("Modifications")
+ .HasForeignKey("DatawalletId");
+
+ b.Navigation("Datawallet");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
+ {
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", "SyncRun")
+ .WithMany("ExternalEvents")
+ .HasForeignKey("SyncRunId");
+
+ b.Navigation("SyncRun");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncError", b =>
+ {
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", null)
+ .WithMany("Errors")
+ .HasForeignKey("ExternalEventId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", null)
+ .WithMany("Errors")
+ .HasForeignKey("SyncRunId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", b =>
+ {
+ b.Navigation("Modifications");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
+ {
+ b.Navigation("Errors");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", b =>
+ {
+ b.Navigation("Errors");
+
+ b.Navigation("ExternalEvents");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Modules/Synchronization/src/Synchronization.Infrastructure.Database.Postgres/Migrations/20231004081756_AddBlobReferencePropertyToDatawalletModification.cs b/Modules/Synchronization/src/Synchronization.Infrastructure.Database.Postgres/Migrations/20231004081756_AddBlobReferencePropertyToDatawalletModification.cs
new file mode 100644
index 0000000000..c42b9600d3
--- /dev/null
+++ b/Modules/Synchronization/src/Synchronization.Infrastructure.Database.Postgres/Migrations/20231004081756_AddBlobReferencePropertyToDatawalletModification.cs
@@ -0,0 +1,32 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Backbone.Modules.Synchronization.Infrastructure.Database.Postgres.Migrations
+{
+ ///
+ public partial class AddBlobReferencePropertyToDatawalletModification : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "BlobReference",
+ table: "DatawalletModifications",
+ type: "character(32)",
+ unicode: false,
+ fixedLength: true,
+ maxLength: 32,
+ nullable: false,
+ defaultValue: "");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "BlobReference",
+ table: "DatawalletModifications");
+ }
+ }
+}
diff --git a/Modules/Synchronization/src/Synchronization.Infrastructure.Database.Postgres/Migrations/SynchronizationDbContextModelSnapshot.cs b/Modules/Synchronization/src/Synchronization.Infrastructure.Database.Postgres/Migrations/SynchronizationDbContextModelSnapshot.cs
index 10a8751f35..befce1c1e7 100644
--- a/Modules/Synchronization/src/Synchronization.Infrastructure.Database.Postgres/Migrations/SynchronizationDbContextModelSnapshot.cs
+++ b/Modules/Synchronization/src/Synchronization.Infrastructure.Database.Postgres/Migrations/SynchronizationDbContextModelSnapshot.cs
@@ -1,311 +1,318 @@
-//
-using System;
-using Backbone.Modules.Synchronization.Infrastructure.Persistence.Database;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#nullable disable
-
-namespace Synchronization.Infrastructure.Database.Postgres.Migrations
-{
- [DbContext(typeof(SynchronizationDbContext))]
- partial class SynchronizationDbContextModelSnapshot : ModelSnapshot
- {
- protected override void BuildModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "7.0.2")
- .HasAnnotation("Relational:MaxIdentifierLength", 63);
-
- NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
-
- modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", b =>
- {
- b.Property("Id")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("character(20)")
- .IsFixedLength();
-
- b.Property("Owner")
- .IsRequired()
- .HasMaxLength(36)
- .IsUnicode(false)
- .HasColumnType("character(36)")
- .IsFixedLength();
-
- b.Property("Version")
- .IsUnicode(false)
- .HasColumnType("integer");
-
- b.HasKey("Id");
-
- b.HasIndex("Owner")
- .IsUnique();
-
- b.ToTable("Datawallets");
- });
-
- modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.DatawalletModification", b =>
- {
- b.Property("Id")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("character(20)")
- .IsFixedLength();
-
- b.Property("Collection")
- .IsRequired()
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("CreatedBy")
- .IsRequired()
- .HasMaxLength(36)
- .IsUnicode(false)
- .HasColumnType("character(36)")
- .IsFixedLength();
-
- b.Property("CreatedByDevice")
- .IsRequired()
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("character(20)")
- .IsFixedLength();
-
- b.Property("DatawalletId")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("character(20)")
- .IsFixedLength();
-
- b.Property("DatawalletVersion")
- .IsUnicode(false)
- .HasColumnType("integer");
-
- b.Property("Index")
- .HasColumnType("bigint");
-
- b.Property("ObjectIdentifier")
- .IsRequired()
- .HasMaxLength(100)
- .HasColumnType("character varying(100)");
-
- b.Property("PayloadCategory")
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("Type")
- .HasColumnType("integer");
-
- b.HasKey("Id");
-
- b.HasIndex("CreatedBy");
-
- b.HasIndex("DatawalletId");
-
- b.HasIndex("CreatedBy", "Index")
- .IsUnique();
-
- b.ToTable("DatawalletModifications");
- });
-
- modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
- {
- b.Property("Id")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("character(20)")
- .IsFixedLength();
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Index")
- .HasColumnType("bigint");
-
- b.Property("Owner")
- .IsRequired()
- .HasMaxLength(36)
- .IsUnicode(false)
- .HasColumnType("character(36)")
- .IsFixedLength();
-
- b.Property("Payload")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("SyncErrorCount")
- .HasColumnType("smallint");
-
- b.Property("SyncRunId")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("character(20)")
- .IsFixedLength();
-
- b.Property("Type")
- .HasMaxLength(50)
- .HasColumnType("integer");
-
- b.HasKey("Id");
-
- b.HasIndex("SyncRunId");
-
- b.HasIndex("Owner", "Index")
- .IsUnique();
-
- b.HasIndex("Owner", "SyncRunId");
-
- b.ToTable("ExternalEvents");
- });
-
- modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncError", b =>
- {
- b.Property("Id")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("character(20)")
- .IsFixedLength();
-
- b.Property("ErrorCode")
- .IsRequired()
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("ExternalEventId")
- .IsRequired()
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("character(20)")
- .IsFixedLength();
-
- b.Property("SyncRunId")
- .IsRequired()
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("character(20)")
- .IsFixedLength();
-
- b.HasKey("Id");
-
- b.HasIndex("ExternalEventId");
-
- b.HasIndex("SyncRunId", "ExternalEventId")
- .IsUnique();
-
- b.ToTable("SyncErrors");
- });
-
- modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", b =>
- {
- b.Property("Id")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("character(20)")
- .IsFixedLength();
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("CreatedBy")
- .IsRequired()
- .HasMaxLength(36)
- .IsUnicode(false)
- .HasColumnType("character(36)")
- .IsFixedLength();
-
- b.Property("CreatedByDevice")
- .IsRequired()
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("character(20)")
- .IsFixedLength();
-
- b.Property("EventCount")
- .HasColumnType("integer");
-
- b.Property("ExpiresAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("FinalizedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Index")
- .HasColumnType("bigint");
-
- b.Property("Type")
- .HasColumnType("integer");
-
- b.HasKey("Id");
-
- b.HasIndex("CreatedBy");
-
- b.HasIndex("CreatedBy", "FinalizedAt");
-
- b.HasIndex("CreatedBy", "Index")
- .IsUnique();
-
- b.ToTable("SyncRuns");
- });
-
- modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.DatawalletModification", b =>
- {
- b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", "Datawallet")
- .WithMany("Modifications")
- .HasForeignKey("DatawalletId");
-
- b.Navigation("Datawallet");
- });
-
- modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
- {
- b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", "SyncRun")
- .WithMany("ExternalEvents")
- .HasForeignKey("SyncRunId");
-
- b.Navigation("SyncRun");
- });
-
- modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncError", b =>
- {
- b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", null)
- .WithMany("Errors")
- .HasForeignKey("ExternalEventId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", null)
- .WithMany("Errors")
- .HasForeignKey("SyncRunId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", b =>
- {
- b.Navigation("Modifications");
- });
-
- modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
- {
- b.Navigation("Errors");
- });
-
- modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", b =>
- {
- b.Navigation("Errors");
-
- b.Navigation("ExternalEvents");
- });
-#pragma warning restore 612, 618
- }
- }
-}
+//
+using System;
+using Backbone.Modules.Synchronization.Infrastructure.Persistence.Database;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace Synchronization.Infrastructure.Database.Postgres.Migrations
+{
+ [DbContext(typeof(SynchronizationDbContext))]
+ partial class SynchronizationDbContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("Owner")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("character(36)")
+ .IsFixedLength();
+
+ b.Property("Version")
+ .IsUnicode(false)
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Owner")
+ .IsUnique();
+
+ b.ToTable("Datawallets");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.DatawalletModification", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("BlobReference")
+ .IsRequired()
+ .HasMaxLength(32)
+ .IsUnicode(false)
+ .HasColumnType("character(32)")
+ .IsFixedLength();
+
+ b.Property("Collection")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreatedBy")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("character(36)")
+ .IsFixedLength();
+
+ b.Property("CreatedByDevice")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("DatawalletId")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("DatawalletVersion")
+ .IsUnicode(false)
+ .HasColumnType("integer");
+
+ b.Property("Index")
+ .HasColumnType("bigint");
+
+ b.Property("ObjectIdentifier")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("character varying(100)");
+
+ b.Property("PayloadCategory")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("Type")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("DatawalletId");
+
+ b.HasIndex("CreatedBy", "Index")
+ .IsUnique();
+
+ b.ToTable("DatawalletModifications");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Index")
+ .HasColumnType("bigint");
+
+ b.Property("Owner")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("character(36)")
+ .IsFixedLength();
+
+ b.Property("Payload")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("SyncErrorCount")
+ .HasColumnType("smallint");
+
+ b.Property("SyncRunId")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("Type")
+ .HasMaxLength(50)
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SyncRunId");
+
+ b.HasIndex("Owner", "Index")
+ .IsUnique();
+
+ b.HasIndex("Owner", "SyncRunId");
+
+ b.ToTable("ExternalEvents");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncError", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("ErrorCode")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("ExternalEventId")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("SyncRunId")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.HasKey("Id");
+
+ b.HasIndex("ExternalEventId");
+
+ b.HasIndex("SyncRunId", "ExternalEventId")
+ .IsUnique();
+
+ b.ToTable("SyncErrors");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreatedBy")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("character(36)")
+ .IsFixedLength();
+
+ b.Property("CreatedByDevice")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("character(20)")
+ .IsFixedLength();
+
+ b.Property("EventCount")
+ .HasColumnType("integer");
+
+ b.Property("ExpiresAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("FinalizedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Index")
+ .HasColumnType("bigint");
+
+ b.Property("Type")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("CreatedBy", "FinalizedAt");
+
+ b.HasIndex("CreatedBy", "Index")
+ .IsUnique();
+
+ b.ToTable("SyncRuns");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.DatawalletModification", b =>
+ {
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", "Datawallet")
+ .WithMany("Modifications")
+ .HasForeignKey("DatawalletId");
+
+ b.Navigation("Datawallet");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
+ {
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", "SyncRun")
+ .WithMany("ExternalEvents")
+ .HasForeignKey("SyncRunId");
+
+ b.Navigation("SyncRun");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncError", b =>
+ {
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", null)
+ .WithMany("Errors")
+ .HasForeignKey("ExternalEventId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", null)
+ .WithMany("Errors")
+ .HasForeignKey("SyncRunId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", b =>
+ {
+ b.Navigation("Modifications");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
+ {
+ b.Navigation("Errors");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", b =>
+ {
+ b.Navigation("Errors");
+
+ b.Navigation("ExternalEvents");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Modules/Synchronization/src/Synchronization.Infrastructure.Database.SqlServer/Migrations/20231004081751_AddBlobReferencePropertyToDatawalletModification.Designer.cs b/Modules/Synchronization/src/Synchronization.Infrastructure.Database.SqlServer/Migrations/20231004081751_AddBlobReferencePropertyToDatawalletModification.Designer.cs
new file mode 100644
index 0000000000..0f58af41cc
--- /dev/null
+++ b/Modules/Synchronization/src/Synchronization.Infrastructure.Database.SqlServer/Migrations/20231004081751_AddBlobReferencePropertyToDatawalletModification.Designer.cs
@@ -0,0 +1,321 @@
+//
+using System;
+using Backbone.Modules.Synchronization.Infrastructure.Persistence.Database;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace Backbone.Modules.Synchronization.Infrastructure.Database.SqlServer.Migrations
+{
+ [DbContext(typeof(SynchronizationDbContext))]
+ [Migration("20231004081751_AddBlobReferencePropertyToDatawalletModification")]
+ partial class AddBlobReferencePropertyToDatawalletModification
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("Owner")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("char(36)")
+ .IsFixedLength();
+
+ b.Property("Version")
+ .IsUnicode(false)
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Owner")
+ .IsUnique();
+
+ b.ToTable("Datawallets");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.DatawalletModification", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("BlobReference")
+ .IsRequired()
+ .HasMaxLength(32)
+ .IsUnicode(false)
+ .HasColumnType("char(32)")
+ .IsFixedLength();
+
+ b.Property("Collection")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("char(36)")
+ .IsFixedLength();
+
+ b.Property("CreatedByDevice")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("DatawalletId")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("DatawalletVersion")
+ .IsUnicode(false)
+ .HasColumnType("int");
+
+ b.Property("Index")
+ .HasColumnType("bigint");
+
+ b.Property("ObjectIdentifier")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("PayloadCategory")
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("DatawalletId");
+
+ b.HasIndex("CreatedBy", "Index")
+ .IsUnique();
+
+ b.ToTable("DatawalletModifications");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("Index")
+ .HasColumnType("bigint");
+
+ b.Property("Owner")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("char(36)")
+ .IsFixedLength();
+
+ b.Property("Payload")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("SyncErrorCount")
+ .HasColumnType("tinyint");
+
+ b.Property("SyncRunId")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("Type")
+ .HasMaxLength(50)
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SyncRunId");
+
+ b.HasIndex("Owner", "Index")
+ .IsUnique();
+
+ b.HasIndex("Owner", "SyncRunId");
+
+ b.ToTable("ExternalEvents");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncError", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("ErrorCode")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("ExternalEventId")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("SyncRunId")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.HasKey("Id");
+
+ b.HasIndex("ExternalEventId");
+
+ b.HasIndex("SyncRunId", "ExternalEventId")
+ .IsUnique();
+
+ b.ToTable("SyncErrors");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("char(36)")
+ .IsFixedLength();
+
+ b.Property("CreatedByDevice")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("EventCount")
+ .HasColumnType("int");
+
+ b.Property("ExpiresAt")
+ .HasColumnType("datetime2");
+
+ b.Property("FinalizedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("Index")
+ .HasColumnType("bigint");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("CreatedBy", "FinalizedAt");
+
+ b.HasIndex("CreatedBy", "Index")
+ .IsUnique();
+
+ b.ToTable("SyncRuns");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.DatawalletModification", b =>
+ {
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", "Datawallet")
+ .WithMany("Modifications")
+ .HasForeignKey("DatawalletId");
+
+ b.Navigation("Datawallet");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
+ {
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", "SyncRun")
+ .WithMany("ExternalEvents")
+ .HasForeignKey("SyncRunId");
+
+ b.Navigation("SyncRun");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncError", b =>
+ {
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", null)
+ .WithMany("Errors")
+ .HasForeignKey("ExternalEventId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", null)
+ .WithMany("Errors")
+ .HasForeignKey("SyncRunId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", b =>
+ {
+ b.Navigation("Modifications");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
+ {
+ b.Navigation("Errors");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", b =>
+ {
+ b.Navigation("Errors");
+
+ b.Navigation("ExternalEvents");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Modules/Synchronization/src/Synchronization.Infrastructure.Database.SqlServer/Migrations/20231004081751_AddBlobReferencePropertyToDatawalletModification.cs b/Modules/Synchronization/src/Synchronization.Infrastructure.Database.SqlServer/Migrations/20231004081751_AddBlobReferencePropertyToDatawalletModification.cs
new file mode 100644
index 0000000000..5d1604f62b
--- /dev/null
+++ b/Modules/Synchronization/src/Synchronization.Infrastructure.Database.SqlServer/Migrations/20231004081751_AddBlobReferencePropertyToDatawalletModification.cs
@@ -0,0 +1,32 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Backbone.Modules.Synchronization.Infrastructure.Database.SqlServer.Migrations
+{
+ ///
+ public partial class AddBlobReferencePropertyToDatawalletModification : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "BlobReference",
+ table: "DatawalletModifications",
+ type: "char(32)",
+ unicode: false,
+ fixedLength: true,
+ maxLength: 32,
+ nullable: false,
+ defaultValue: "");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "BlobReference",
+ table: "DatawalletModifications");
+ }
+ }
+}
diff --git a/Modules/Synchronization/src/Synchronization.Infrastructure.Database.SqlServer/Migrations/ApplicationDbContextModelSnapshot.cs b/Modules/Synchronization/src/Synchronization.Infrastructure.Database.SqlServer/Migrations/ApplicationDbContextModelSnapshot.cs
index dc6383fa04..0cb5ab95fb 100644
--- a/Modules/Synchronization/src/Synchronization.Infrastructure.Database.SqlServer/Migrations/ApplicationDbContextModelSnapshot.cs
+++ b/Modules/Synchronization/src/Synchronization.Infrastructure.Database.SqlServer/Migrations/ApplicationDbContextModelSnapshot.cs
@@ -1,311 +1,318 @@
-//
-using System;
-using Backbone.Modules.Synchronization.Infrastructure.Persistence.Database;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-
-#nullable disable
-
-namespace Backbone.Modules.Synchronization.Infrastructure.Database.SqlServer.Migrations
-{
- [DbContext(typeof(SynchronizationDbContext))]
- partial class ApplicationDbContextModelSnapshot : ModelSnapshot
- {
- protected override void BuildModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "6.0.9")
- .HasAnnotation("Relational:MaxIdentifierLength", 128);
-
- SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
-
- modelBuilder.Entity("Synchronization.Domain.Entities.Datawallet", b =>
- {
- b.Property("Id")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("char(20)")
- .IsFixedLength();
-
- b.Property("Owner")
- .IsRequired()
- .HasMaxLength(36)
- .IsUnicode(false)
- .HasColumnType("char(36)")
- .IsFixedLength();
-
- b.Property("Version")
- .IsUnicode(false)
- .HasColumnType("int");
-
- b.HasKey("Id");
-
- b.HasIndex("Owner")
- .IsUnique();
-
- b.ToTable("Datawallets");
- });
-
- modelBuilder.Entity("Synchronization.Domain.Entities.DatawalletModification", b =>
- {
- b.Property("Id")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("char(20)")
- .IsFixedLength();
-
- b.Property("Collection")
- .IsRequired()
- .HasMaxLength(50)
- .HasColumnType("nvarchar(50)");
-
- b.Property("CreatedAt")
- .HasColumnType("datetime2");
-
- b.Property("CreatedBy")
- .IsRequired()
- .HasMaxLength(36)
- .IsUnicode(false)
- .HasColumnType("char(36)")
- .IsFixedLength();
-
- b.Property("CreatedByDevice")
- .IsRequired()
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("char(20)")
- .IsFixedLength();
-
- b.Property("DatawalletId")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("char(20)")
- .IsFixedLength();
-
- b.Property("DatawalletVersion")
- .IsUnicode(false)
- .HasColumnType("int");
-
- b.Property("Index")
- .HasColumnType("bigint");
-
- b.Property("ObjectIdentifier")
- .IsRequired()
- .HasMaxLength(100)
- .HasColumnType("nvarchar(100)");
-
- b.Property("PayloadCategory")
- .HasMaxLength(50)
- .HasColumnType("nvarchar(50)");
-
- b.Property("Type")
- .HasColumnType("int");
-
- b.HasKey("Id");
-
- b.HasIndex("CreatedBy");
-
- b.HasIndex("DatawalletId");
-
- b.HasIndex("CreatedBy", "Index")
- .IsUnique();
-
- b.ToTable("DatawalletModifications");
- });
-
- modelBuilder.Entity("Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
- {
- b.Property("Id")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("char(20)")
- .IsFixedLength();
-
- b.Property("CreatedAt")
- .HasColumnType("datetime2");
-
- b.Property("Index")
- .HasColumnType("bigint");
-
- b.Property("Owner")
- .IsRequired()
- .HasMaxLength(36)
- .IsUnicode(false)
- .HasColumnType("char(36)")
- .IsFixedLength();
-
- b.Property("Payload")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("nvarchar(200)");
-
- b.Property("SyncErrorCount")
- .HasColumnType("tinyint");
-
- b.Property("SyncRunId")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("char(20)")
- .IsFixedLength();
-
- b.Property("Type")
- .HasMaxLength(50)
- .HasColumnType("int");
-
- b.HasKey("Id");
-
- b.HasIndex("SyncRunId");
-
- b.HasIndex("Owner", "Index")
- .IsUnique();
-
- b.HasIndex("Owner", "SyncRunId");
-
- b.ToTable("ExternalEvents");
- });
-
- modelBuilder.Entity("Synchronization.Domain.Entities.Sync.SyncError", b =>
- {
- b.Property("Id")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("char(20)")
- .IsFixedLength();
-
- b.Property("ErrorCode")
- .IsRequired()
- .HasMaxLength(50)
- .HasColumnType("nvarchar(50)");
-
- b.Property("ExternalEventId")
- .IsRequired()
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("char(20)")
- .IsFixedLength();
-
- b.Property("SyncRunId")
- .IsRequired()
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("char(20)")
- .IsFixedLength();
-
- b.HasKey("Id");
-
- b.HasIndex("ExternalEventId");
-
- b.HasIndex("SyncRunId", "ExternalEventId")
- .IsUnique();
-
- b.ToTable("SyncErrors");
- });
-
- modelBuilder.Entity("Synchronization.Domain.Entities.Sync.SyncRun", b =>
- {
- b.Property("Id")
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("char(20)")
- .IsFixedLength();
-
- b.Property("CreatedAt")
- .HasColumnType("datetime2");
-
- b.Property("CreatedBy")
- .IsRequired()
- .HasMaxLength(36)
- .IsUnicode(false)
- .HasColumnType("char(36)")
- .IsFixedLength();
-
- b.Property("CreatedByDevice")
- .IsRequired()
- .HasMaxLength(20)
- .IsUnicode(false)
- .HasColumnType("char(20)")
- .IsFixedLength();
-
- b.Property("EventCount")
- .HasColumnType("int");
-
- b.Property("ExpiresAt")
- .HasColumnType("datetime2");
-
- b.Property("FinalizedAt")
- .HasColumnType("datetime2");
-
- b.Property("Index")
- .HasColumnType("bigint");
-
- b.Property("Type")
- .HasColumnType("int");
-
- b.HasKey("Id");
-
- b.HasIndex("CreatedBy");
-
- b.HasIndex("CreatedBy", "FinalizedAt");
-
- b.HasIndex("CreatedBy", "Index")
- .IsUnique();
-
- b.ToTable("SyncRuns");
- });
-
- modelBuilder.Entity("Synchronization.Domain.Entities.DatawalletModification", b =>
- {
- b.HasOne("Synchronization.Domain.Entities.Datawallet", "Datawallet")
- .WithMany("Modifications")
- .HasForeignKey("DatawalletId");
-
- b.Navigation("Datawallet");
- });
-
- modelBuilder.Entity("Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
- {
- b.HasOne("Synchronization.Domain.Entities.Sync.SyncRun", "SyncRun")
- .WithMany("ExternalEvents")
- .HasForeignKey("SyncRunId");
-
- b.Navigation("SyncRun");
- });
-
- modelBuilder.Entity("Synchronization.Domain.Entities.Sync.SyncError", b =>
- {
- b.HasOne("Synchronization.Domain.Entities.Sync.ExternalEvent", null)
- .WithMany("Errors")
- .HasForeignKey("ExternalEventId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("Synchronization.Domain.Entities.Sync.SyncRun", null)
- .WithMany("Errors")
- .HasForeignKey("SyncRunId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Synchronization.Domain.Entities.Datawallet", b =>
- {
- b.Navigation("Modifications");
- });
-
- modelBuilder.Entity("Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
- {
- b.Navigation("Errors");
- });
-
- modelBuilder.Entity("Synchronization.Domain.Entities.Sync.SyncRun", b =>
- {
- b.Navigation("Errors");
-
- b.Navigation("ExternalEvents");
- });
-#pragma warning restore 612, 618
- }
- }
-}
+//
+using System;
+using Backbone.Modules.Synchronization.Infrastructure.Persistence.Database;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace Backbone.Modules.Synchronization.Infrastructure.Database.SqlServer.Migrations
+{
+ [DbContext(typeof(SynchronizationDbContext))]
+ partial class ApplicationDbContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("Owner")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("char(36)")
+ .IsFixedLength();
+
+ b.Property("Version")
+ .IsUnicode(false)
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Owner")
+ .IsUnique();
+
+ b.ToTable("Datawallets");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.DatawalletModification", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("BlobReference")
+ .IsRequired()
+ .HasMaxLength(32)
+ .IsUnicode(false)
+ .HasColumnType("char(32)")
+ .IsFixedLength();
+
+ b.Property("Collection")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("char(36)")
+ .IsFixedLength();
+
+ b.Property("CreatedByDevice")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("DatawalletId")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("DatawalletVersion")
+ .IsUnicode(false)
+ .HasColumnType("int");
+
+ b.Property("Index")
+ .HasColumnType("bigint");
+
+ b.Property("ObjectIdentifier")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("PayloadCategory")
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("DatawalletId");
+
+ b.HasIndex("CreatedBy", "Index")
+ .IsUnique();
+
+ b.ToTable("DatawalletModifications");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("Index")
+ .HasColumnType("bigint");
+
+ b.Property("Owner")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("char(36)")
+ .IsFixedLength();
+
+ b.Property("Payload")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("SyncErrorCount")
+ .HasColumnType("tinyint");
+
+ b.Property("SyncRunId")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("Type")
+ .HasMaxLength(50)
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SyncRunId");
+
+ b.HasIndex("Owner", "Index")
+ .IsUnique();
+
+ b.HasIndex("Owner", "SyncRunId");
+
+ b.ToTable("ExternalEvents");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncError", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("ErrorCode")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("nvarchar(50)");
+
+ b.Property("ExternalEventId")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("SyncRunId")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.HasKey("Id");
+
+ b.HasIndex("ExternalEventId");
+
+ b.HasIndex("SyncRunId", "ExternalEventId")
+ .IsUnique();
+
+ b.ToTable("SyncErrors");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("CreatedBy")
+ .IsRequired()
+ .HasMaxLength(36)
+ .IsUnicode(false)
+ .HasColumnType("char(36)")
+ .IsFixedLength();
+
+ b.Property("CreatedByDevice")
+ .IsRequired()
+ .HasMaxLength(20)
+ .IsUnicode(false)
+ .HasColumnType("char(20)")
+ .IsFixedLength();
+
+ b.Property("EventCount")
+ .HasColumnType("int");
+
+ b.Property("ExpiresAt")
+ .HasColumnType("datetime2");
+
+ b.Property("FinalizedAt")
+ .HasColumnType("datetime2");
+
+ b.Property("Index")
+ .HasColumnType("bigint");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CreatedBy");
+
+ b.HasIndex("CreatedBy", "FinalizedAt");
+
+ b.HasIndex("CreatedBy", "Index")
+ .IsUnique();
+
+ b.ToTable("SyncRuns");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.DatawalletModification", b =>
+ {
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", "Datawallet")
+ .WithMany("Modifications")
+ .HasForeignKey("DatawalletId");
+
+ b.Navigation("Datawallet");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
+ {
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", "SyncRun")
+ .WithMany("ExternalEvents")
+ .HasForeignKey("SyncRunId");
+
+ b.Navigation("SyncRun");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncError", b =>
+ {
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", null)
+ .WithMany("Errors")
+ .HasForeignKey("ExternalEventId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", null)
+ .WithMany("Errors")
+ .HasForeignKey("SyncRunId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Datawallet", b =>
+ {
+ b.Navigation("Modifications");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.ExternalEvent", b =>
+ {
+ b.Navigation("Errors");
+ });
+
+ modelBuilder.Entity("Backbone.Modules.Synchronization.Domain.Entities.Sync.SyncRun", b =>
+ {
+ b.Navigation("Errors");
+
+ b.Navigation("ExternalEvents");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Modules/Synchronization/src/Synchronization.Infrastructure/Persistence/Database/Configurations/DatawalletModificationEntityTypeConfiguration.cs b/Modules/Synchronization/src/Synchronization.Infrastructure/Persistence/Database/Configurations/DatawalletModificationEntityTypeConfiguration.cs
index e3a8617c14..b96405250f 100644
--- a/Modules/Synchronization/src/Synchronization.Infrastructure/Persistence/Database/Configurations/DatawalletModificationEntityTypeConfiguration.cs
+++ b/Modules/Synchronization/src/Synchronization.Infrastructure/Persistence/Database/Configurations/DatawalletModificationEntityTypeConfiguration.cs
@@ -22,6 +22,7 @@ public void Configure(EntityTypeBuilder builder)
builder.Property(x => x.ObjectIdentifier).HasMaxLength(100);
builder.Property(x => x.PayloadCategory).HasMaxLength(50);
builder.Property(x => x.Type);
+ builder.Property(x => x.BlobReference).HasMaxLength(32).IsUnicode(false).IsFixedLength(true);
builder.Ignore(x => x.EncryptedPayload);
}
diff --git a/Modules/Synchronization/src/Synchronization.Infrastructure/Persistence/Database/SynchronizationDbContext.cs b/Modules/Synchronization/src/Synchronization.Infrastructure/Persistence/Database/SynchronizationDbContext.cs
index 056eb45ea1..53f3b064e2 100644
--- a/Modules/Synchronization/src/Synchronization.Infrastructure/Persistence/Database/SynchronizationDbContext.cs
+++ b/Modules/Synchronization/src/Synchronization.Infrastructure/Persistence/Database/SynchronizationDbContext.cs
@@ -64,7 +64,7 @@ public async Task> GetDatawalletModif
var paginationResult = Database.IsNpgsql()
? await DatawalletModifications
- .FromSqlInterpolated($@"SELECT * FROM(SELECT *, ROW_NUMBER() OVER(PARTITION BY ""ObjectIdentifier"", ""Type"", ""PayloadCategory"" ORDER BY ""Index"" DESC) AS rank FROM ""Synchronization"".""DatawalletModifications"" m1 WHERE ""CreatedBy"" = {activeIdentityParam} AND ""Index"" > {localIndex ?? -1}) AS ignoreDuplicates WHERE rank = 1")
+ .FromSqlInterpolated($"""SELECT * FROM(SELECT *, ROW_NUMBER() OVER(PARTITION BY "ObjectIdentifier", "Type", "PayloadCategory" ORDER BY "Index" DESC) AS rank FROM "Synchronization"."DatawalletModifications" m1 WHERE "CreatedBy" = {activeIdentityParam} AND "Index" > {localIndex ?? -1}) AS ignoreDuplicates WHERE rank = 1""")
.AsNoTracking()
.OrderAndPaginate(m => m.Index, paginationFilter, cancellationToken)
: await DatawalletModifications
diff --git a/Modules/Synchronization/test/Synchronization.Application.Tests/DatawalletExtensions.cs b/Modules/Synchronization/test/Synchronization.Application.Tests/DatawalletExtensions.cs
index 69abdce11c..f8e4188053 100644
--- a/Modules/Synchronization/test/Synchronization.Application.Tests/DatawalletExtensions.cs
+++ b/Modules/Synchronization/test/Synchronization.Application.Tests/DatawalletExtensions.cs
@@ -7,7 +7,7 @@ public static class DatawalletExtensions
{
public static DatawalletModification AddModification(this Datawallet datawallet, AddModificationParameters parameters)
{
- return datawallet.AddModification(parameters.Type, parameters.DatawalletVersion, parameters.Collection, parameters.ObjectIdentifier, parameters.PayloadCategory, parameters.EncryptedPayload, parameters.CreatedByDevice);
+ return datawallet.AddModification(parameters.Type, parameters.DatawalletVersion, parameters.Collection, parameters.ObjectIdentifier, parameters.PayloadCategory, parameters.EncryptedPayload, parameters.CreatedByDevice, "");
}
public class AddModificationParameters
diff --git a/Modules/Synchronization/test/Synchronization.Application.Tests/DatawalletModificationBuilder.cs b/Modules/Synchronization/test/Synchronization.Application.Tests/DatawalletModificationBuilder.cs
deleted file mode 100644
index 66c2d27493..0000000000
--- a/Modules/Synchronization/test/Synchronization.Application.Tests/DatawalletModificationBuilder.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-using Backbone.Modules.Synchronization.Domain.Entities;
-using Enmeshed.DevelopmentKit.Identity.ValueObjects;
-using static Backbone.Modules.Synchronization.Domain.Entities.Datawallet;
-
-namespace Backbone.Modules.Synchronization.Application.Tests;
-
-public class DatawalletModificationBuilder
-{
- private string _collection;
- private DeviceId _createdByDevice;
- private Datawallet _datawallet;
- private byte[] _encryptedPayload;
- private long _index;
- private string _objectIdentifier;
- private string _payloadCategory;
- private DatawalletModificationType _type;
- private DatawalletVersion _version = new(1);
-
- public DatawalletModificationBuilder()
- {
- _index = 0;
- _type = DatawalletModificationType.Create;
- _collection = "ACollection";
- _objectIdentifier = "AnObjectIdentifier";
- _createdByDevice = TestDataGenerator.CreateRandomDeviceId();
- _payloadCategory = "APayloadCategory";
- _encryptedPayload = TestDataGenerator.CreateRandomBytes();
- }
-
- public DatawalletModificationBuilder WithIndex(long value)
- {
- _index = value;
- return this;
- }
-
- public DatawalletModificationBuilder WithType(DatawalletModificationType value)
- {
- _type = value;
- return this;
- }
-
- public DatawalletModificationBuilder WithCollection(string value)
- {
- _collection = value;
- return this;
- }
-
- public DatawalletModificationBuilder WithObjectIdentifier(string value)
- {
- _objectIdentifier = value;
- return this;
- }
-
- public DatawalletModificationBuilder WithCreatedByDevice(DeviceId value)
- {
- _createdByDevice = value;
- return this;
- }
-
- public DatawalletModificationBuilder WithPayloadCategory(string value)
- {
- _payloadCategory = value;
- return this;
- }
-
- public DatawalletModificationBuilder WithDatawallet(Datawallet datawallet)
- {
- _datawallet = datawallet;
- return this;
- }
-
- public DatawalletModificationBuilder WithEncryptedPayload(byte[] value)
- {
- _encryptedPayload = value;
- return this;
- }
-
- public DatawalletModificationBuilder WithVersion(DatawalletVersion value)
- {
- _version = value;
- return this;
- }
-
- public DatawalletModification Build()
- {
- if (_datawallet == null)
- throw new Exception("datawallet cannot be null");
- var modification = new DatawalletModification(_datawallet, _version, _index, _type, _collection, _objectIdentifier, _payloadCategory, _encryptedPayload, _createdByDevice);
-
- return modification;
- }
-}
diff --git a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Commands/PushDatawalletModifications/HandlerTests.cs b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Commands/PushDatawalletModifications/HandlerTests.cs
index c1b8cc1626..820ffc9a62 100644
--- a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Commands/PushDatawalletModifications/HandlerTests.cs
+++ b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Commands/PushDatawalletModifications/HandlerTests.cs
@@ -43,7 +43,7 @@ public HandlerTests()
public async Task Parallel_push_leads_to_an_error_for_one_call()
{
var arrangeContext = CreateDbContext();
- arrangeContext.SaveEntity(new Backbone.Modules.Synchronization.Domain.Entities.Datawallet(new Backbone.Modules.Synchronization.Domain.Entities.Datawallet.DatawalletVersion(1), _activeIdentity));
+ arrangeContext.SaveEntity(new Domain.Entities.Datawallet(new Domain.Entities.Datawallet.DatawalletVersion(1), _activeIdentity));
// By adding a save-delay to one of the calls, we can ensure that the second one will finish first, and therefore the first one
// will definitely run into an error regarding the duplicate database index.
diff --git a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Queries/GetDatawalletModifications/HandlerTests.cs b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Queries/GetDatawalletModifications/HandlerTests.cs
index 9a71c4ce78..f8324aa0ec 100644
--- a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Queries/GetDatawalletModifications/HandlerTests.cs
+++ b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Queries/GetDatawalletModifications/HandlerTests.cs
@@ -11,6 +11,7 @@
using FakeItEasy;
using FluentAssertions;
using FluentAssertions.Execution;
+using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Xunit;
@@ -348,14 +349,14 @@ public async void Returns_all_modifications_when_passing_no_local_index()
result.Should().HaveCount(2);
}
- private static Backbone.Modules.Synchronization.Domain.Entities.Datawallet CreateDatawalletForActiveIdentity(ushort version = DATAWALLET_VERSION)
+ private static Domain.Entities.Datawallet CreateDatawalletForActiveIdentity(ushort version = DATAWALLET_VERSION)
{
- return new Backbone.Modules.Synchronization.Domain.Entities.Datawallet(new Backbone.Modules.Synchronization.Domain.Entities.Datawallet.DatawalletVersion(version), ACTIVE_IDENTITY);
+ return new Domain.Entities.Datawallet(new Domain.Entities.Datawallet.DatawalletVersion(version), ACTIVE_IDENTITY);
}
- private static Backbone.Modules.Synchronization.Domain.Entities.Datawallet CreateDatawalletFor(IdentityAddress owner)
+ private static Domain.Entities.Datawallet CreateDatawalletFor(IdentityAddress owner)
{
- return new Backbone.Modules.Synchronization.Domain.Entities.Datawallet(new Backbone.Modules.Synchronization.Domain.Entities.Datawallet.DatawalletVersion(1), owner);
+ return new Domain.Entities.Datawallet(new Domain.Entities.Datawallet.DatawalletVersion(1), owner);
}
diff --git a/Modules/Synchronization/test/Synchronization.Domain.Tests/DatawalletTests.cs b/Modules/Synchronization/test/Synchronization.Domain.Tests/DatawalletTests.cs
index 3a78f9ebb1..34b6de1525 100644
--- a/Modules/Synchronization/test/Synchronization.Domain.Tests/DatawalletTests.cs
+++ b/Modules/Synchronization/test/Synchronization.Domain.Tests/DatawalletTests.cs
@@ -82,6 +82,6 @@ private static Datawallet CreateDatawallet(Datawallet.DatawalletVersion version)
private static DatawalletModification AddModificationToDatawallet(Datawallet datawallet)
{
- return datawallet.AddModification(DatawalletModificationType.Create, new Datawallet.DatawalletVersion(1), "aCollection", "anId", "aPayloadCategory", TestDataGenerator.CreateRandomBytes(), TestDataGenerator.CreateRandomDeviceId());
+ return datawallet.AddModification(DatawalletModificationType.Create, new Datawallet.DatawalletVersion(1), "aCollection", "anId", "aPayloadCategory", TestDataGenerator.CreateRandomBytes(), TestDataGenerator.CreateRandomDeviceId(), "aBlobName");
}
}