diff --git a/backend/Squidex.sln b/backend/Squidex.sln
index 7f3458932..eeb79d405 100644
--- a/backend/Squidex.sln
+++ b/backend/Squidex.sln
@@ -16,8 +16,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Infrastructure.Test
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Apps.Core.Tests", "tests\Squidex.Domain.Apps.Core.Tests\Squidex.Domain.Apps.Core.Tests.csproj", "{FD0AFD44-7A93-4F9E-B5ED-72582392E435}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Infrastructure.MongoDb", "src\Squidex.Infrastructure.MongoDb\Squidex.Infrastructure.MongoDb.csproj", "{6A811927-3C37-430A-90F4-503E37123956}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{94207AA6-4923-4183-A558-E0F8196B8CA3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Shared", "src\Squidex.Shared\Squidex.Shared.csproj", "{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}"
@@ -42,8 +40,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Apps.Entitie
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Apps.Entities.Tests", "tests\Squidex.Domain.Apps.Entities.Tests\Squidex.Domain.Apps.Entities.Tests.csproj", "{AA003372-CD8D-4DBC-962C-F61E0C93CF05}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Apps.Entities.MongoDb", "src\Squidex.Domain.Apps.Entities.MongoDb\Squidex.Domain.Apps.Entities.MongoDb.csproj", "{7DA5B308-D950-4496-93D5-21D6C4D91644}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Web.Tests", "tests\Squidex.Web.Tests\Squidex.Web.Tests.csproj", "{7E8CC864-4C6E-496F-A672-9F9AD8874835}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "extensions", "extensions", "{FB8BC3A2-2010-4C3C-A87D-D4A98C05EE52}"
@@ -56,7 +52,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Web", "src\Squidex.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Migrations", "src\Migrations\Migrations.csproj", "{23615A39-F3FB-4575-A91C-535899DFB636}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Infrastructure.GetEventStore", "src\Squidex.Infrastructure.GetEventStore\Squidex.Infrastructure.GetEventStore.csproj", "{4CFBD9FF-6565-457E-B81C-9FCEFEE854BC}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{3378B841-53F8-48CC-87C1-1B30CF912BFD}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squidex.Data.MongoDb", "src\Squidex.Data.MongoDb\Squidex.Data.MongoDb.csproj", "{F754F05E-02FF-47B2-AB46-BB05C7E6B29D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squidex.Data.Tests", "tests\Squidex.Data.Tests\Squidex.Data.Tests.csproj", "{AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -108,14 +108,6 @@ Global
{FD0AFD44-7A93-4F9E-B5ED-72582392E435}.Release|Any CPU.Build.0 = Release|Any CPU
{FD0AFD44-7A93-4F9E-B5ED-72582392E435}.Release|x64.ActiveCfg = Release|Any CPU
{FD0AFD44-7A93-4F9E-B5ED-72582392E435}.Release|x86.ActiveCfg = Release|Any CPU
- {6A811927-3C37-430A-90F4-503E37123956}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6A811927-3C37-430A-90F4-503E37123956}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6A811927-3C37-430A-90F4-503E37123956}.Debug|x64.ActiveCfg = Debug|Any CPU
- {6A811927-3C37-430A-90F4-503E37123956}.Debug|x86.ActiveCfg = Debug|Any CPU
- {6A811927-3C37-430A-90F4-503E37123956}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6A811927-3C37-430A-90F4-503E37123956}.Release|Any CPU.Build.0 = Release|Any CPU
- {6A811927-3C37-430A-90F4-503E37123956}.Release|x64.ActiveCfg = Release|Any CPU
- {6A811927-3C37-430A-90F4-503E37123956}.Release|x86.ActiveCfg = Release|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -212,18 +204,6 @@ Global
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Release|x64.Build.0 = Release|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Release|x86.ActiveCfg = Release|Any CPU
{AA003372-CD8D-4DBC-962C-F61E0C93CF05}.Release|x86.Build.0 = Release|Any CPU
- {7DA5B308-D950-4496-93D5-21D6C4D91644}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7DA5B308-D950-4496-93D5-21D6C4D91644}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {7DA5B308-D950-4496-93D5-21D6C4D91644}.Debug|x64.ActiveCfg = Debug|Any CPU
- {7DA5B308-D950-4496-93D5-21D6C4D91644}.Debug|x64.Build.0 = Debug|Any CPU
- {7DA5B308-D950-4496-93D5-21D6C4D91644}.Debug|x86.ActiveCfg = Debug|Any CPU
- {7DA5B308-D950-4496-93D5-21D6C4D91644}.Debug|x86.Build.0 = Debug|Any CPU
- {7DA5B308-D950-4496-93D5-21D6C4D91644}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7DA5B308-D950-4496-93D5-21D6C4D91644}.Release|Any CPU.Build.0 = Release|Any CPU
- {7DA5B308-D950-4496-93D5-21D6C4D91644}.Release|x64.ActiveCfg = Release|Any CPU
- {7DA5B308-D950-4496-93D5-21D6C4D91644}.Release|x64.Build.0 = Release|Any CPU
- {7DA5B308-D950-4496-93D5-21D6C4D91644}.Release|x86.ActiveCfg = Release|Any CPU
- {7DA5B308-D950-4496-93D5-21D6C4D91644}.Release|x86.Build.0 = Release|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7E8CC864-4C6E-496F-A672-9F9AD8874835}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -272,18 +252,30 @@ Global
{23615A39-F3FB-4575-A91C-535899DFB636}.Release|x64.Build.0 = Release|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Release|x86.ActiveCfg = Release|Any CPU
{23615A39-F3FB-4575-A91C-535899DFB636}.Release|x86.Build.0 = Release|Any CPU
- {4CFBD9FF-6565-457E-B81C-9FCEFEE854BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4CFBD9FF-6565-457E-B81C-9FCEFEE854BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4CFBD9FF-6565-457E-B81C-9FCEFEE854BC}.Debug|x64.ActiveCfg = Debug|Any CPU
- {4CFBD9FF-6565-457E-B81C-9FCEFEE854BC}.Debug|x64.Build.0 = Debug|Any CPU
- {4CFBD9FF-6565-457E-B81C-9FCEFEE854BC}.Debug|x86.ActiveCfg = Debug|Any CPU
- {4CFBD9FF-6565-457E-B81C-9FCEFEE854BC}.Debug|x86.Build.0 = Debug|Any CPU
- {4CFBD9FF-6565-457E-B81C-9FCEFEE854BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4CFBD9FF-6565-457E-B81C-9FCEFEE854BC}.Release|Any CPU.Build.0 = Release|Any CPU
- {4CFBD9FF-6565-457E-B81C-9FCEFEE854BC}.Release|x64.ActiveCfg = Release|Any CPU
- {4CFBD9FF-6565-457E-B81C-9FCEFEE854BC}.Release|x64.Build.0 = Release|Any CPU
- {4CFBD9FF-6565-457E-B81C-9FCEFEE854BC}.Release|x86.ActiveCfg = Release|Any CPU
- {4CFBD9FF-6565-457E-B81C-9FCEFEE854BC}.Release|x86.Build.0 = Release|Any CPU
+ {F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Debug|x64.Build.0 = Debug|Any CPU
+ {F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Debug|x86.Build.0 = Debug|Any CPU
+ {F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Release|x64.ActiveCfg = Release|Any CPU
+ {F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Release|x64.Build.0 = Release|Any CPU
+ {F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Release|x86.ActiveCfg = Release|Any CPU
+ {F754F05E-02FF-47B2-AB46-BB05C7E6B29D}.Release|x86.Build.0 = Release|Any CPU
+ {AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Debug|x64.Build.0 = Debug|Any CPU
+ {AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Debug|x86.Build.0 = Debug|Any CPU
+ {AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Release|x64.ActiveCfg = Release|Any CPU
+ {AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Release|x64.Build.0 = Release|Any CPU
+ {AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Release|x86.ActiveCfg = Release|Any CPU
+ {AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -293,7 +285,6 @@ Global
{25F66C64-058A-4D44-BC0C-F12A054F9A91} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{7FD0A92B-7862-4BB1-932B-B52A9CACB56B} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{FD0AFD44-7A93-4F9E-B5ED-72582392E435} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
- {6A811927-3C37-430A-90F4-503E37123956} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F} = {7EDE8CF1-B1E4-4005-B154-834B944E0D7A}
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0} = {7EDE8CF1-B1E4-4005-B154-834B944E0D7A}
{27CF800D-890F-4882-BF05-44EC3233537D} = {7EDE8CF1-B1E4-4005-B154-834B944E0D7A}
@@ -302,12 +293,12 @@ Global
{6B3F75B6-5888-468E-BA4F-4FC725DAEF31} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{79FEF326-CA5E-4698-B2BA-C16A4580B4D5} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{AA003372-CD8D-4DBC-962C-F61E0C93CF05} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
- {7DA5B308-D950-4496-93D5-21D6C4D91644} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{7E8CC864-4C6E-496F-A672-9F9AD8874835} = {7EDE8CF1-B1E4-4005-B154-834B944E0D7A}
{F3C41B82-6A67-409A-B7FE-54543EE4F38B} = {FB8BC3A2-2010-4C3C-A87D-D4A98C05EE52}
{5B2D251F-46E3-486A-AE16-E3FE06B559ED} = {7EDE8CF1-B1E4-4005-B154-834B944E0D7A}
{23615A39-F3FB-4575-A91C-535899DFB636} = {94207AA6-4923-4183-A558-E0F8196B8CA3}
- {4CFBD9FF-6565-457E-B81C-9FCEFEE854BC} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
+ {F754F05E-02FF-47B2-AB46-BB05C7E6B29D} = {3378B841-53F8-48CC-87C1-1B30CF912BFD}
+ {AA2F3C32-E3C8-4DF3-A365-F25C7EC19BCD} = {3378B841-53F8-48CC-87C1-1B30CF912BFD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {02F2E872-3141-44F5-BD6A-33CD84E9FE08}
diff --git a/backend/src/Migrations/Migrations.csproj b/backend/src/Migrations/Migrations.csproj
index 06781ee03..2908dae94 100644
--- a/backend/src/Migrations/Migrations.csproj
+++ b/backend/src/Migrations/Migrations.csproj
@@ -14,11 +14,10 @@
+
-
-
diff --git a/backend/src/Migrations/Migrations/ConvertEventStore.cs b/backend/src/Migrations/Migrations/ConvertEventStore.cs
index bfe2dc64d..bd75add73 100644
--- a/backend/src/Migrations/Migrations/ConvertEventStore.cs
+++ b/backend/src/Migrations/Migrations/ConvertEventStore.cs
@@ -7,9 +7,10 @@
using MongoDB.Bson;
using MongoDB.Driver;
-using Squidex.Infrastructure.EventSourcing;
+using Squidex.Events;
+using Squidex.Events.Mongo;
+using Squidex.Infrastructure;
using Squidex.Infrastructure.Migrations;
-using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations;
diff --git a/backend/src/Migrations/Migrations/ConvertEventStoreAppId.cs b/backend/src/Migrations/Migrations/ConvertEventStoreAppId.cs
index 842c0fcfe..0ed68b0c5 100644
--- a/backend/src/Migrations/Migrations/ConvertEventStoreAppId.cs
+++ b/backend/src/Migrations/Migrations/ConvertEventStoreAppId.cs
@@ -7,10 +7,10 @@
using MongoDB.Bson;
using MongoDB.Driver;
+using Squidex.Events;
+using Squidex.Events.Mongo;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Migrations;
-using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations;
diff --git a/backend/src/Migrations/Migrations/MongoDb/AddAppIdToEventStream.cs b/backend/src/Migrations/Migrations/MongoDb/AddAppIdToEventStream.cs
index 5c272abae..d8ed6c045 100644
--- a/backend/src/Migrations/Migrations/MongoDb/AddAppIdToEventStream.cs
+++ b/backend/src/Migrations/Migrations/MongoDb/AddAppIdToEventStream.cs
@@ -10,7 +10,6 @@ using MongoDB.Bson;
using MongoDB.Driver;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Migrations;
-using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.Tasks;
namespace Migrations.Migrations.MongoDb;
diff --git a/backend/src/Migrations/Migrations/MongoDb/ConvertDocumentIds.cs b/backend/src/Migrations/Migrations/MongoDb/ConvertDocumentIds.cs
index ca28142d8..e0f040b86 100644
--- a/backend/src/Migrations/Migrations/MongoDb/ConvertDocumentIds.cs
+++ b/backend/src/Migrations/Migrations/MongoDb/ConvertDocumentIds.cs
@@ -9,7 +9,6 @@ using MongoDB.Bson;
using MongoDB.Driver;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Migrations;
-using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.Tasks;
namespace Migrations.Migrations.MongoDb;
diff --git a/backend/src/Migrations/Migrations/MongoDb/ConvertOldSnapshotStores.cs b/backend/src/Migrations/Migrations/MongoDb/ConvertOldSnapshotStores.cs
index 8e473107f..3e66fea70 100644
--- a/backend/src/Migrations/Migrations/MongoDb/ConvertOldSnapshotStores.cs
+++ b/backend/src/Migrations/Migrations/MongoDb/ConvertOldSnapshotStores.cs
@@ -7,8 +7,8 @@
using MongoDB.Bson;
using MongoDB.Driver;
+using Squidex.Infrastructure;
using Squidex.Infrastructure.Migrations;
-using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations.MongoDb;
diff --git a/backend/src/Migrations/Migrations/MongoDb/ConvertRuleEventsJson.cs b/backend/src/Migrations/Migrations/MongoDb/ConvertRuleEventsJson.cs
index d8041c49e..2733e53bf 100644
--- a/backend/src/Migrations/Migrations/MongoDb/ConvertRuleEventsJson.cs
+++ b/backend/src/Migrations/Migrations/MongoDb/ConvertRuleEventsJson.cs
@@ -7,8 +7,8 @@
using MongoDB.Bson;
using MongoDB.Driver;
+using Squidex.Infrastructure;
using Squidex.Infrastructure.Migrations;
-using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations.MongoDb;
diff --git a/backend/src/Migrations/Migrations/MongoDb/CopyRuleStatistics.cs b/backend/src/Migrations/Migrations/MongoDb/CopyRuleStatistics.cs
index 4b3d77538..09c4a7969 100644
--- a/backend/src/Migrations/Migrations/MongoDb/CopyRuleStatistics.cs
+++ b/backend/src/Migrations/Migrations/MongoDb/CopyRuleStatistics.cs
@@ -11,7 +11,6 @@ using MongoDB.Driver;
using Squidex.Domain.Apps.Entities.Rules;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Migrations;
-using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations.MongoDb;
diff --git a/backend/src/Migrations/Migrations/MongoDb/RenameAssetMetadata.cs b/backend/src/Migrations/Migrations/MongoDb/RenameAssetMetadata.cs
index 2356a4813..ebdcc0a28 100644
--- a/backend/src/Migrations/Migrations/MongoDb/RenameAssetMetadata.cs
+++ b/backend/src/Migrations/Migrations/MongoDb/RenameAssetMetadata.cs
@@ -7,8 +7,8 @@
using MongoDB.Bson;
using MongoDB.Driver;
+using Squidex.Infrastructure;
using Squidex.Infrastructure.Migrations;
-using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations.MongoDb;
diff --git a/backend/src/Migrations/Migrations/MongoDb/RenameAssetSlugField.cs b/backend/src/Migrations/Migrations/MongoDb/RenameAssetSlugField.cs
index 6249f205e..0a2e80efe 100644
--- a/backend/src/Migrations/Migrations/MongoDb/RenameAssetSlugField.cs
+++ b/backend/src/Migrations/Migrations/MongoDb/RenameAssetSlugField.cs
@@ -7,8 +7,8 @@
using MongoDB.Bson;
using MongoDB.Driver;
+using Squidex.Infrastructure;
using Squidex.Infrastructure.Migrations;
-using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations.MongoDb;
diff --git a/backend/src/Migrations/Migrations/MongoDb/RestructureContentCollection.cs b/backend/src/Migrations/Migrations/MongoDb/RestructureContentCollection.cs
index cd62d015c..30c06df6a 100644
--- a/backend/src/Migrations/Migrations/MongoDb/RestructureContentCollection.cs
+++ b/backend/src/Migrations/Migrations/MongoDb/RestructureContentCollection.cs
@@ -7,8 +7,8 @@
using MongoDB.Bson;
using MongoDB.Driver;
+using Squidex.Infrastructure;
using Squidex.Infrastructure.Migrations;
-using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations.MongoDb;
diff --git a/backend/src/Migrations/RebuilderExtensions.cs b/backend/src/Migrations/RebuilderExtensions.cs
index 334949a5b..580c20123 100644
--- a/backend/src/Migrations/RebuilderExtensions.cs
+++ b/backend/src/Migrations/RebuilderExtensions.cs
@@ -15,8 +15,8 @@ using Squidex.Domain.Apps.Entities.Assets.DomainObject;
using Squidex.Domain.Apps.Entities.Contents.DomainObject;
using Squidex.Domain.Apps.Entities.Rules.DomainObject;
using Squidex.Domain.Apps.Entities.Schemas.DomainObject;
+using Squidex.Events;
using Squidex.Infrastructure.Commands;
-using Squidex.Infrastructure.EventSourcing;
namespace Migrations;
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/AdaptIdVisitor.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/AdaptIdVisitor.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/AdaptIdVisitor.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/AdaptIdVisitor.cs
index fcbcb0eec..cf2955d5c 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/AdaptIdVisitor.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/AdaptIdVisitor.cs
@@ -11,7 +11,7 @@ using Squidex.Infrastructure.Queries;
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
-namespace Squidex.Domain.Apps.Entities.MongoDb;
+namespace Squidex.Domain.Apps.Entities;
internal sealed class AdaptIdVisitor : TransformVisitor
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppEntity.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Apps/MongoAppEntity.cs
similarity index 96%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppEntity.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Apps/MongoAppEntity.cs
index 1dd6a81f0..d46ce6105 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppEntity.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Apps/MongoAppEntity.cs
@@ -11,7 +11,7 @@ using Squidex.Domain.Apps.Core.Apps;
using Squidex.Infrastructure;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Apps;
+namespace Squidex.Domain.Apps.Entities.Apps;
public sealed class MongoAppEntity : MongoState
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppRepository.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Apps/MongoAppRepository.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppRepository.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Apps/MongoAppRepository.cs
index caf03b7c7..cf0fd46c7 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Apps/MongoAppRepository.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Apps/MongoAppRepository.cs
@@ -11,7 +11,7 @@ using Squidex.Domain.Apps.Entities.Apps.Repositories;
using Squidex.Infrastructure;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Apps;
+namespace Squidex.Domain.Apps.Entities.Apps;
public sealed class MongoAppRepository(IMongoDatabase database) : MongoSnapshotStoreBase(database), IAppRepository, IDeleter
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/AssetItemClassMap.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/AssetItemClassMap.cs
similarity index 93%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/AssetItemClassMap.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/AssetItemClassMap.cs
index 49c41a718..54f1fec2c 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/AssetItemClassMap.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/AssetItemClassMap.cs
@@ -8,7 +8,7 @@
using MongoDB.Bson.Serialization;
using Squidex.Domain.Apps.Core.Assets;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Assets;
+namespace Squidex.Domain.Apps.Entities.Assets;
internal static class AssetItemClassMap
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetEntity.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetEntity.cs
similarity index 97%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetEntity.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetEntity.cs
index 6c20a54c6..a9cbdccb5 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetEntity.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetEntity.cs
@@ -8,11 +8,10 @@
using MongoDB.Bson.Serialization;
using Squidex.Domain.Apps.Core.Assets;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Assets;
+namespace Squidex.Domain.Apps.Entities.Assets;
public record MongoAssetEntity : Asset, IVersionedEntity
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderEntity.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderEntity.cs
similarity index 95%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderEntity.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderEntity.cs
index 19c65a6ef..6112dfe8c 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderEntity.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderEntity.cs
@@ -8,11 +8,10 @@
using MongoDB.Bson.Serialization;
using Squidex.Domain.Apps.Core.Assets;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Assets;
+namespace Squidex.Domain.Apps.Entities.Assets;
public record MongoAssetFolderEntity : AssetFolder, IVersionedEntity
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderRepository.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderRepository.cs
index b4045fa7f..608cad584 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderRepository.cs
@@ -7,9 +7,9 @@
using MongoDB.Driver;
using Squidex.Domain.Apps.Core.Assets;
+using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Domain.Apps.Entities.Assets.Repositories;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
namespace Squidex.Domain.Apps.Entities.MongoDb.Assets;
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository_SnapshotStore.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderRepository_SnapshotStore.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository_SnapshotStore.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderRepository_SnapshotStore.cs
index 6b128d923..e20d62bf5 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository_SnapshotStore.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetFolderRepository_SnapshotStore.cs
@@ -8,8 +8,8 @@
using MongoDB.Driver;
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Assets;
+using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.States;
#pragma warning disable MA0048 // File name must match type name
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetRepository.cs
similarity index 97%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetRepository.cs
index d84d3231b..b38c64d7e 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetRepository.cs
@@ -9,11 +9,12 @@ using System.Runtime.CompilerServices;
using Microsoft.Extensions.Logging;
using MongoDB.Driver;
using Squidex.Domain.Apps.Core.Assets;
+using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Domain.Apps.Entities.Assets.Repositories;
-using Squidex.Domain.Apps.Entities.MongoDb.Assets.Visitors;
+using Squidex.Domain.Apps.Entities.Assets.Visitors;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
-using Squidex.Infrastructure.MongoDb.Queries;
+using Squidex.Infrastructure.Counts;
+using Squidex.Infrastructure.Queries;
using Squidex.Infrastructure.Translations;
namespace Squidex.Domain.Apps.Entities.MongoDb.Assets;
@@ -99,7 +100,7 @@ public sealed partial class MongoAssetRepository : MongoRepositoryBase 0 })
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository_SnapshotStore.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetRepository_SnapshotStore.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository_SnapshotStore.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetRepository_SnapshotStore.cs
index 337689b47..6e86ca64c 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository_SnapshotStore.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoAssetRepository_SnapshotStore.cs
@@ -8,8 +8,8 @@
using MongoDB.Driver;
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Assets;
+using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.States;
#pragma warning disable MA0048 // File name must match type name
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoShardedAssetRepository.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoShardedAssetRepository.cs
similarity index 96%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoShardedAssetRepository.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoShardedAssetRepository.cs
index b900b0680..832580e36 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoShardedAssetRepository.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/MongoShardedAssetRepository.cs
@@ -8,10 +8,11 @@
using MongoDB.Driver;
using Squidex.Domain.Apps.Core.Assets;
using Squidex.Domain.Apps.Entities.Assets.Repositories;
+using Squidex.Domain.Apps.Entities.MongoDb.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Assets;
+namespace Squidex.Domain.Apps.Entities.Assets;
public sealed class MongoShardedAssetRepository(IShardingStrategy sharding, Func factory) : ShardedSnapshotStore(sharding, factory, x => x.AppId.Id), IAssetRepository, IDeleter
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FindExtensions.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/Visitors/FindExtensions.cs
similarity index 93%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FindExtensions.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/Visitors/FindExtensions.cs
index 4da26991a..043ad189b 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FindExtensions.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/Visitors/FindExtensions.cs
@@ -7,16 +7,15 @@
using MongoDB.Driver;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb.Queries;
using Squidex.Infrastructure.Queries;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Assets.Visitors;
+namespace Squidex.Domain.Apps.Entities.Assets.Visitors;
public static class FindExtensions
{
private static readonly FilterDefinitionBuilder Filter = Builders.Filter;
- public static ClrQuery AdjustToModel(this ClrQuery query, DomainId appId)
+ public static ClrQuery AdjustToAssetModel(this ClrQuery query, DomainId appId)
{
if (query.Filter != null)
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FirstPascalPathConverter.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/Visitors/FirstPascalPathConverter.cs
similarity index 93%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FirstPascalPathConverter.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/Visitors/FirstPascalPathConverter.cs
index 99b9ca2f6..f4185e05b 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FirstPascalPathConverter.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/Visitors/FirstPascalPathConverter.cs
@@ -8,7 +8,7 @@
using Squidex.Infrastructure;
using Squidex.Infrastructure.Queries;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Assets.Visitors;
+namespace Squidex.Domain.Apps.Entities.Assets.Visitors;
public sealed class FirstPascalPathConverter : TransformVisitor
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FirstPascalPathExtension.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/Visitors/FirstPascalPathExtension.cs
similarity index 91%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FirstPascalPathExtension.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/Visitors/FirstPascalPathExtension.cs
index 96ff823bb..b48ce840b 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FirstPascalPathExtension.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Assets/Visitors/FirstPascalPathExtension.cs
@@ -8,7 +8,7 @@
using Squidex.Infrastructure.Queries;
using Squidex.Text;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Assets.Visitors;
+namespace Squidex.Domain.Apps.Entities.Assets.Visitors;
public static class FirstPascalPathExtension
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/BsonUniqueContentIdSerializer.IdInfo.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/BsonUniqueContentIdSerializer.IdInfo.cs
similarity index 100%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/BsonUniqueContentIdSerializer.IdInfo.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/BsonUniqueContentIdSerializer.IdInfo.cs
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/BsonUniqueContentIdSerializer.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/BsonUniqueContentIdSerializer.cs
similarity index 100%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/BsonUniqueContentIdSerializer.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/BsonUniqueContentIdSerializer.cs
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/IndexParser.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/IndexParser.cs
similarity index 93%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/IndexParser.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/IndexParser.cs
index fc7677dcd..f42e215e0 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/IndexParser.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/IndexParser.cs
@@ -7,11 +7,11 @@
using System.Diagnostics.CodeAnalysis;
using MongoDB.Bson;
-using Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+using Squidex.Domain.Apps.Entities.Contents.Operations;
using Squidex.Infrastructure.Queries;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents;
+namespace Squidex.Domain.Apps.Entities.Contents;
public static class IndexParser
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentCollection.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentCollection.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentCollection.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentCollection.cs
index 4ea3e5dbe..371055be8 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentCollection.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentCollection.cs
@@ -11,16 +11,16 @@ using NodaTime;
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas;
-using Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+using Squidex.Domain.Apps.Entities.Contents.Operations;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
+using Squidex.Infrastructure.Counts;
using Squidex.Infrastructure.Queries;
using Squidex.Infrastructure.States;
using Squidex.Infrastructure.Translations;
#pragma warning disable IDE0060 // Remove unused parameter
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents;
+namespace Squidex.Domain.Apps.Entities.Contents;
public sealed class MongoContentCollection : MongoRepositoryBase
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentEntity.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentEntity.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentEntity.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentEntity.cs
index dd3142a78..881031c95 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentEntity.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentEntity.cs
@@ -10,10 +10,9 @@ using NodaTime;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.ExtractReferenceIds;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents;
+namespace Squidex.Domain.Apps.Entities.Contents;
public record MongoContentEntity : Content, IVersionedEntity
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentRepository.cs
similarity index 99%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentRepository.cs
index eec20accf..d8588e8be 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentRepository.cs
@@ -18,7 +18,6 @@ using Squidex.Domain.Apps.Entities.Contents.Repositories;
using Squidex.Hosting;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
-using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.Queries;
using Squidex.Infrastructure.States;
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentRepository_SnapshotStore.cs
similarity index 99%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentRepository_SnapshotStore.cs
index 48a4d7d7e..0a396c043 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoContentRepository_SnapshotStore.cs
@@ -8,6 +8,7 @@
using MongoDB.Driver;
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Contents;
+using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Infrastructure;
using Squidex.Infrastructure.States;
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoShardedContentRepository.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoShardedContentRepository.cs
similarity index 97%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoShardedContentRepository.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoShardedContentRepository.cs
index 783aaecf6..db651d74a 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoShardedContentRepository.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/MongoShardedContentRepository.cs
@@ -10,13 +10,13 @@ using NodaTime;
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas;
-using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Domain.Apps.Entities.Contents.Repositories;
+using Squidex.Domain.Apps.Entities.MongoDb.Contents;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Queries;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents;
+namespace Squidex.Domain.Apps.Entities.Contents;
public sealed class MongoShardedContentRepository(IShardingStrategy sharding, Func factory) : ShardedSnapshotStore(sharding, factory, x => x.AppId.Id), IContentRepository, IDeleter
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/Adapt.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/Adapt.cs
similarity index 95%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/Adapt.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/Adapt.cs
index ff4b2984e..2a3f21835 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/Adapt.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/Adapt.cs
@@ -8,11 +8,10 @@
using GraphQL;
using MongoDB.Bson.Serialization;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.Queries;
using Squidex.Infrastructure.Queries.OData;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+namespace Squidex.Domain.Apps.Entities.Contents.Operations;
public static class Adapt
{
@@ -105,7 +104,7 @@ public static class Adapt
return result;
}
- public static ClrQuery AdjustToModel(this ClrQuery query, DomainId appId)
+ public static ClrQuery AdjustToContentModel(this ClrQuery query, DomainId appId)
{
if (query.Filter != null)
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/AdaptionVisitor.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/AdaptionVisitor.cs
similarity index 94%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/AdaptionVisitor.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/AdaptionVisitor.cs
index a889e5cd5..fb1bc1983 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/AdaptionVisitor.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/AdaptionVisitor.cs
@@ -8,7 +8,7 @@
using Squidex.Infrastructure;
using Squidex.Infrastructure.Queries;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+namespace Squidex.Domain.Apps.Entities.Contents.Operations;
internal sealed class AdaptionVisitor : TransformVisitor
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/Extensions.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/Extensions.cs
similarity index 96%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/Extensions.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/Extensions.cs
index 94eb3390e..d413d977d 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/Extensions.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/Extensions.cs
@@ -12,11 +12,9 @@ using MongoDB.Driver;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
-using Squidex.Infrastructure.MongoDb.Queries;
using Squidex.Infrastructure.Queries;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+namespace Squidex.Domain.Apps.Entities.Contents.Operations;
public static class Extensions
{
@@ -182,12 +180,12 @@ public static class Extensions
public static IFindFluent SelectFields(this IFindFluent find, IEnumerable? fields)
{
- return find.Project(BuildProjection(fields));
+ return find.Project(BuildProjection(fields));
}
public static IAggregateFluent SelectFields(this IAggregateFluent find, IEnumerable? fields)
{
- return find.Project(BuildProjection(fields));
+ return find.Project(BuildProjection(fields));
}
public static ProjectionDefinition BuildProjection(IEnumerable? fields)
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/OperationBase.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/OperationBase.cs
similarity index 88%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/OperationBase.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/OperationBase.cs
index 58d60ff2e..228807312 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/OperationBase.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/OperationBase.cs
@@ -6,9 +6,9 @@
// ==========================================================================
using MongoDB.Driver;
-using Squidex.Infrastructure.MongoDb;
+using Squidex.Infrastructure;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+namespace Squidex.Domain.Apps.Entities.Contents.Operations;
public abstract class OperationBase : MongoBase
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryAsStream.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryAsStream.cs
similarity index 97%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryAsStream.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryAsStream.cs
index 8af2f385b..1a9247963 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryAsStream.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryAsStream.cs
@@ -11,7 +11,7 @@ using MongoDB.Driver;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+namespace Squidex.Domain.Apps.Entities.Contents.Operations;
public sealed class QueryAsStream : OperationBase
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryById.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryById.cs
similarity index 93%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryById.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryById.cs
index d2e7e576a..4e02ad8d7 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryById.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryById.cs
@@ -10,7 +10,7 @@ using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+namespace Squidex.Domain.Apps.Entities.Contents.Operations;
internal sealed class QueryById : OperationBase
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryByIds.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryByIds.cs
similarity index 94%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryByIds.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryByIds.cs
index c315a30b4..c30478d63 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryByIds.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryByIds.cs
@@ -11,11 +11,9 @@ using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Collections;
-using Squidex.Infrastructure.MongoDb;
-using Squidex.Infrastructure.MongoDb.Queries;
using Squidex.Infrastructure.Queries;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+namespace Squidex.Domain.Apps.Entities.Contents.Operations;
internal sealed class QueryByIds : OperationBase
{
@@ -44,7 +42,7 @@ internal sealed class QueryByIds : OperationBase
}
// We need to translate the query names to the document field names in MongoDB.
- var query = q.Query.AdjustToModel(app.Id);
+ var query = q.Query.AdjustToContentModel(app.Id);
// Create a filter from the Ids and ensure that the content ids match to the schema IDs.
var filter = CreateFilter(app.Id, schemas.Select(x => x.Id), q.Ids.ToHashSet(), query.Filter);
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryByQuery.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryByQuery.cs
similarity index 96%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryByQuery.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryByQuery.cs
index 202627add..70616998c 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryByQuery.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryByQuery.cs
@@ -10,11 +10,10 @@ using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
-using Squidex.Infrastructure.MongoDb.Queries;
+using Squidex.Infrastructure.Counts;
using Squidex.Infrastructure.Queries;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+namespace Squidex.Domain.Apps.Entities.Contents.Operations;
internal sealed class QueryByQuery(MongoCountCollection countCollection) : OperationBase
{
@@ -52,7 +51,7 @@ internal sealed class QueryByQuery(MongoCountCollection countCollection) : Opera
CancellationToken ct)
{
// We need to translate the query names to the document field names in MongoDB.
- var query = q.Query.AdjustToModel(app.Id);
+ var query = q.Query.AdjustToContentModel(app.Id);
var (filter, isDefault) = CreateFilter(app.Id, schemas.Select(x => x.Id), query, q.Reference, q.CreatedBy);
@@ -83,7 +82,7 @@ internal sealed class QueryByQuery(MongoCountCollection countCollection) : Opera
CancellationToken ct)
{
// We need to translate the query names to the document field names in MongoDB.
- var query = q.Query.AdjustToModel(schema.AppId.Id);
+ var query = q.Query.AdjustToContentModel(schema.AppId.Id);
// Default means that no other filters are applied and we only query by app and schema.
var (filter, isDefault) = CreateFilter(schema.AppId.Id, Enumerable.Repeat(schema.Id, 1), query, q.Reference, q.CreatedBy);
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryInDedicatedCollection.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryInDedicatedCollection.cs
similarity index 97%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryInDedicatedCollection.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryInDedicatedCollection.cs
index 87ffb7ba7..88c7ebf19 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryInDedicatedCollection.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryInDedicatedCollection.cs
@@ -11,12 +11,10 @@ using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
-using Squidex.Infrastructure.MongoDb.Queries;
using Squidex.Infrastructure.Queries;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+namespace Squidex.Domain.Apps.Entities.Contents.Operations;
internal sealed class QueryInDedicatedCollection(IMongoClient mongoClient, string prefixDatabase, string prefixCollection) : MongoBase
{
@@ -70,7 +68,7 @@ internal sealed class QueryInDedicatedCollection(IMongoClient mongoClient, strin
CancellationToken ct)
{
// We need to translate the query names to the document field names in MongoDB.
- var query = q.Query.AdjustToModel(schema.AppId.Id);
+ var query = q.Query.AdjustToContentModel(schema.AppId.Id);
var filter = CreateFilter(query, q.Reference, q.CreatedBy);
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryReferences.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryReferences.cs
similarity index 96%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryReferences.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryReferences.cs
index 4d9f60e53..95a91b1ab 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryReferences.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryReferences.cs
@@ -12,7 +12,7 @@ using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+namespace Squidex.Domain.Apps.Entities.Contents.Operations;
internal sealed class QueryReferences(QueryByIds queryByIds) : OperationBase
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryReferrers.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryReferrers.cs
similarity index 95%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryReferrers.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryReferrers.cs
index e2eb91279..39cdd3bc5 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryReferrers.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryReferrers.cs
@@ -10,9 +10,8 @@ using MongoDB.Driver;
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+namespace Squidex.Domain.Apps.Entities.Contents.Operations;
internal sealed class QueryReferrers : OperationBase
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryScheduled.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryScheduled.cs
similarity index 95%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryScheduled.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryScheduled.cs
index 494e33859..22cf46a7c 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryScheduled.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Contents/Operations/QueryScheduled.cs
@@ -11,11 +11,10 @@ using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
#pragma warning disable MA0073 // Avoid comparison with bool constant
-namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations;
+namespace Squidex.Domain.Apps.Entities.Contents.Operations;
internal sealed class QueryScheduled : OperationBase
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/EntityClassMap.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/EntityClassMap.cs
similarity index 97%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/EntityClassMap.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/EntityClassMap.cs
index f0abbe927..89646ee6a 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/EntityClassMap.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/EntityClassMap.cs
@@ -9,7 +9,7 @@ using MongoDB.Bson.Serialization;
using Squidex.Domain.Apps.Core;
using Squidex.Infrastructure.Commands;
-namespace Squidex.Domain.Apps.Entities.MongoDb;
+namespace Squidex.Domain.Apps.Entities;
internal static class EntityClassMap
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/History/MongoHistoryEventRepository.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/History/MongoHistoryEventRepository.cs
similarity index 95%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/History/MongoHistoryEventRepository.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/History/MongoHistoryEventRepository.cs
index 3ee597545..1337a1904 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/History/MongoHistoryEventRepository.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/History/MongoHistoryEventRepository.cs
@@ -8,12 +8,10 @@
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
using Squidex.Domain.Apps.Core.Apps;
-using Squidex.Domain.Apps.Entities.History;
using Squidex.Domain.Apps.Entities.History.Repositories;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
-namespace Squidex.Domain.Apps.Entities.MongoDb.History;
+namespace Squidex.Domain.Apps.Entities.History;
public sealed class MongoHistoryEventRepository(IMongoDatabase database) : MongoRepositoryBase(database), IHistoryEventRepository, IDeleter
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEntity.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Rules/MongoRuleEntity.cs
similarity index 94%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEntity.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Rules/MongoRuleEntity.cs
index ebd684e3a..2a2770f73 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEntity.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Rules/MongoRuleEntity.cs
@@ -10,7 +10,7 @@ using Squidex.Domain.Apps.Core.Rules;
using Squidex.Infrastructure;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Rules;
+namespace Squidex.Domain.Apps.Entities.Rules;
public sealed class MongoRuleEntity : MongoState
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventEntity.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Rules/MongoRuleEventEntity.cs
similarity index 94%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventEntity.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Rules/MongoRuleEventEntity.cs
index 5fcff46fc..6f060354e 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventEntity.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Rules/MongoRuleEventEntity.cs
@@ -10,13 +10,11 @@ using MongoDB.Bson.Serialization.Attributes;
using NodaTime;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules;
-using Squidex.Domain.Apps.Entities.Rules;
using Squidex.Domain.Apps.Entities.Rules.Repositories;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.Reflection;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Rules;
+namespace Squidex.Domain.Apps.Entities.Rules;
public sealed class MongoRuleEventEntity : IRuleEventEntity
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventRepository.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Rules/MongoRuleEventRepository.cs
similarity index 97%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventRepository.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Rules/MongoRuleEventRepository.cs
index 7140d8b4e..73a7e73ce 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventRepository.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Rules/MongoRuleEventRepository.cs
@@ -9,12 +9,10 @@ using MongoDB.Driver;
using NodaTime;
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Rules;
-using Squidex.Domain.Apps.Entities.Rules;
using Squidex.Domain.Apps.Entities.Rules.Repositories;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Rules;
+namespace Squidex.Domain.Apps.Entities.Rules;
public sealed class MongoRuleEventRepository(IMongoDatabase database) : MongoRepositoryBase(database), IRuleEventRepository, IDeleter
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleRepository.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Rules/MongoRuleRepository.cs
similarity index 97%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleRepository.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Rules/MongoRuleRepository.cs
index 3d01cc4df..ab232a3be 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleRepository.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Rules/MongoRuleRepository.cs
@@ -12,7 +12,7 @@ using Squidex.Domain.Apps.Entities.Rules.Repositories;
using Squidex.Infrastructure;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Rules;
+namespace Squidex.Domain.Apps.Entities.Rules;
public sealed class MongoRuleRepository(IMongoDatabase database) : MongoSnapshotStoreBase(database), IRuleRepository, IDeleter
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaEntity.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Schemas/MongoSchemaEntity.cs
similarity index 95%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaEntity.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Schemas/MongoSchemaEntity.cs
index 51aaaf448..3471d980d 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaEntity.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Schemas/MongoSchemaEntity.cs
@@ -11,7 +11,7 @@ using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Schemas;
+namespace Squidex.Domain.Apps.Entities.Schemas;
public sealed class MongoSchemaEntity : MongoState
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaRepository.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Schemas/MongoSchemaRepository.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaRepository.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Schemas/MongoSchemaRepository.cs
index e842caa59..f6249bc92 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaRepository.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Schemas/MongoSchemaRepository.cs
@@ -12,7 +12,7 @@ using Squidex.Domain.Apps.Entities.Schemas.Repositories;
using Squidex.Infrastructure;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Schemas;
+namespace Squidex.Domain.Apps.Entities.Schemas;
public sealed class MongoSchemaRepository(IMongoDatabase database) : MongoSnapshotStoreBase(database), ISchemaRepository, IDeleter
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemasHash.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Schemas/MongoSchemasHash.cs
similarity index 96%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemasHash.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Schemas/MongoSchemasHash.cs
index b6a052c94..9f33e8911 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemasHash.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Schemas/MongoSchemasHash.cs
@@ -9,14 +9,13 @@ using MongoDB.Driver;
using NodaTime;
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Schemas;
-using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Domain.Apps.Events;
+using Squidex.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
-using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.ObjectPool;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Schemas;
+namespace Squidex.Domain.Apps.Entities.Schemas;
public sealed class MongoSchemasHash(IMongoDatabase database) : MongoRepositoryBase(database), ISchemasHash, IEventConsumer, IDeleter
{
@@ -55,7 +54,7 @@ public sealed class MongoSchemasHash(IMongoDatabase database) : MongoRepositoryB
Filter.Eq(x => x.AppId, schemaEvent.AppId.Id),
Update
.Set($"s.{schemaEvent.SchemaId.Id}", @event.Headers.EventStreamNumber())
- .Set(x => x.Updated, @event.Headers.Timestamp()))
+ .Set(x => x.Updated, @event.Headers.TimestampAsInstant()))
{
IsUpsert = true
});
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemasHashEntity.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Schemas/MongoSchemasHashEntity.cs
similarity index 93%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemasHashEntity.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Schemas/MongoSchemasHashEntity.cs
index 4a48735e8..9de3410a7 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemasHashEntity.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Schemas/MongoSchemasHashEntity.cs
@@ -9,7 +9,7 @@ using MongoDB.Bson.Serialization.Attributes;
using NodaTime;
using Squidex.Infrastructure;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Schemas;
+namespace Squidex.Domain.Apps.Entities.Schemas;
public sealed class MongoSchemasHashEntity
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/ShardedSnapshotStore.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/ShardedSnapshotStore.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/ShardedSnapshotStore.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/ShardedSnapshotStore.cs
index a08859f93..d7d6f8988 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/ShardedSnapshotStore.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/ShardedSnapshotStore.cs
@@ -10,7 +10,7 @@ using Squidex.Domain.Apps.Core.Apps;
using Squidex.Infrastructure;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb;
+namespace Squidex.Domain.Apps.Entities;
public abstract class ShardedSnapshotStore(IShardingStrategy sharding, Func factory, Func getShardKey) : ShardedService(sharding, factory), ISnapshotStore, IDeleter where TStore : ISnapshotStore, IDeleter
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Teams/MongoTeamEntity.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Teams/MongoTeamEntity.cs
similarity index 96%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Teams/MongoTeamEntity.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Teams/MongoTeamEntity.cs
index 92b5c875a..fbfe66fe4 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Teams/MongoTeamEntity.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Teams/MongoTeamEntity.cs
@@ -11,7 +11,7 @@ using Squidex.Domain.Apps.Core.Teams;
using Squidex.Infrastructure;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Teams;
+namespace Squidex.Domain.Apps.Entities.Teams;
public sealed class MongoTeamEntity : MongoState
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Teams/MongoTeamRepository.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Teams/MongoTeamRepository.cs
similarity index 97%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Teams/MongoTeamRepository.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Teams/MongoTeamRepository.cs
index bd20877f1..179222d19 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Teams/MongoTeamRepository.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Teams/MongoTeamRepository.cs
@@ -11,7 +11,7 @@ using Squidex.Domain.Apps.Entities.Teams.Repositories;
using Squidex.Infrastructure;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Teams;
+namespace Squidex.Domain.Apps.Entities.Teams;
public sealed class MongoTeamRepository(IMongoDatabase database) : MongoSnapshotStoreBase(database), ITeamRepository
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/AtlasIndexDefinition.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/AtlasIndexDefinition.cs
similarity index 99%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/AtlasIndexDefinition.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/AtlasIndexDefinition.cs
index eea6ad274..e24a2dfa7 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/AtlasIndexDefinition.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/AtlasIndexDefinition.cs
@@ -8,7 +8,7 @@
using System.Net.Http.Json;
using Squidex.Hosting.Configuration;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Text;
+namespace Squidex.Domain.Apps.Entities.Text;
public static class AtlasIndexDefinition
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/AtlasOptions.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/AtlasOptions.cs
similarity index 94%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/AtlasOptions.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/AtlasOptions.cs
index 2e3b9ca21..ce963a721 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/AtlasOptions.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/AtlasOptions.cs
@@ -5,7 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
-namespace Squidex.Domain.Apps.Entities.MongoDb.Text;
+namespace Squidex.Domain.Apps.Entities.Text;
public sealed class AtlasOptions
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/AtlasTextIndex.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/AtlasTextIndex.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/AtlasTextIndex.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/AtlasTextIndex.cs
index 08a6c9af1..24beace92 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/AtlasTextIndex.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/AtlasTextIndex.cs
@@ -17,7 +17,7 @@ using Squidex.Domain.Apps.Entities.Contents.Text;
using Squidex.Infrastructure;
using LuceneQueryAnalyzer = Lucene.Net.QueryParsers.Classic.QueryParser;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Text;
+namespace Squidex.Domain.Apps.Entities.Text;
public sealed class AtlasTextIndex(IMongoDatabase database, IHttpClientFactory atlasClient, IOptions atlasOptions, string shardKey) : MongoTextIndexBase>(database, shardKey, new CommandFactory>(BuildTexts))
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/CommandFactory.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/CommandFactory.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/CommandFactory.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/CommandFactory.cs
index 953402372..9bf94b89e 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/CommandFactory.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/CommandFactory.cs
@@ -8,9 +8,9 @@
using MongoDB.Bson;
using MongoDB.Driver;
using Squidex.Domain.Apps.Entities.Contents.Text;
-using Squidex.Infrastructure.MongoDb;
+using Squidex.Infrastructure;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Text;
+namespace Squidex.Domain.Apps.Entities.Text;
public sealed class CommandFactory(Func, T> textBuilder) : MongoBase> where T : class
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/LuceneQueryVisitor.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/LuceneQueryVisitor.cs
similarity index 99%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/LuceneQueryVisitor.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/LuceneQueryVisitor.cs
index dae951b17..d28c879f4 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/LuceneQueryVisitor.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/LuceneQueryVisitor.cs
@@ -13,7 +13,7 @@ using Lucene.Net.Util;
using MongoDB.Bson;
using Squidex.Infrastructure;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Text;
+namespace Squidex.Domain.Apps.Entities.Text;
public sealed class LuceneQueryVisitor(Func? fieldConverter = null)
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/LuceneSearchDefinitionExtensions.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/LuceneSearchDefinitionExtensions.cs
similarity index 96%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/LuceneSearchDefinitionExtensions.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/LuceneSearchDefinitionExtensions.cs
index c5dc8293a..6888a1bdc 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/LuceneSearchDefinitionExtensions.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/LuceneSearchDefinitionExtensions.cs
@@ -9,7 +9,7 @@ using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Text;
+namespace Squidex.Domain.Apps.Entities.Text;
public static class LuceneSearchDefinitionExtensions
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoShardedTextIndex.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoShardedTextIndex.cs
similarity index 97%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoShardedTextIndex.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoShardedTextIndex.cs
index 330aae00e..268a52278 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoShardedTextIndex.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoShardedTextIndex.cs
@@ -12,7 +12,7 @@ using Squidex.Domain.Apps.Entities.Contents.Text;
using Squidex.Infrastructure;
using Squidex.Infrastructure.States;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Text;
+namespace Squidex.Domain.Apps.Entities.Text;
public sealed class MongoShardedTextIndex(IShardingStrategy sharding, Func> factory) : ShardedService>(sharding, factory), ITextIndex, IDeleter where T : class
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndex.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndex.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndex.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndex.cs
index 75044b7df..d45889d24 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndex.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndex.cs
@@ -11,7 +11,7 @@ using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Domain.Apps.Entities.Contents.Text;
using Squidex.Infrastructure;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Text;
+namespace Squidex.Domain.Apps.Entities.Text;
public sealed class MongoTextIndex(IMongoDatabase database, string shardKey) : MongoTextIndexBase>(database, shardKey, new CommandFactory>(BuildTexts))
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndexBase.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndexBase.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndexBase.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndexBase.cs
index 7ac90caca..9c50d92c7 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndexBase.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndexBase.cs
@@ -13,9 +13,8 @@ using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Domain.Apps.Entities.Contents.Text;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Text;
+namespace Squidex.Domain.Apps.Entities.Text;
public abstract class MongoTextIndexBase(IMongoDatabase database, string shardKey, CommandFactory factory) : MongoRepositoryBase>(database), ITextIndex, IDeleter where T : class
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndexEntity.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndexEntity.cs
similarity index 94%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndexEntity.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndexEntity.cs
index 526694bfb..28cad20bc 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndexEntity.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndexEntity.cs
@@ -9,9 +9,8 @@ using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using NetTopologySuite.Geometries;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Text;
+namespace Squidex.Domain.Apps.Entities.Text;
public sealed class MongoTextIndexEntity
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndexEntityText.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndexEntityText.cs
similarity index 93%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndexEntityText.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndexEntityText.cs
index e881f2fcd..75261481f 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndexEntityText.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndexEntityText.cs
@@ -7,7 +7,7 @@
using MongoDB.Bson.Serialization.Attributes;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Text;
+namespace Squidex.Domain.Apps.Entities.Text;
public sealed class MongoTextIndexEntityText
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndexerState.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndexerState.cs
similarity index 97%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndexerState.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndexerState.cs
index bfc93ae81..a1f1bc238 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/MongoTextIndexerState.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/MongoTextIndexerState.cs
@@ -13,10 +13,10 @@ using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Domain.Apps.Entities.Contents.Repositories;
using Squidex.Domain.Apps.Entities.Contents.Text;
using Squidex.Domain.Apps.Entities.Contents.Text.State;
+using Squidex.Domain.Apps.Entities.MongoDb;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.MongoDb;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Text;
+namespace Squidex.Domain.Apps.Entities.Text;
public sealed class MongoTextIndexerState(
IMongoDatabase database,
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/Tokenizer.cs b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/Tokenizer.cs
similarity index 98%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/Tokenizer.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/Tokenizer.cs
index 3eaeb61e6..8b3138bf5 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Text/Tokenizer.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Apps/Entities/Text/Tokenizer.cs
@@ -16,7 +16,7 @@ using Squidex.Domain.Apps.Core;
using Squidex.Infrastructure;
using Squidex.Infrastructure.ObjectPool;
-namespace Squidex.Domain.Apps.Entities.MongoDb.Text;
+namespace Squidex.Domain.Apps.Entities.Text;
public static class Tokenizer
{
diff --git a/backend/src/Squidex.Domain.Users.MongoDb/MongoRoleStore.cs b/backend/src/Squidex.Data.MongoDb/Domain/Users/MongoRoleStore.cs
similarity index 99%
rename from backend/src/Squidex.Domain.Users.MongoDb/MongoRoleStore.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Users/MongoRoleStore.cs
index b3aaa5333..512b25d0e 100644
--- a/backend/src/Squidex.Domain.Users.MongoDb/MongoRoleStore.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Users/MongoRoleStore.cs
@@ -10,7 +10,7 @@ using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver;
-using Squidex.Infrastructure.MongoDb;
+using Squidex.Infrastructure;
namespace Squidex.Domain.Users.MongoDb;
diff --git a/backend/src/Squidex.Domain.Users.MongoDb/MongoUser.cs b/backend/src/Squidex.Data.MongoDb/Domain/Users/MongoUser.cs
similarity index 100%
rename from backend/src/Squidex.Domain.Users.MongoDb/MongoUser.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Users/MongoUser.cs
diff --git a/backend/src/Squidex.Domain.Users.MongoDb/MongoUserStore.cs b/backend/src/Squidex.Data.MongoDb/Domain/Users/MongoUserStore.cs
similarity index 99%
rename from backend/src/Squidex.Domain.Users.MongoDb/MongoUserStore.cs
rename to backend/src/Squidex.Data.MongoDb/Domain/Users/MongoUserStore.cs
index 80b514da6..86d7d9308 100644
--- a/backend/src/Squidex.Domain.Users.MongoDb/MongoUserStore.cs
+++ b/backend/src/Squidex.Data.MongoDb/Domain/Users/MongoUserStore.cs
@@ -11,7 +11,7 @@ using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver;
-using Squidex.Infrastructure.MongoDb;
+using Squidex.Infrastructure;
namespace Squidex.Domain.Users.MongoDb;
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Batching.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Batching.cs
similarity index 93%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Batching.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Batching.cs
index 1be716fea..186e699ad 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Batching.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/Batching.cs
@@ -7,7 +7,7 @@
using MongoDB.Driver;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public static class Batching
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonDefaultConventions.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonDefaultConventions.cs
similarity index 96%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonDefaultConventions.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/BsonDefaultConventions.cs
index 4ee7c52d2..f3a3bcfcf 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonDefaultConventions.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonDefaultConventions.cs
@@ -10,7 +10,7 @@ using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Bson.Serialization.Serializers;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public static class BsonDefaultConventions
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonDomainIdSerializer.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonDomainIdSerializer.cs
similarity index 98%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonDomainIdSerializer.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/BsonDomainIdSerializer.cs
index fc960b94e..63892db39 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonDomainIdSerializer.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonDomainIdSerializer.cs
@@ -10,7 +10,7 @@ using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public sealed class BsonDomainIdSerializer : SerializerBase, IBsonPolymorphicSerializer, IRepresentationConfigurable
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonEscapedDictionarySerializer.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonEscapedDictionarySerializer.cs
similarity index 97%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonEscapedDictionarySerializer.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/BsonEscapedDictionarySerializer.cs
index e234c4daf..ef83ce1be 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonEscapedDictionarySerializer.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonEscapedDictionarySerializer.cs
@@ -10,7 +10,7 @@ using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public sealed class BsonEscapedDictionarySerializer : ClassSerializerBase where TInstance : Dictionary, new()
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonHelper.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonHelper.cs
similarity index 97%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonHelper.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/BsonHelper.cs
index 07975565c..ad85f8a83 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonHelper.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonHelper.cs
@@ -5,7 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public static class BsonHelper
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonInstantSerializer.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonInstantSerializer.cs
similarity index 98%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonInstantSerializer.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/BsonInstantSerializer.cs
index 171aa0bac..c3a443f1c 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonInstantSerializer.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonInstantSerializer.cs
@@ -11,7 +11,7 @@ using MongoDB.Bson.Serialization.Serializers;
using NodaTime;
using NodaTime.Text;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public sealed class BsonInstantSerializer : SerializerBase, IBsonPolymorphicSerializer, IRepresentationConfigurable
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonAttribute.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonJsonAttribute.cs
similarity index 91%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonAttribute.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/BsonJsonAttribute.cs
index 49c2bd8fe..695cce015 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonAttribute.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonJsonAttribute.cs
@@ -5,7 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
[AttributeUsage(AttributeTargets.Property)]
public sealed class BsonJsonAttribute : Attribute
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonConvention.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonJsonConvention.cs
similarity index 97%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonConvention.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/BsonJsonConvention.cs
index 155f8845c..df8ff65b1 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonConvention.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonJsonConvention.cs
@@ -11,7 +11,7 @@ using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Conventions;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public static class BsonJsonConvention
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonSerializer.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonJsonSerializer.cs
similarity index 99%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonSerializer.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/BsonJsonSerializer.cs
index f6e713500..8176ecb41 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonSerializer.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonJsonSerializer.cs
@@ -13,7 +13,7 @@ using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
using Squidex.Infrastructure.ObjectPool;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public sealed class BsonJsonSerializer : SerializerBase, IRepresentationConfigurable> where T : class
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonValueSerializer.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonJsonValueSerializer.cs
similarity index 98%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonValueSerializer.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/BsonJsonValueSerializer.cs
index 8cecf16fc..bc8d8645a 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonValueSerializer.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonJsonValueSerializer.cs
@@ -10,7 +10,7 @@ using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
using Squidex.Infrastructure.Json.Objects;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public sealed class BsonJsonValueSerializer : SerializerBase
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonStringSerializer.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonStringSerializer.cs
similarity index 97%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonStringSerializer.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/BsonStringSerializer.cs
index 9648033fc..65850089b 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonStringSerializer.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/BsonStringSerializer.cs
@@ -10,7 +10,7 @@ using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public sealed class BsonStringSerializer : SerializerBase
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/Caching/MongoCacheEntry.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Caching/MongoCacheEntry.cs
similarity index 100%
rename from backend/src/Squidex.Infrastructure.MongoDb/Caching/MongoCacheEntry.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Caching/MongoCacheEntry.cs
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/Caching/MongoDistributedCache.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Caching/MongoDistributedCache.cs
similarity index 98%
rename from backend/src/Squidex.Infrastructure.MongoDb/Caching/MongoDistributedCache.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Caching/MongoDistributedCache.cs
index 4000675da..165628693 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/Caching/MongoDistributedCache.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/Caching/MongoDistributedCache.cs
@@ -7,7 +7,6 @@
using Microsoft.Extensions.Caching.Distributed;
using MongoDB.Driver;
-using Squidex.Infrastructure.MongoDb;
namespace Squidex.Infrastructure.Caching;
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/MongoCountCollection.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Counts/MongoCountCollection.cs
similarity index 97%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/MongoCountCollection.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Counts/MongoCountCollection.cs
index 70d96f1fd..ff0ab65ca 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/MongoCountCollection.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/Counts/MongoCountCollection.cs
@@ -8,10 +8,9 @@
using Microsoft.Extensions.Logging;
using MongoDB.Driver;
using NodaTime;
-using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.Tasks;
-namespace Squidex.Domain.Apps.Entities.MongoDb;
+namespace Squidex.Infrastructure.Counts;
internal sealed class MongoCountCollection(IMongoDatabase database, ILogger log, string name) : MongoRepositoryBase(database)
{
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/MongoCountEntity.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Counts/MongoCountEntity.cs
similarity index 93%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/MongoCountEntity.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Counts/MongoCountEntity.cs
index ff9cf2b5a..8c2addc18 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/MongoCountEntity.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/Counts/MongoCountEntity.cs
@@ -8,7 +8,7 @@
using MongoDB.Bson.Serialization.Attributes;
using NodaTime;
-namespace Squidex.Domain.Apps.Entities.MongoDb;
+namespace Squidex.Infrastructure.Counts;
internal sealed class MongoCountEntity
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/Diagnostics/MongoHealthCheck.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Diagnostics/MongoHealthCheck.cs
similarity index 100%
rename from backend/src/Squidex.Infrastructure.MongoDb/Diagnostics/MongoHealthCheck.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Diagnostics/MongoHealthCheck.cs
diff --git a/backend/src/Squidex.Data.MongoDb/Infrastructure/Diagnostics/ProfilerCollection.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Diagnostics/ProfilerCollection.cs
new file mode 100644
index 000000000..1d183f502
--- /dev/null
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/Diagnostics/ProfilerCollection.cs
@@ -0,0 +1,34 @@
+// ==========================================================================
+// Squidex Headless CMS
+// ==========================================================================
+// Copyright (c) Squidex UG (haftungsbeschraenkt)
+// All rights reserved. Licensed under the MIT license.
+// ==========================================================================
+
+using MongoDB.Bson;
+using MongoDB.Driver;
+
+#pragma warning disable CA1822 // Mark members as static
+
+namespace Squidex.Infrastructure.Diagnostics;
+
+public sealed class ProfilerCollection(IMongoDatabase database)
+{
+ private readonly IMongoCollection collection = database.GetCollection("system.profile");
+
+ public async Task> GetQueriesAsync(string collectionName,
+ CancellationToken ct = default)
+ {
+ var ns = $"{collection.Database.DatabaseNamespace.DatabaseName}.{collectionName}";
+
+ return await collection.Find(x => x.Operation == "query" && x.Namespace == ns).ToListAsync(ct);
+ }
+
+ public async Task ClearAsync(
+ CancellationToken ct = default)
+ {
+ await database.RunCommandAsync("{ profile : 0 }", cancellationToken: ct);
+ await database.DropCollectionAsync(ProfilerDocument.CollectionName, ct);
+ await database.RunCommandAsync("{ profile : 2 }", cancellationToken: ct);
+ }
+}
diff --git a/backend/src/Squidex.Data.MongoDb/Infrastructure/Diagnostics/ProfilerDocument.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Diagnostics/ProfilerDocument.cs
new file mode 100644
index 000000000..1f1407774
--- /dev/null
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/Diagnostics/ProfilerDocument.cs
@@ -0,0 +1,35 @@
+// ==========================================================================
+// Squidex Headless CMS
+// ==========================================================================
+// Copyright (c) Squidex UG (haftungsbeschraenkt)
+// All rights reserved. Licensed under the MIT license.
+// ==========================================================================
+
+using MongoDB.Bson;
+using MongoDB.Bson.Serialization.Attributes;
+
+namespace Squidex.Infrastructure.Diagnostics;
+
+[BsonIgnoreExtraElements]
+public sealed class ProfilerDocument
+{
+ public const string CollectionName = "system.profile";
+
+ [BsonElement("op")]
+ public string Operation { get; set; }
+
+ [BsonElement("ns")]
+ public string Namespace { get; set; }
+
+ [BsonElement("nreturned")]
+ public int NumDocuments { get; set; }
+
+ [BsonElement("keysExamined")]
+ public int KeysExamined { get; set; }
+
+ [BsonElement("docsExamined")]
+ public int DocsExamined { get; set; }
+
+ [BsonElement("planSummary")]
+ public string PlanSummary { get; set; }
+}
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Field.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Field.cs
similarity index 96%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Field.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Field.cs
index 2e1160139..c8bc22f8e 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Field.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/Field.cs
@@ -7,7 +7,7 @@
using MongoDB.Bson.Serialization;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public static class Field
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/IVersionedEntity.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/IVersionedEntity.cs
similarity index 91%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/IVersionedEntity.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/IVersionedEntity.cs
index 067c06a1e..a5f98e990 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/IVersionedEntity.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/IVersionedEntity.cs
@@ -5,7 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public interface IVersionedEntity
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/Log/MongoRequest.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Log/MongoRequest.cs
similarity index 100%
rename from backend/src/Squidex.Infrastructure.MongoDb/Log/MongoRequest.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Log/MongoRequest.cs
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/Log/MongoRequestLogRepository.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Log/MongoRequestLogRepository.cs
similarity index 98%
rename from backend/src/Squidex.Infrastructure.MongoDb/Log/MongoRequestLogRepository.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Log/MongoRequestLogRepository.cs
index 5e86d805e..837bbc89d 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/Log/MongoRequestLogRepository.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/Log/MongoRequestLogRepository.cs
@@ -8,7 +8,6 @@
using Microsoft.Extensions.Options;
using MongoDB.Driver;
using NodaTime;
-using Squidex.Infrastructure.MongoDb;
namespace Squidex.Infrastructure.Log;
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/Migrations/MongoMigrationEntity.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Migrations/MongoMigrationEntity.cs
similarity index 100%
rename from backend/src/Squidex.Infrastructure.MongoDb/Migrations/MongoMigrationEntity.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Migrations/MongoMigrationEntity.cs
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/Migrations/MongoMigrationStatus.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Migrations/MongoMigrationStatus.cs
similarity index 98%
rename from backend/src/Squidex.Infrastructure.MongoDb/Migrations/MongoMigrationStatus.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Migrations/MongoMigrationStatus.cs
index e6bbb2919..371d00b26 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/Migrations/MongoMigrationStatus.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/Migrations/MongoMigrationStatus.cs
@@ -6,7 +6,6 @@
// ==========================================================================
using MongoDB.Driver;
-using Squidex.Infrastructure.MongoDb;
namespace Squidex.Infrastructure.Migrations;
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoBase.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/MongoBase.cs
similarity index 97%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoBase.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/MongoBase.cs
index ca67643b2..644dc8ebe 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoBase.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/MongoBase.cs
@@ -10,7 +10,7 @@ using MongoDB.Driver;
#pragma warning disable RECS0108 // Warns about static fields in generic types
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public abstract class MongoBase
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoClientFactory.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/MongoClientFactory.cs
similarity index 97%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoClientFactory.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/MongoClientFactory.cs
index 2f96f8e5f..d3ddc1817 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoClientFactory.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/MongoClientFactory.cs
@@ -9,7 +9,7 @@ using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Squidex.Infrastructure.Json.Objects;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public static class MongoClientFactory
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoDbErrorCodes.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/MongoDbErrorCodes.cs
similarity index 92%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoDbErrorCodes.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/MongoDbErrorCodes.cs
index b974f2b25..8fb8cb4dd 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoDbErrorCodes.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/MongoDbErrorCodes.cs
@@ -7,7 +7,7 @@
#pragma warning disable SA1310 // Field names should not contain underscore
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public static class MongoDbErrorCodes
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoExtensions.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/MongoExtensions.cs
similarity index 99%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoExtensions.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/MongoExtensions.cs
index 0b964fc96..7ff2a0637 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoExtensions.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/MongoExtensions.cs
@@ -10,9 +10,10 @@ using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using MongoDB.Bson;
using MongoDB.Driver;
+using Squidex.Infrastructure;
using Squidex.Infrastructure.States;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public static class MongoExtensions
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoRepositoryBase.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/MongoRepositoryBase.cs
similarity index 98%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoRepositoryBase.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/MongoRepositoryBase.cs
index 238344761..a47fe12e9 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoRepositoryBase.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/MongoRepositoryBase.cs
@@ -10,7 +10,7 @@ using MongoDB.Driver;
using Squidex.Hosting;
using Squidex.Hosting.Configuration;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public abstract class MongoRepositoryBase : MongoBase, IInitializable
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/ProfilerCollection.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/ProfilerCollection.cs
similarity index 97%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/ProfilerCollection.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/ProfilerCollection.cs
index 839740dbc..80b413df8 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/ProfilerCollection.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/ProfilerCollection.cs
@@ -10,7 +10,7 @@ using MongoDB.Driver;
#pragma warning disable CA1822 // Mark members as static
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
public sealed class ProfilerCollection(IMongoDatabase database)
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/ProfilerDocument.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/ProfilerDocument.cs
similarity index 95%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/ProfilerDocument.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/ProfilerDocument.cs
index 2f8afb8f0..b3caa73e5 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/ProfilerDocument.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/ProfilerDocument.cs
@@ -8,7 +8,7 @@
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
-namespace Squidex.Infrastructure.MongoDb;
+namespace Squidex.Infrastructure;
[BsonIgnoreExtraElements]
public sealed class ProfilerDocument
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/FilterBuilder.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Queries/FilterBuilder.cs
similarity index 93%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/FilterBuilder.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Queries/FilterBuilder.cs
index eae715222..883d7692b 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/FilterBuilder.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/Queries/FilterBuilder.cs
@@ -6,10 +6,9 @@
// ==========================================================================
using MongoDB.Driver;
-using Squidex.Infrastructure.Queries;
using Squidex.Infrastructure.Validation;
-namespace Squidex.Infrastructure.MongoDb.Queries;
+namespace Squidex.Infrastructure.Queries;
public static class FilterBuilder
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/FilterVisitor.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Queries/FilterVisitor.cs
similarity index 98%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/FilterVisitor.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Queries/FilterVisitor.cs
index 33425c789..acd91df6d 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/FilterVisitor.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/Queries/FilterVisitor.cs
@@ -9,9 +9,8 @@ using System.Collections;
using System.Text.RegularExpressions;
using MongoDB.Bson;
using MongoDB.Driver;
-using Squidex.Infrastructure.Queries;
-namespace Squidex.Infrastructure.MongoDb.Queries;
+namespace Squidex.Infrastructure.Queries;
public sealed class FilterVisitor : FilterNodeVisitor, ClrValue, None>
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/LimitExtensions.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Queries/LimitExtensions.cs
similarity index 95%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/LimitExtensions.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Queries/LimitExtensions.cs
index c6fea157a..becc31bd1 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/LimitExtensions.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/Queries/LimitExtensions.cs
@@ -6,9 +6,8 @@
// ==========================================================================
using MongoDB.Driver;
-using Squidex.Infrastructure.Queries;
-namespace Squidex.Infrastructure.MongoDb.Queries;
+namespace Squidex.Infrastructure.Queries;
public static class LimitExtensions
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/SortBuilder.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/Queries/SortDefinitionBuilder.cs
similarity index 90%
rename from backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/SortBuilder.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/Queries/SortDefinitionBuilder.cs
index dd230bdef..1f52261aa 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/SortBuilder.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/Queries/SortDefinitionBuilder.cs
@@ -6,11 +6,10 @@
// ==========================================================================
using MongoDB.Driver;
-using Squidex.Infrastructure.Queries;
-namespace Squidex.Infrastructure.MongoDb.Queries;
+namespace Squidex.Infrastructure.Queries;
-public static class SortBuilder
+public static class SortDefinitionBuilder
{
public static SortDefinition? BuildSort(this ClrQuery query)
{
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/States/MongoSnapshotStore.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/States/MongoSnapshotStore.cs
similarity index 100%
rename from backend/src/Squidex.Infrastructure.MongoDb/States/MongoSnapshotStore.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/States/MongoSnapshotStore.cs
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/States/MongoSnapshotStoreBase.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/States/MongoSnapshotStoreBase.cs
similarity index 99%
rename from backend/src/Squidex.Infrastructure.MongoDb/States/MongoSnapshotStoreBase.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/States/MongoSnapshotStoreBase.cs
index c8e686ed3..773ed06ef 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/States/MongoSnapshotStoreBase.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/States/MongoSnapshotStoreBase.cs
@@ -7,7 +7,6 @@
using System.Runtime.CompilerServices;
using MongoDB.Driver;
-using Squidex.Infrastructure.MongoDb;
namespace Squidex.Infrastructure.States;
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/States/MongoState.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/States/MongoState.cs
similarity index 95%
rename from backend/src/Squidex.Infrastructure.MongoDb/States/MongoState.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/States/MongoState.cs
index 9607192e9..19ff1f14f 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/States/MongoState.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/States/MongoState.cs
@@ -7,7 +7,6 @@
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
-using Squidex.Infrastructure.MongoDb;
namespace Squidex.Infrastructure.States;
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/UsageTracking/MongoUsage.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/UsageTracking/MongoUsage.cs
similarity index 100%
rename from backend/src/Squidex.Infrastructure.MongoDb/UsageTracking/MongoUsage.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/UsageTracking/MongoUsage.cs
diff --git a/backend/src/Squidex.Infrastructure.MongoDb/UsageTracking/MongoUsageRepository.cs b/backend/src/Squidex.Data.MongoDb/Infrastructure/UsageTracking/MongoUsageRepository.cs
similarity index 99%
rename from backend/src/Squidex.Infrastructure.MongoDb/UsageTracking/MongoUsageRepository.cs
rename to backend/src/Squidex.Data.MongoDb/Infrastructure/UsageTracking/MongoUsageRepository.cs
index cfdac6b28..6437d60fd 100644
--- a/backend/src/Squidex.Infrastructure.MongoDb/UsageTracking/MongoUsageRepository.cs
+++ b/backend/src/Squidex.Data.MongoDb/Infrastructure/UsageTracking/MongoUsageRepository.cs
@@ -7,7 +7,6 @@
using MongoDB.Bson;
using MongoDB.Driver;
-using Squidex.Infrastructure.MongoDb;
namespace Squidex.Infrastructure.UsageTracking;
diff --git a/backend/src/Squidex.Data.MongoDb/Migrations/AddAppIdToEventStream.cs b/backend/src/Squidex.Data.MongoDb/Migrations/AddAppIdToEventStream.cs
new file mode 100644
index 000000000..054f6bde5
--- /dev/null
+++ b/backend/src/Squidex.Data.MongoDb/Migrations/AddAppIdToEventStream.cs
@@ -0,0 +1,137 @@
+// ==========================================================================
+// Squidex Headless CMS
+// ==========================================================================
+// Copyright (c) Squidex UG (haftungsbeschraenkt)
+// All rights reserved. Licensed under the MIT license.
+// ==========================================================================
+
+using System.Diagnostics.CodeAnalysis;
+using MongoDB.Bson;
+using MongoDB.Driver;
+using Squidex.Infrastructure;
+using Squidex.Infrastructure.Migrations;
+using Squidex.Infrastructure.Tasks;
+
+namespace Squidex.Migrations.MongoDb;
+
+public sealed class AddAppIdToEventStream(IMongoDatabase database) : MongoBase, IMigration
+{
+ public async Task UpdateAsync(
+ CancellationToken ct)
+ {
+ // Do not resolve in constructor, because most of the time it is not executed anyway.
+ var collectionV1 = database.GetCollection("Events");
+ var collectionV2 = database.GetCollection("Events2");
+
+ // Run batch first, because it is cheaper as it has less items.
+ var batchedCommits = collectionV1.Find(FindAll).ToAsyncEnumerable(ct).Batch(500, ct).Buffered(2, ct);
+
+ var options = new ParallelOptions
+ {
+ CancellationToken = ct,
+ // The tasks are mostly executed on database level, therefore we increase parallelism.
+ MaxDegreeOfParallelism = Environment.ProcessorCount * 2,
+ };
+
+ await Parallel.ForEachAsync(batchedCommits, ct, async (batch, ct) =>
+ {
+ var writes = new List>();
+
+ foreach (var document in batch)
+ {
+ var eventStream = document["EventStream"].AsString;
+
+ if (TryGetAppId(document, out var appId))
+ {
+ if (!eventStream.StartsWith("app-", StringComparison.OrdinalIgnoreCase))
+ {
+ var indexOfType = eventStream.IndexOf('-', StringComparison.Ordinal);
+ var indexOfId = indexOfType + 1;
+
+ var indexOfOldId = eventStream.LastIndexOf("--", StringComparison.OrdinalIgnoreCase);
+
+ if (indexOfOldId > 0)
+ {
+ indexOfId = indexOfOldId + 2;
+ }
+
+ var domainType = eventStream[..indexOfType];
+ var domainId = eventStream[indexOfId..];
+
+ var newDomainId = DomainId.Combine(DomainId.Create(appId), DomainId.Create(domainId)).ToString();
+ var newStreamName = $"{domainType}-{newDomainId}";
+
+ document["EventStream"] = newStreamName;
+
+ foreach (var @event in document["Events"].AsBsonArray)
+ {
+ var metadata = @event["Metadata"].AsBsonDocument;
+
+ metadata["AggregateId"] = newDomainId;
+ }
+ }
+
+ foreach (var @event in document["Events"].AsBsonArray)
+ {
+ var metadata = @event["Metadata"].AsBsonDocument;
+
+ metadata.Remove("AppId");
+ }
+ }
+
+ var filter = Builders.Filter.Eq("_id", document["_id"].AsString);
+
+ writes.Add(new ReplaceOneModel(filter, document)
+ {
+ IsUpsert = true
+ });
+ }
+
+ if (writes.Count > 0)
+ {
+ await collectionV2.BulkWriteAsync(writes, BulkUnordered, ct);
+ }
+ });
+ }
+
+ private static bool TryGetAppId(BsonDocument document, [MaybeNullWhen(false)] out string appId)
+ {
+ const int guidLength = 36;
+
+ foreach (var @event in document["Events"].AsBsonArray)
+ {
+ var metadata = @event["Metadata"].AsBsonDocument;
+
+ if (metadata.TryGetValue("AppId", out var value))
+ {
+ appId = value.AsString;
+ return true;
+ }
+
+ if (metadata.TryGetValue("AggregateId", out var aggregateId))
+ {
+ var parts = aggregateId.AsString.Split("--");
+
+ if (parts.Length == 2)
+ {
+ appId = parts[0];
+ return true;
+ }
+ }
+
+ var payload = @event["Payload"].AsString;
+
+ var indexOfAppId = payload.IndexOf("appId\":\"", StringComparison.OrdinalIgnoreCase);
+
+ if (indexOfAppId > 0)
+ {
+ appId = payload.Substring(indexOfAppId, guidLength);
+ return true;
+ }
+ }
+
+ appId = null;
+
+ return false;
+ }
+}
diff --git a/backend/src/Squidex.Data.MongoDb/Migrations/ConvertDocumentIds.cs b/backend/src/Squidex.Data.MongoDb/Migrations/ConvertDocumentIds.cs
new file mode 100644
index 000000000..d9ebe2e0d
--- /dev/null
+++ b/backend/src/Squidex.Data.MongoDb/Migrations/ConvertDocumentIds.cs
@@ -0,0 +1,130 @@
+// ==========================================================================
+// Squidex Headless CMS
+// ==========================================================================
+// Copyright (c) Squidex UG (haftungsbeschraenkt)
+// All rights reserved. Licensed under the MIT license.
+// ==========================================================================
+
+using MongoDB.Bson;
+using MongoDB.Driver;
+using Squidex.Infrastructure;
+using Squidex.Infrastructure.Migrations;
+using Squidex.Infrastructure.Tasks;
+
+namespace Squidex.Migrations.MongoDb;
+
+public sealed class ConvertDocumentIds(IMongoDatabase databaseDefault, IMongoDatabase databaseContent) : MongoBase, IMigration
+{
+ private Scope scope;
+
+ private enum Scope
+ {
+ None,
+ Assets,
+ Contents
+ }
+
+ public override string ToString()
+ {
+ return $"{base.ToString()}({scope})";
+ }
+
+ public ConvertDocumentIds ForContents()
+ {
+ scope = Scope.Contents;
+
+ return this;
+ }
+
+ public ConvertDocumentIds ForAssets()
+ {
+ scope = Scope.Assets;
+
+ return this;
+ }
+
+ public async Task UpdateAsync(
+ CancellationToken ct)
+ {
+ switch (scope)
+ {
+ case Scope.Assets:
+ await RebuildAsync(databaseDefault, ConvertParentId, "States_Assets", ct);
+ await RebuildAsync(databaseDefault, ConvertParentId, "States_AssetFolders", ct);
+ break;
+ case Scope.Contents:
+ await RebuildAsync(databaseContent, null, "State_Contents_All", ct);
+ await RebuildAsync(databaseContent, null, "State_Contents_Published", ct);
+ break;
+ }
+ }
+
+ private static async Task RebuildAsync(IMongoDatabase database, Action? extraAction, string collectionNameV1,
+ CancellationToken ct)
+ {
+ string collectionNameV2;
+
+ collectionNameV2 = $"{collectionNameV1}2";
+ collectionNameV2 = collectionNameV2.Replace("State_", "States_", StringComparison.Ordinal);
+
+ // Do not resolve in constructor, because most of the time it is not executed anyway.
+ var collectionV1 = database.GetCollection(collectionNameV1);
+ var collectionV2 = database.GetCollection(collectionNameV2);
+
+ if (!await collectionV1.AnyAsync(ct: ct))
+ {
+ return;
+ }
+
+ await collectionV2.DeleteManyAsync(FindAll, ct);
+
+ // Run batch first, because it is cheaper as it has less items.
+ var batches = collectionV1.Find(FindAll).ToAsyncEnumerable(ct).Batch(500, ct).Buffered(2, ct);
+
+ await Parallel.ForEachAsync(batches, ct, async (batch, ct) =>
+ {
+ var writes = new List>();
+
+ foreach (var document in batch)
+ {
+ var appId = document["_ai"].AsString;
+
+ var documentIdOld = document["_id"].AsString;
+
+ if (documentIdOld.Contains("--", StringComparison.OrdinalIgnoreCase))
+ {
+ var index = documentIdOld.LastIndexOf("--", StringComparison.OrdinalIgnoreCase);
+
+ documentIdOld = documentIdOld[(index + 2)..];
+ }
+
+ var documentIdNew = DomainId.Combine(DomainId.Create(appId), DomainId.Create(documentIdOld)).ToString();
+
+ document["id"] = documentIdOld;
+ document["_id"] = documentIdNew;
+
+ extraAction?.Invoke(document);
+
+ var filter = Filter.Eq("_id", documentIdNew);
+
+ writes.Add(new ReplaceOneModel(filter, document)
+ {
+ IsUpsert = true
+ });
+ }
+
+ if (writes.Count > 0)
+ {
+ await collectionV2.BulkWriteAsync(writes, BulkUnordered, ct);
+ }
+ });
+ }
+
+ private static void ConvertParentId(BsonDocument document)
+ {
+ if (document.Contains("pi"))
+ {
+ document["pi"] = document["pi"].AsGuid.ToString();
+ }
+ }
+}
diff --git a/backend/src/Squidex.Data.MongoDb/Migrations/ConvertOldSnapshotStores.cs b/backend/src/Squidex.Data.MongoDb/Migrations/ConvertOldSnapshotStores.cs
new file mode 100644
index 000000000..a18d94bdf
--- /dev/null
+++ b/backend/src/Squidex.Data.MongoDb/Migrations/ConvertOldSnapshotStores.cs
@@ -0,0 +1,32 @@
+// ==========================================================================
+// Squidex Headless CMS
+// ==========================================================================
+// Copyright (c) Squidex UG (haftungsbeschraenkt)
+// All rights reserved. Licensed under the MIT license.
+// ==========================================================================
+
+using MongoDB.Bson;
+using MongoDB.Driver;
+using Squidex.Infrastructure;
+using Squidex.Infrastructure.Migrations;
+
+namespace Squidex.Migrations.MongoDb;
+
+public sealed class ConvertOldSnapshotStores(IMongoDatabase database) : MongoBase, IMigration
+{
+ public Task UpdateAsync(
+ CancellationToken ct)
+ {
+ // Do not resolve in constructor, because most of the time it is not executed anyway.
+ var collections = new[]
+ {
+ "States_Apps",
+ "States_Rules",
+ "States_Schemas"
+ }.Select(x => database.GetCollection(x));
+
+ var update = Update.Rename("State", "Doc");
+
+ return Task.WhenAll(collections.Select(x => x.UpdateManyAsync(FindAll, update, cancellationToken: ct)));
+ }
+}
diff --git a/backend/src/Squidex.Data.MongoDb/Migrations/ConvertRuleEventsJson.cs b/backend/src/Squidex.Data.MongoDb/Migrations/ConvertRuleEventsJson.cs
new file mode 100644
index 000000000..195d3a8b3
--- /dev/null
+++ b/backend/src/Squidex.Data.MongoDb/Migrations/ConvertRuleEventsJson.cs
@@ -0,0 +1,38 @@
+// ==========================================================================
+// Squidex Headless CMS
+// ==========================================================================
+// Copyright (c) Squidex UG (haftungsbeschraenkt)
+// All rights reserved. Licensed under the MIT license.
+// ==========================================================================
+
+using MongoDB.Bson;
+using MongoDB.Driver;
+using Squidex.Infrastructure;
+using Squidex.Infrastructure.Migrations;
+
+namespace Squidex.Migrations.MongoDb;
+
+public sealed class ConvertRuleEventsJson(IMongoDatabase database) : MongoBase, IMigration
+{
+ private readonly IMongoCollection collection = database.GetCollection("RuleEvents");
+
+ public async Task UpdateAsync(
+ CancellationToken ct)
+ {
+ foreach (var document in collection.Find(FindAll).ToEnumerable(ct))
+ {
+ try
+ {
+ document["Job"]["actionData"] = document["Job"]["actionData"].ToBsonDocument().ToJson();
+
+ var filter = Filter.Eq("_id", document["_id"].ToString());
+
+ await collection.ReplaceOneAsync(filter, document, cancellationToken: ct);
+ }
+ catch
+ {
+ continue;
+ }
+ }
+ }
+}
diff --git a/backend/src/Squidex.Data.MongoDb/Migrations/CopyRuleStatistics.cs b/backend/src/Squidex.Data.MongoDb/Migrations/CopyRuleStatistics.cs
new file mode 100644
index 000000000..a33e29728
--- /dev/null
+++ b/backend/src/Squidex.Data.MongoDb/Migrations/CopyRuleStatistics.cs
@@ -0,0 +1,56 @@
+// ==========================================================================
+// Squidex Headless CMS
+// ==========================================================================
+// Copyright (c) Squidex UG (haftungsbeschraenkt)
+// All rights reserved. Licensed under the MIT license.
+// ==========================================================================
+
+using MongoDB.Bson;
+using MongoDB.Bson.Serialization.Attributes;
+using MongoDB.Driver;
+using Squidex.Domain.Apps.Entities.Rules;
+using Squidex.Infrastructure;
+using Squidex.Infrastructure.Migrations;
+
+namespace Squidex.Migrations.MongoDb;
+
+public sealed class CopyRuleStatistics(IMongoDatabase database, IRuleUsageTracker ruleUsageTracker) : IMigration
+{
+ [BsonIgnoreExtraElements]
+ public class Document
+ {
+ public DomainId AppId { get; private set; }
+
+ public DomainId RuleId { get; private set; }
+
+ public int NumFailed { get; private set; }
+
+ public int NumSucceeded { get; private set; }
+ }
+
+ public async Task UpdateAsync(
+ CancellationToken ct)
+ {
+ var collectionName = "RuleStatistics";
+
+ // Do not create the collection if not needed.
+ if (!await database.CollectionExistsAsync(collectionName, ct))
+ {
+ return;
+ }
+
+ var collection = database.GetCollection(collectionName);
+
+ await foreach (var document in collection.Find(new BsonDocument()).ToAsyncEnumerable(ct))
+ {
+ await ruleUsageTracker.TrackAsync(
+ document.AppId,
+ document.RuleId,
+ default,
+ 0,
+ document.NumSucceeded,
+ document.NumFailed,
+ ct);
+ }
+ }
+}
diff --git a/backend/src/Squidex.Data.MongoDb/Migrations/DeleteContentCollections.cs b/backend/src/Squidex.Data.MongoDb/Migrations/DeleteContentCollections.cs
new file mode 100644
index 000000000..ccaedf40f
--- /dev/null
+++ b/backend/src/Squidex.Data.MongoDb/Migrations/DeleteContentCollections.cs
@@ -0,0 +1,23 @@
+// ==========================================================================
+// Squidex Headless CMS
+// ==========================================================================
+// Copyright (c) Squidex UG (haftungsbeschraenkt)
+// All rights reserved. Licensed under the MIT license.
+// ==========================================================================
+
+using MongoDB.Driver;
+using Squidex.Infrastructure.Migrations;
+
+namespace Squidex.Migrations.MongoDb;
+
+public sealed class DeleteContentCollections(IMongoDatabase database) : IMigration
+{
+ public async Task UpdateAsync(
+ CancellationToken ct)
+ {
+ await database.DropCollectionAsync("States_Contents", ct);
+ await database.DropCollectionAsync("States_Contents_Archive", ct);
+ await database.DropCollectionAsync("State_Content_Draft", ct);
+ await database.DropCollectionAsync("State_Content_Published", ct);
+ }
+}
diff --git a/backend/src/Squidex.Data.MongoDb/Migrations/RenameAssetMetadata.cs b/backend/src/Squidex.Data.MongoDb/Migrations/RenameAssetMetadata.cs
new file mode 100644
index 000000000..c8cb0e6a9
--- /dev/null
+++ b/backend/src/Squidex.Data.MongoDb/Migrations/RenameAssetMetadata.cs
@@ -0,0 +1,53 @@
+// ==========================================================================
+// Squidex Headless CMS
+// ==========================================================================
+// Copyright (c) Squidex UG (haftungsbeschraenkt)
+// All rights reserved. Licensed under the MIT license.
+// ==========================================================================
+
+using MongoDB.Bson;
+using MongoDB.Driver;
+using Squidex.Infrastructure;
+using Squidex.Infrastructure.Migrations;
+
+namespace Squidex.Migrations.MongoDb;
+
+public sealed class RenameAssetMetadata(IMongoDatabase database) : MongoBase, IMigration
+{
+ public async Task UpdateAsync(
+ CancellationToken ct)
+ {
+ // Do not resolve in constructor, because most of the time it is not executed anyway.
+ var collection = database.GetCollection("States_Assets");
+
+ // Create metadata.
+ await collection.UpdateManyAsync(FindAll,
+ Update.Set("md", new BsonDocument()),
+ cancellationToken: ct);
+
+ // Remove null pixel infos.
+ await collection.UpdateManyAsync(new BsonDocument("ph", BsonValue.Create(null)),
+ Update.Unset("ph").Unset("pw"),
+ cancellationToken: ct);
+
+ // Set pixel metadata.
+ await collection.UpdateManyAsync(FindAll,
+ Update.Rename("ph", "md.pixelHeight").Rename("pw", "md.pixelWidth"),
+ cancellationToken: ct);
+
+ // Set type to image.
+ await collection.UpdateManyAsync(new BsonDocument("im", true),
+ Update.Set("at", "Image"),
+ cancellationToken: ct);
+
+ // Set type to unknown.
+ await collection.UpdateManyAsync(new BsonDocument("im", false),
+ Update.Set("at", "Unknown"),
+ cancellationToken: ct);
+
+ // Remove IsImage.
+ await collection.UpdateManyAsync(FindAll,
+ Update.Unset("im"),
+ cancellationToken: ct);
+ }
+}
diff --git a/backend/src/Squidex.Data.MongoDb/Migrations/RenameAssetSlugField.cs b/backend/src/Squidex.Data.MongoDb/Migrations/RenameAssetSlugField.cs
new file mode 100644
index 000000000..2c0b45395
--- /dev/null
+++ b/backend/src/Squidex.Data.MongoDb/Migrations/RenameAssetSlugField.cs
@@ -0,0 +1,27 @@
+// ==========================================================================
+// Squidex Headless CMS
+// ==========================================================================
+// Copyright (c) Squidex UG (haftungsbeschraenkt)
+// All rights reserved. Licensed under the MIT license.
+// ==========================================================================
+
+using MongoDB.Bson;
+using MongoDB.Driver;
+using Squidex.Infrastructure;
+using Squidex.Infrastructure.Migrations;
+
+namespace Squidex.Migrations.MongoDb;
+
+public sealed class RenameAssetSlugField(IMongoDatabase database) : MongoBase, IMigration
+{
+ public Task UpdateAsync(
+ CancellationToken ct)
+ {
+ // Do not resolve in constructor, because most of the time it is not executed anyway.
+ var collection = database.GetCollection("States_Assets");
+
+ var update = Builders.Update.Rename("FileNameSlug", "Slug");
+
+ return collection.UpdateManyAsync(FindAll, update, cancellationToken: ct);
+ }
+}
diff --git a/backend/src/Squidex.Data.MongoDb/Migrations/RestructureContentCollection.cs b/backend/src/Squidex.Data.MongoDb/Migrations/RestructureContentCollection.cs
new file mode 100644
index 000000000..d6dcd098a
--- /dev/null
+++ b/backend/src/Squidex.Data.MongoDb/Migrations/RestructureContentCollection.cs
@@ -0,0 +1,35 @@
+// ==========================================================================
+// Squidex Headless CMS
+// ==========================================================================
+// Copyright (c) Squidex UG (haftungsbeschraenkt)
+// All rights reserved. Licensed under the MIT license.
+// ==========================================================================
+
+using MongoDB.Bson;
+using MongoDB.Driver;
+using Squidex.Infrastructure;
+using Squidex.Infrastructure.Migrations;
+
+namespace Squidex.Migrations.MongoDb;
+
+public sealed class RestructureContentCollection(IMongoDatabase contentDatabase) : MongoBase, IMigration
+{
+ public async Task UpdateAsync(
+ CancellationToken ct)
+ {
+ if (await contentDatabase.CollectionExistsAsync("State_Content_Draft", ct))
+ {
+ await contentDatabase.DropCollectionAsync("State_Contents", ct);
+ await contentDatabase.DropCollectionAsync("State_Content_Published", ct);
+
+ await contentDatabase.RenameCollectionAsync("State_Content_Draft", "State_Contents", cancellationToken: ct);
+ }
+
+ if (await contentDatabase.CollectionExistsAsync("State_Contents", ct))
+ {
+ var collection = contentDatabase.GetCollection("State_Contents");
+
+ await collection.UpdateManyAsync(FindAll, Update.Unset("dt"), cancellationToken: ct);
+ }
+ }
+}
diff --git a/backend/src/Squidex.Data.MongoDb/ServiceExtensions.cs b/backend/src/Squidex.Data.MongoDb/ServiceExtensions.cs
new file mode 100644
index 000000000..3321261c8
--- /dev/null
+++ b/backend/src/Squidex.Data.MongoDb/ServiceExtensions.cs
@@ -0,0 +1,297 @@
+// ==========================================================================
+// Squidex Headless CMS
+// ==========================================================================
+// Copyright (c) Squidex UG (haftungsbeschraenkt)
+// All rights reserved. Licensed under the MIT license.
+// ==========================================================================
+
+using System.Net;
+using System.Text.Json;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.Extensions.Caching.Distributed;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using MongoDB.Bson;
+using MongoDB.Driver;
+using MongoDB.Driver.Core.Extensions.DiagnosticSources;
+using MongoDB.Driver.GridFS;
+using Squidex.AI;
+using Squidex.Domain.Apps.Core.Apps;
+using Squidex.Domain.Apps.Core.Assets;
+using Squidex.Domain.Apps.Core.Contents;
+using Squidex.Domain.Apps.Core.Rules;
+using Squidex.Domain.Apps.Core.Schemas;
+using Squidex.Domain.Apps.Core.Teams;
+using Squidex.Domain.Apps.Entities;
+using Squidex.Domain.Apps.Entities.Apps;
+using Squidex.Domain.Apps.Entities.Apps.Repositories;
+using Squidex.Domain.Apps.Entities.Assets;
+using Squidex.Domain.Apps.Entities.Assets.Repositories;
+using Squidex.Domain.Apps.Entities.Contents;
+using Squidex.Domain.Apps.Entities.Contents.Repositories;
+using Squidex.Domain.Apps.Entities.Contents.Text;
+using Squidex.Domain.Apps.Entities.Contents.Text.State;
+using Squidex.Domain.Apps.Entities.History;
+using Squidex.Domain.Apps.Entities.History.Repositories;
+using Squidex.Domain.Apps.Entities.MongoDb.Assets;
+using Squidex.Domain.Apps.Entities.MongoDb.Contents;
+using Squidex.Domain.Apps.Entities.Rules;
+using Squidex.Domain.Apps.Entities.Rules.Repositories;
+using Squidex.Domain.Apps.Entities.Schemas;
+using Squidex.Domain.Apps.Entities.Schemas.Repositories;
+using Squidex.Domain.Apps.Entities.Teams;
+using Squidex.Domain.Apps.Entities.Teams.Repositories;
+using Squidex.Domain.Apps.Entities.Text;
+using Squidex.Domain.Users;
+using Squidex.Domain.Users.InMemory;
+using Squidex.Domain.Users.MongoDb;
+using Squidex.Events;
+using Squidex.Events.Mongo;
+using Squidex.Infrastructure;
+using Squidex.Infrastructure.Caching;
+using Squidex.Infrastructure.Diagnostics;
+using Squidex.Infrastructure.EventSourcing;
+using Squidex.Infrastructure.Log;
+using Squidex.Infrastructure.Migrations;
+using Squidex.Infrastructure.States;
+using Squidex.Infrastructure.UsageTracking;
+using Squidex.Migrations.MongoDb;
+using YDotNet.Server.MongoDB;
+
+namespace Squidex;
+
+public static class ServiceExtensions
+{
+ public static void AddSquidexMongoEventStore(this IServiceCollection services, IConfiguration config)
+ {
+ var mongoConfiguration = config.GetRequiredValue("eventStore:mongoDb:configuration");
+ var mongoDatabaseName = config.GetRequiredValue("eventStore:mongoDb:database");
+
+ services.AddMongoEventStore(config);
+ services.AddSingletonAs(c =>
+ {
+ var options = c.GetRequiredService>();
+ var mongoClient = GetMongoClient(mongoConfiguration);
+ var mongoDatabase = mongoClient.GetDatabase(mongoDatabaseName);
+
+ return new MongoEventStore(mongoDatabase, options);
+ })
+ .As();
+ }
+
+ public static void AddSquidexMongoAssetStore(this IServiceCollection services, IConfiguration config)
+ {
+ var mongoConfiguration = config.GetRequiredValue("assetStore:mongoDb:configuration");
+ var mongoDatabaseName = config.GetRequiredValue("assetStore:mongoDb:database");
+ var mongoGridFsBucketName = config.GetRequiredValue("assetStore:mongoDb:bucket");
+
+ services.AddMongoAssetStore(c =>
+ {
+ var mongoClient = GetMongoClient(mongoConfiguration);
+ var mongoDatabase = mongoClient.GetDatabase(mongoDatabaseName);
+
+ return new GridFSBucket(mongoDatabase, new GridFSBucketOptions
+ {
+ BucketName = mongoGridFsBucketName
+ });
+ });
+ }
+
+ public static void AddSquidexMongoStore(this IServiceCollection services, IConfiguration config)
+ {
+ var mongoConfiguration = config.GetRequiredValue("store:mongoDb:configuration")!;
+ var mongoDatabaseName = config.GetRequiredValue("store:mongoDb:database")!;
+ var mongoContentDatabaseName = config.GetOptionalValue("store:mongoDb:contentDatabase", mongoDatabaseName)!;
+
+ services.AddMongoAssetKeyValueStore();
+ services.AddSingleton(typeof(ISnapshotStore<>), typeof(MongoSnapshotStore<>));
+
+ services.AddYDotNet()
+ .AddMongoStorage(options =>
+ {
+ options.DatabaseName = mongoDatabaseName;
+ });
+
+ services.AddAI()
+ .AddMongoChatStore(config, options =>
+ {
+ options.CollectionName = "Chat";
+ });
+
+ services.AddMessaging()
+ .AddMongoDataStore(config);
+
+ services.AddSingletonAs(c => GetMongoClient(mongoConfiguration))
+ .As();
+
+ services.AddSingletonAs(c => GetDatabase(c, mongoDatabaseName))
+ .As();
+
+ services.AddSingletonAs()
+ .As();
+
+ services.AddTransientAs()
+ .As();
+
+ services.AddTransientAs()
+ .As();
+
+ services.AddTransientAs(c => new DeleteContentCollections(GetDatabase(c, mongoContentDatabaseName)))
+ .As();
+
+ services.AddTransientAs(c => new RestructureContentCollection(GetDatabase(c, mongoContentDatabaseName)))
+ .As();
+
+ services.AddTransientAs(c => new ConvertDocumentIds(GetDatabase(c, mongoDatabaseName), GetDatabase(c, mongoContentDatabaseName)))
+ .As();
+
+ services.AddTransientAs()
+ .As();
+
+ services.AddTransientAs()
+ .As();
+
+ services.AddTransientAs()
+ .As();
+
+ services.AddTransientAs()
+ .As();
+
+ services.AddSingletonAs()
+ .As();
+
+ services.AddHealthChecks()
+ .AddCheck("MongoDB", tags: ["node"]);
+
+ services.AddSingletonAs()
+ .As();
+
+ services.AddSingletonAs()
+ .As();
+
+ services.AddSingletonAs()
+ .As().As();
+
+ services.AddSingletonAs()
+ .As().As();
+
+ services.AddSingletonAs()
+ .As>();
+
+ services.AddSingletonAs()
+ .As>().As();
+
+ services.AddSingletonAs()
+ .As().As>().As();
+
+ services.AddSingletonAs()
+ .As().As>().As();
+
+ services.AddSingletonAs()
+ .As().As>();
+
+ services.AddSingletonAs()
+ .As().As>().As();
+
+ services.AddSingletonAs()
+ .As().As>().As();
+
+ services.AddSingletonAs()
+ .AsOptional().As().As();
+
+ services.AddSingletonAs()
+ .As().As();
+
+ services.AddSingletonAs(c =>
+ {
+ return new MongoShardedAssetRepository(GetSharding(config, "store:mongoDB:assetShardCount"),
+ shardKey => ActivatorUtilities.CreateInstance(c, shardKey));
+ }).As().As>().As();
+
+ services.AddSingletonAs(c =>
+ {
+ var contentDatabase = GetDatabase(c, mongoContentDatabaseName);
+
+ return new MongoShardedContentRepository(GetSharding(config, "store:mongoDB:contentShardCount"),
+ shardKey => ActivatorUtilities.CreateInstance(c, shardKey, contentDatabase));
+ }).As().As>().As();
+
+ services.AddOpenIddict()
+ .AddCore(builder =>
+ {
+ builder.UseMongoDb()
+ .SetScopesCollectionName("Identity_Scopes")
+ .SetTokensCollectionName("Identity_Tokens");
+
+ builder.SetDefaultScopeEntity();
+ builder.SetDefaultApplicationEntity();
+ });
+
+ var atlasOptions = config.GetSection("store:mongoDb:atlas").Get() ?? new ();
+
+ if (atlasOptions.IsConfigured() && atlasOptions.FullTextEnabled)
+ {
+ services.Configure(config.GetSection("store:mongoDb:atlas"));
+
+ services.AddHttpClient("Atlas", options =>
+ {
+ options.BaseAddress = new Uri("https://cloud.mongodb.com/");
+ })
+ .ConfigurePrimaryHttpMessageHandler(() =>
+ {
+ return new HttpClientHandler
+ {
+ Credentials = new NetworkCredential(atlasOptions.PublicKey, atlasOptions.PrivateKey, "cloud.mongodb.com")
+ };
+ });
+
+ services.AddSingletonAs(c =>
+ {
+ return new MongoShardedTextIndex>(GetSharding(config, "store:mongoDB:textShardCount"),
+ shardKey => ActivatorUtilities.CreateInstance(c, shardKey));
+ }).AsOptional().As();
+ }
+ else
+ {
+ services.AddSingletonAs(c =>
+ {
+ return new MongoShardedTextIndex>(GetSharding(config, "store:mongoDB:textShardCount"),
+ shardKey => ActivatorUtilities.CreateInstance(c, shardKey));
+ }).AsOptional().As();
+ }
+
+ services.AddInitializer("Serializer (BSON)", jsonSerializerOptions =>
+ {
+ var representation = config.GetValue("store:mongoDB:valueRepresentation");
+
+ BsonJsonConvention.Register(jsonSerializerOptions, representation);
+ }, int.MinValue);
+ }
+
+ private static IMongoClient GetMongoClient(string configuration)
+ {
+ return Singletons.GetOrAdd(configuration, connectionString =>
+ {
+ return MongoClientFactory.Create(connectionString, settings =>
+ {
+ settings.ClusterConfigurator = builder =>
+ {
+ builder.Subscribe(new DiagnosticsActivityEventSubscriber());
+ };
+ });
+ });
+ }
+
+ private static IShardingStrategy GetSharding(IConfiguration config, string name)
+ {
+ var shardCount = config.GetValue(name);
+
+ return shardCount > 0 && shardCount <= 100 ? new PartitionedSharding(shardCount) : SingleSharding.Instance;
+ }
+
+ private static IMongoDatabase GetDatabase(IServiceProvider serviceProvider, string name)
+ {
+ return serviceProvider.GetRequiredService().GetDatabase(name);
+ }
+}
diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj b/backend/src/Squidex.Data.MongoDb/Squidex.Data.MongoDb.csproj
similarity index 61%
rename from backend/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj
rename to backend/src/Squidex.Data.MongoDb/Squidex.Data.MongoDb.csproj
index 988e72b0a..0f54de38c 100644
--- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj
+++ b/backend/src/Squidex.Data.MongoDb/Squidex.Data.MongoDb.csproj
@@ -1,6 +1,7 @@
-
+
net8.0
+ Squidex
latest
enable
enable
@@ -10,12 +11,9 @@
True
-
-
-
-
-
+
+
@@ -24,9 +22,18 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EventEnricher.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EventEnricher.cs
index 953334eec..bffed50c5 100644
--- a/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EventEnricher.cs
+++ b/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EventEnricher.cs
@@ -22,7 +22,7 @@ public sealed class EventEnricher(IMemoryCache userCache, IUserResolver userReso
{
if (@event != null)
{
- enrichedEvent.Timestamp = @event.Headers.Timestamp();
+ enrichedEvent.Timestamp = @event.Headers.TimestampAsInstant();
enrichedEvent.AppId = @event.Payload.AppId;
}
diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs
index bada0828e..9d050df60 100644
--- a/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs
+++ b/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs
@@ -170,7 +170,7 @@ public sealed class RuleService(
var eventTime =
@event.Headers.ContainsKey(CommonHeaders.Timestamp) ?
- @event.Headers.Timestamp() :
+ @event.Headers.TimestampAsInstant() :
now;
if (!context.IncludeStale && eventTime.Plus(Constants.StaleTime) < now)
diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj b/backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj
index 543674455..f29d8c396 100644
--- a/backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj
+++ b/backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj
@@ -28,8 +28,8 @@
-
-
+
+
diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/Subscriptions/SubscriptionPublisher.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/Subscriptions/SubscriptionPublisher.cs
index e2c81847d..c22ce994c 100644
--- a/backend/src/Squidex.Domain.Apps.Core.Operations/Subscriptions/SubscriptionPublisher.cs
+++ b/backend/src/Squidex.Domain.Apps.Core.Operations/Subscriptions/SubscriptionPublisher.cs
@@ -8,6 +8,7 @@
using Squidex.Domain.Apps.Events;
using Squidex.Domain.Apps.Events.Assets;
using Squidex.Domain.Apps.Events.Contents;
+using Squidex.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Messaging.Subscriptions;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Apps/AppEventDeleter.cs b/backend/src/Squidex.Domain.Apps.Entities/Apps/AppEventDeleter.cs
index f99f9bb53..ffdeed326 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Apps/AppEventDeleter.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Apps/AppEventDeleter.cs
@@ -6,7 +6,7 @@
// ==========================================================================
using Squidex.Domain.Apps.Core.Apps;
-using Squidex.Infrastructure.EventSourcing;
+using Squidex.Events;
namespace Squidex.Domain.Apps.Entities.Apps;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Apps/AppPermanentDeleter.cs b/backend/src/Squidex.Domain.Apps.Entities/Apps/AppPermanentDeleter.cs
index 9ddfc3cdf..879166abe 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Apps/AppPermanentDeleter.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Apps/AppPermanentDeleter.cs
@@ -8,6 +8,7 @@
using Microsoft.Extensions.Options;
using Squidex.Domain.Apps.Entities.Apps.DomainObject;
using Squidex.Domain.Apps.Events.Apps;
+using Squidex.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetPermanentDeleter.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetPermanentDeleter.cs
index efde8234e..ba49159b2 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetPermanentDeleter.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetPermanentDeleter.cs
@@ -7,6 +7,7 @@
using Squidex.Assets;
using Squidex.Domain.Apps.Events.Assets;
+using Squidex.Events;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Reflection;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetUsageTracker_EventHandling.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetUsageTracker_EventHandling.cs
index dd9af405b..bb02da189 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetUsageTracker_EventHandling.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetUsageTracker_EventHandling.cs
@@ -9,6 +9,7 @@ using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using Squidex.Domain.Apps.Core.Tags;
using Squidex.Domain.Apps.Events.Assets;
+using Squidex.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.States;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/RebuildFiles.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/RebuildFiles.cs
index 910f2c68a..931c7641d 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Assets/RebuildFiles.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/RebuildFiles.cs
@@ -8,6 +8,7 @@
using System.Text;
using Squidex.Assets;
using Squidex.Domain.Apps.Events.Assets;
+using Squidex.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/RecursiveDeleter.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/RecursiveDeleter.cs
index b1cc8c4c8..487e65ec4 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Assets/RecursiveDeleter.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/RecursiveDeleter.cs
@@ -9,6 +9,7 @@ using Microsoft.Extensions.Logging;
using Squidex.Domain.Apps.Entities.Assets.Commands;
using Squidex.Domain.Apps.Entities.Assets.Repositories;
using Squidex.Domain.Apps.Events.Assets;
+using Squidex.Events;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Reflection;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupJob.cs b/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupJob.cs
index c75e06d9a..ae01b1fd3 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupJob.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupJob.cs
@@ -8,6 +8,7 @@
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Entities.Jobs;
using Squidex.Domain.Apps.Events;
+using Squidex.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Translations;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupWriter.cs b/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupWriter.cs
index e3faa5e45..e6c7b8c23 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupWriter.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupWriter.cs
@@ -8,8 +8,8 @@
using System.IO.Compression;
using Squidex.Domain.Apps.Entities.Backup.Helpers;
using Squidex.Domain.Apps.Entities.Backup.Model;
+using Squidex.Events;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Json;
namespace Squidex.Domain.Apps.Entities.Backup;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Backup/IBackupWriter.cs b/backend/src/Squidex.Domain.Apps.Entities/Backup/IBackupWriter.cs
index b2347119e..e46b009a2 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Backup/IBackupWriter.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Backup/IBackupWriter.cs
@@ -5,7 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
-using Squidex.Infrastructure.EventSourcing;
+using Squidex.Events;
namespace Squidex.Domain.Apps.Entities.Backup;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Backup/Model/CompatibleStoredEvent.cs b/backend/src/Squidex.Domain.Apps.Entities/Backup/Model/CompatibleStoredEvent.cs
index 5a0f36f0f..672ca3700 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Backup/Model/CompatibleStoredEvent.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Backup/Model/CompatibleStoredEvent.cs
@@ -6,7 +6,7 @@
// ==========================================================================
using System.Text.Json.Serialization;
-using Squidex.Infrastructure.EventSourcing;
+using Squidex.Events;
using Squidex.Infrastructure.Json.System;
#pragma warning disable MA0048 // File name must match type name
@@ -35,7 +35,7 @@ public sealed class CompatibleStoredEvent
return new CompatibleStoredEvent
{
Data = CompatibleEventData.V1(stored.Data),
- EventPosition = stored.EventPosition,
+ EventPosition = stored.EventPosition.Token!,
EventStreamNumber = stored.EventStreamNumber,
StreamName = stored.StreamName
};
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreJob.cs b/backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreJob.cs
index e883df84a..31bf2748b 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreJob.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreJob.cs
@@ -12,6 +12,7 @@ using Squidex.Domain.Apps.Entities.Apps.Commands;
using Squidex.Domain.Apps.Entities.Jobs;
using Squidex.Domain.Apps.Events;
using Squidex.Domain.Apps.Events.Apps;
+using Squidex.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
@@ -265,7 +266,7 @@ public sealed class RestoreJob(
{
var commits =
batch.Select(item =>
- EventCommit.Create(
+ EventCommitBuilder.Create(
item.Stream,
item.Offset,
item.Event,
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Collaboration/CommentCollaborationHandler.cs b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/CommentCollaborationHandler.cs
index 2d476b053..33005c0c3 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Collaboration/CommentCollaborationHandler.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/CommentCollaborationHandler.cs
@@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging;
using NodaTime;
using Squidex.Domain.Apps.Core.Comments;
using Squidex.Domain.Apps.Events.Comments;
+using Squidex.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Json;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentEventDeleter.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentEventDeleter.cs
index d04a401a8..98e3d0566 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentEventDeleter.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentEventDeleter.cs
@@ -8,8 +8,8 @@
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Contents.Repositories;
+using Squidex.Events;
using Squidex.Infrastructure;
-using Squidex.Infrastructure.EventSourcing;
namespace Squidex.Domain.Apps.Entities.Contents;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexingProcess.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexingProcess.cs
index 9c992341d..f2d1a0c76 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexingProcess.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexingProcess.cs
@@ -8,6 +8,7 @@
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Entities.Contents.Text.State;
using Squidex.Domain.Apps.Events.Contents;
+using Squidex.Events;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Json;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/EntityExtensions.cs b/backend/src/Squidex.Domain.Apps.Entities/EntityExtensions.cs
index dad751e51..81b8e9214 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/EntityExtensions.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/EntityExtensions.cs
@@ -17,7 +17,7 @@ public static class EntityExtensions
{
var headers = @event.Headers;
- var timestamp = headers.Timestamp();
+ var timestamp = headers.TimestampAsInstant();
var created = source.Created;
var createdBy = source.CreatedBy;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/History/HistoryService.cs b/backend/src/Squidex.Domain.Apps.Entities/History/HistoryService.cs
index c61010a6a..adf0d96b8 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/History/HistoryService.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/History/HistoryService.cs
@@ -5,10 +5,12 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
+using NodaTime.Extensions;
using Squidex.Domain.Apps.Entities.History.Repositories;
using Squidex.Domain.Apps.Events;
using Squidex.Domain.Apps.Events.Comments;
using Squidex.Domain.Apps.Events.Teams;
+using Squidex.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
@@ -113,7 +115,7 @@ public sealed class HistoryService : IHistoryService, IEventConsumer
{
historyEvent.Actor = actor;
historyEvent.OwnerId = ownerId;
- historyEvent.Created = @event.Headers.Timestamp();
+ historyEvent.Created = @event.Headers.Timestamp().ToInstant();
historyEvent.Version = @event.Headers.EventStreamNumber();
return historyEvent;
}
diff --git a/backend/src/Squidex.Domain.Apps.Entities/History/NotifoService.cs b/backend/src/Squidex.Domain.Apps.Entities/History/NotifoService.cs
index c6f056f9b..73acd7923 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/History/NotifoService.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/History/NotifoService.cs
@@ -153,7 +153,7 @@ public class NotifoService : IUserEvents
var batches = events
.Where(x => x.AppEvent.Headers.Restored() == false)
- .Where(x => x.AppEvent.Headers.Timestamp() > maxAge)
+ .Where(x => x.AppEvent.Headers.TimestampAsInstant() > maxAge)
.SelectMany(x => CreateRequests(x.AppEvent, x.HistoryEvent))
.Batch(50);
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Invitation/InvitationEventConsumer.cs b/backend/src/Squidex.Domain.Apps.Entities/Invitation/InvitationEventConsumer.cs
index a79d14e67..45854d0bb 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Invitation/InvitationEventConsumer.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Invitation/InvitationEventConsumer.cs
@@ -10,6 +10,7 @@ using NodaTime;
using Squidex.Domain.Apps.Entities.Collaboration;
using Squidex.Domain.Apps.Events.Apps;
using Squidex.Domain.Apps.Events.Teams;
+using Squidex.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Shared.Users;
@@ -41,11 +42,10 @@ public sealed class InvitationEventConsumer(
return;
}
- var now = SystemClock.Instance.GetCurrentInstant();
+ var timestamp = @event.Headers.TimestampAsInstant();
- var timestamp = @event.Headers.Timestamp();
-
- if (now - timestamp > MaxAge)
+ var currentTime = SystemClock.Instance.GetCurrentInstant();
+ if (currentTime - timestamp > MaxAge)
{
return;
}
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/DefaultRuleRunnerService.cs b/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/DefaultRuleRunnerService.cs
index 0d2ed42e0..d4ceba59f 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/DefaultRuleRunnerService.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/DefaultRuleRunnerService.cs
@@ -12,6 +12,7 @@ using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Core.Rules.Triggers;
using Squidex.Domain.Apps.Entities.Jobs;
using Squidex.Domain.Apps.Events;
+using Squidex.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Collections;
using Squidex.Infrastructure.EventSourcing;
@@ -51,7 +52,7 @@ public sealed class DefaultRuleRunnerService(
var simulatedEvents = new List(MaxSimulatedEvents);
- var streamStart = SystemClock.Instance.GetCurrentInstant().Minus(Duration.FromDays(7));
+ var streamStart = SystemClock.Instance.GetCurrentInstant().Minus(Duration.FromDays(7)).ToDateTimeUtc();
var streamFilter = StreamFilter.Prefix($"([a-zA-Z0-9]+)-{appId.Id}");
await foreach (var storedEvent in eventStore.QueryAllReverseAsync(streamFilter, streamStart, MaxSimulatedEvents, ct))
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerJob.cs b/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerJob.cs
index ccac502e8..0d3b64298 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerJob.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerJob.cs
@@ -11,6 +11,7 @@ using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Entities.Jobs;
using Squidex.Domain.Apps.Entities.Rules.Repositories;
+using Squidex.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Translations;
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Schemas/SchemaPermanentDeleter.cs b/backend/src/Squidex.Domain.Apps.Entities/Schemas/SchemaPermanentDeleter.cs
index 988c7797d..cd326485f 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Schemas/SchemaPermanentDeleter.cs
+++ b/backend/src/Squidex.Domain.Apps.Entities/Schemas/SchemaPermanentDeleter.cs
@@ -8,6 +8,7 @@
using Microsoft.Extensions.Options;
using Squidex.Domain.Apps.Entities.Schemas.DomainObject;
using Squidex.Domain.Apps.Events.Schemas;
+using Squidex.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
@@ -60,7 +61,7 @@ public sealed class SchemaPermanentDeleter(
return;
}
- using var activity = Telemetry.Activities.StartActivity("RemoveAppFromSystem");
+ using var activity = Infrastructure.Telemetry.Activities.StartActivity("RemoveAppFromSystem");
var app = await appProvider.GetAppAsync(schemaDeleted.AppId.Id);
if (app == null)
@@ -76,7 +77,7 @@ public sealed class SchemaPermanentDeleter(
foreach (var deleter in deleters)
{
- using (Telemetry.Activities.StartActivity(deleter.GetType().Name))
+ using (Infrastructure.Telemetry.Activities.StartActivity(deleter.GetType().Name))
{
await deleter.DeleteSchemaAsync(app, schema.Snapshot, default);
}
diff --git a/backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj b/backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj
index c895f072a..01282f323 100644
--- a/backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj
+++ b/backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj
@@ -34,7 +34,7 @@
-
+
diff --git a/backend/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj b/backend/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj
deleted file mode 100644
index 9bf54c083..000000000
--- a/backend/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
- net8.0
- latest
- enable
- enable
-
-
- full
- True
-
-
-
-
-
-
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/backend/src/Squidex.Infrastructure.Azure/Diagnostics/CosmosDbHealthCheck.cs b/backend/src/Squidex.Infrastructure.Azure/Diagnostics/CosmosDbHealthCheck.cs
deleted file mode 100644
index 9625c9571..000000000
--- a/backend/src/Squidex.Infrastructure.Azure/Diagnostics/CosmosDbHealthCheck.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-// ==========================================================================
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex UG (haftungsbeschraenkt)
-// All rights reserved. Licensed under the MIT license.
-// ==========================================================================
-
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Azure.Documents.Client;
-using Microsoft.Extensions.Diagnostics.HealthChecks;
-
-namespace Squidex.Infrastructure.Diagnostics
-{
- public sealed class CosmosDbHealthCheck : IHealthCheck
- {
- private readonly DocumentClient documentClient;
-
- public CosmosDbHealthCheck(Uri uri, string masterKey)
- {
- documentClient = new DocumentClient(uri, masterKey);
- }
-
- public async Task CheckHealthAsync(HealthCheckContext context,
- CancellationToken cancellationToken = default)
- {
- await documentClient.ReadDatabaseFeedAsync();
-
- return HealthCheckResult.Healthy("Application must query data from CosmosDB.");
- }
- }
-}
diff --git a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/Constants.cs b/backend/src/Squidex.Infrastructure.Azure/EventSourcing/Constants.cs
deleted file mode 100644
index 120f38704..000000000
--- a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/Constants.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-// ==========================================================================
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex UG (haftungsbeschraenkt)
-// All rights reserved. Licensed under the MIT license.
-// ==========================================================================
-
-namespace Squidex.Infrastructure.EventSourcing
-{
- internal static class Constants
- {
- public const string Collection = "Events";
-
- public const string LeaseCollection = "Leases";
- }
-}
diff --git a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEvent.cs b/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEvent.cs
deleted file mode 100644
index cef83bb18..000000000
--- a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEvent.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// ==========================================================================
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex UG (haftungsbeschraenkt)
-// All rights reserved. Licensed under the MIT license.
-// ==========================================================================
-
-namespace Squidex.Infrastructure.EventSourcing
-{
- internal sealed class CosmosDbEvent
- {
- public string Type { get; set; }
-
- public string Payload { get; set; }
-
- public EnvelopeHeaders Headers { get; set; }
-
- public static CosmosDbEvent FromEventData(EventData data)
- {
- return new CosmosDbEvent { Type = data.Type, Headers = data.Headers, Payload = data.Payload };
- }
-
- public EventData ToEventData()
- {
- return new EventData(Type, Headers, Payload);
- }
- }
-}
\ No newline at end of file
diff --git a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventCommit.cs b/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventCommit.cs
deleted file mode 100644
index 194ad925e..000000000
--- a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventCommit.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// ==========================================================================
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex UG (haftungsbeschraenkt)
-// All rights reserved. Licensed under the MIT license.
-// ==========================================================================
-
-using System;
-
-namespace Squidex.Infrastructure.EventSourcing
-{
- internal sealed class CosmosDbEventCommit
- {
- public Guid Id { get; set; }
-
- public CosmosDbEvent[] Events { get; set; }
-
- public long EventStreamOffset { get; set; }
-
- public long EventsCount { get; set; }
-
- public string EventStream { get; set; }
-
- public long Timestamp { get; set; }
- }
-}
diff --git a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventStore.cs b/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventStore.cs
deleted file mode 100644
index f756ca0b2..000000000
--- a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventStore.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-// ==========================================================================
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex UG (haftungsbeschraenkt)
-// All rights reserved. Licensed under the MIT license.
-// ==========================================================================
-
-using System;
-using System.Collections.ObjectModel;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Azure.Documents;
-using Microsoft.Azure.Documents.Client;
-using Squidex.Hosting;
-using Squidex.Infrastructure.Json;
-using Index = Microsoft.Azure.Documents.Index;
-
-namespace Squidex.Infrastructure.EventSourcing
-{
- public sealed partial class CosmosDbEventStore : DisposableObjectBase, IEventStore, IInitializable
- {
- private readonly DocumentClient documentClient;
- private readonly Uri collectionUri;
- private readonly Uri databaseUri;
-
- public IJsonSerializer JsonSerializer { get; }
-
- public string DatabaseId { get; }
-
- public string MasterKey { get; }
-
- public Uri ServiceUri
- {
- get => documentClient.ServiceEndpoint;
- }
-
- public CosmosDbEventStore(DocumentClient documentClient, string masterKey, string database, IJsonSerializer jsonSerializer)
- {
- this.documentClient = documentClient;
-
- databaseUri = UriFactory.CreateDatabaseUri(database);
- DatabaseId = database;
-
- collectionUri = UriFactory.CreateDocumentCollectionUri(database, Constants.Collection);
-
- MasterKey = masterKey;
-
- JsonSerializer = jsonSerializer;
- }
-
- protected override void DisposeObject(bool disposing)
- {
- if (disposing)
- {
- documentClient.Dispose();
- }
- }
-
- public async Task InitializeAsync(
- CancellationToken ct = default)
- {
- await documentClient.CreateDatabaseIfNotExistsAsync(new Database { Id = DatabaseId });
-
- await documentClient.CreateDocumentCollectionIfNotExistsAsync(databaseUri,
- new DocumentCollection
- {
- PartitionKey = new PartitionKeyDefinition
- {
- Paths = new Collection
- {
- "/id"
- }
- },
- Id = Constants.LeaseCollection
- });
-
- await documentClient.CreateDocumentCollectionIfNotExistsAsync(databaseUri,
- new DocumentCollection
- {
- PartitionKey = new PartitionKeyDefinition
- {
- Paths = new Collection
- {
- "/eventStream"
- }
- },
- IndexingPolicy = new IndexingPolicy
- {
- IncludedPaths = new Collection
- {
- new IncludedPath
- {
- Path = "/*",
- Indexes = new Collection
- {
- Index.Range(DataType.Number),
- Index.Range(DataType.String)
- }
- }
- }
- },
- UniqueKeyPolicy = new UniqueKeyPolicy
- {
- UniqueKeys = new Collection
- {
- new UniqueKey
- {
- Paths = new Collection
- {
- "/eventStream",
- "/eventStreamOffset"
- }
- }
- }
- },
- Id = Constants.Collection
- },
- new RequestOptions
- {
- PartitionKey = new PartitionKey("/eventStream")
- });
- }
- }
-}
diff --git a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventStore_Reader.cs b/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventStore_Reader.cs
deleted file mode 100644
index b498884d2..000000000
--- a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventStore_Reader.cs
+++ /dev/null
@@ -1,166 +0,0 @@
-// ==========================================================================
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex UG (haftungsbeschraenkt)
-// All rights reserved. Licensed under the MIT license.
-// ==========================================================================
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Threading;
-using System.Threading.Tasks;
-using Squidex.Hosting;
-using Squidex.Log;
-
-namespace Squidex.Infrastructure.EventSourcing
-{
- public delegate bool EventPredicate(EventData data);
-
- public partial class CosmosDbEventStore : IEventStore, IInitializable
- {
- private static readonly IReadOnlyList EmptyEvents = new List();
-
- public IEventSubscription CreateSubscription(IEventSubscriber subscriber, string? streamFilter = null, string? position = null)
- {
- Guard.NotNull(subscriber, nameof(subscriber));
-
- ThrowIfDisposed();
-
- return new CosmosDbSubscription(this, subscriber, streamFilter, position);
- }
-
- public async Task> QueryLatestAsync(string streamName, int count)
- {
- Guard.NotNullOrEmpty(streamName, nameof(streamName));
-
- ThrowIfDisposed();
-
- if (count <= 0)
- {
- return EmptyEvents;
- }
-
- using (Profiler.TraceMethod())
- {
- var query = FilterBuilder.ByStreamNameDesc(streamName, count);
-
- var result = new List();
-
- await foreach (var commit in documentClient.QueryAsync(collectionUri, query, default))
- {
- foreach (var storedEvent in commit.Filtered().Reverse())
- {
- result.Add(storedEvent);
-
- if (result.Count == count)
- {
- break;
- }
- }
- }
-
- return result;
- }
- }
-
- public async Task> QueryAsync(string streamName, long streamPosition = 0)
- {
- Guard.NotNullOrEmpty(streamName, nameof(streamName));
-
- ThrowIfDisposed();
-
- using (Profiler.TraceMethod())
- {
- var query = FilterBuilder.ByStreamName(streamName, streamPosition - MaxCommitSize);
-
- var result = new List();
-
- await foreach (var commit in documentClient.QueryAsync(collectionUri, query, default))
- {
- foreach (var storedEvent in commit.Filtered().Reverse())
- {
- result.Add(storedEvent);
- }
- }
-
- return result;
- }
- }
-
- public async IAsyncEnumerable QueryAllAsync( string? streamFilter = null, string? position = null, long take = long.MaxValue,
- [EnumeratorCancellation] CancellationToken ct = default)
- {
- ThrowIfDisposed();
-
- if (take <= 0)
- {
- yield break;
- }
-
- StreamPosition lastPosition = position;
-
- var filterDefinition = FilterBuilder.CreateByFilter(streamFilter, lastPosition, "ASC", take);
-
- var taken = int.MaxValue;
-
- await foreach (var commit in documentClient.QueryAsync(collectionUri, filterDefinition, ct: ct))
- {
- if (taken == take)
- {
- yield break;
- }
-
- foreach (var storedEvent in commit.Filtered(lastPosition))
- {
- if (taken == take)
- {
- yield break;
- }
-
- yield return storedEvent;
-
- taken++;
- }
- }
- }
-
- public async IAsyncEnumerable QueryAllReverseAsync(string? streamFilter = null, string? position = null, long take = long.MaxValue,
- [EnumeratorCancellation] CancellationToken ct = default)
- {
- ThrowIfDisposed();
-
- if (take <= 0)
- {
- yield break;
- }
-
- StreamPosition lastPosition = position;
-
- var filterDefinition = FilterBuilder.CreateByFilter(streamFilter, lastPosition, "DESC", take);
-
- var taken = long.MaxValue;
-
- await foreach (var commit in documentClient.QueryAsync(collectionUri, filterDefinition, ct: ct))
- {
- if (taken == take)
- {
- yield break;
- }
-
- foreach (var storedEvent in commit.Filtered(lastPosition))
- {
- if (taken == take)
- {
- yield break;
- }
-
- yield return storedEvent;
-
- taken++;
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventStore_Writer.cs b/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventStore_Writer.cs
deleted file mode 100644
index 68bf3d0d5..000000000
--- a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbEventStore_Writer.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-// ==========================================================================
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex UG (haftungsbeschraenkt)
-// All rights reserved. Licensed under the MIT license.
-// ==========================================================================
-
-using System;
-using System.Collections.Generic;
-using System.Net;
-using System.Threading.Tasks;
-using Microsoft.Azure.Documents;
-using Microsoft.Azure.Documents.Client;
-using NodaTime;
-using Squidex.Log;
-
-namespace Squidex.Infrastructure.EventSourcing
-{
- public partial class CosmosDbEventStore
- {
- private const int MaxWriteAttempts = 20;
- private const int MaxCommitSize = 10;
-
- public async Task DeleteStreamAsync(string streamName)
- {
- Guard.NotNullOrEmpty(streamName, nameof(streamName));
-
- ThrowIfDisposed();
-
- var query = FilterBuilder.AllIds(streamName);
-
- var deleteOptions = new RequestOptions
- {
- PartitionKey = new PartitionKey(streamName)
- };
-
- await foreach (var commit in documentClient.QueryAsync(collectionUri, query))
- {
- var documentUri = UriFactory.CreateDocumentUri(DatabaseId, Constants.Collection, commit.Id.ToString());
-
- await documentClient.DeleteDocumentAsync(documentUri, deleteOptions);
- }
- }
-
- public Task AppendAsync(Guid commitId, string streamName, ICollection events)
- {
- return AppendAsync(commitId, streamName, EtagVersion.Any, events);
- }
-
- public async Task AppendAsync(Guid commitId, string streamName, long expectedVersion, ICollection events)
- {
- Guard.NotEmpty(commitId, nameof(commitId));
- Guard.NotNullOrEmpty(streamName, nameof(streamName));
- Guard.NotNull(events, nameof(events));
- Guard.LessThan(events.Count, MaxCommitSize, "events.Count");
-
- ThrowIfDisposed();
-
- using (Profiler.TraceMethod())
- {
- if (events.Count == 0)
- {
- return;
- }
-
- var currentVersion = await GetEventStreamOffsetAsync(streamName);
-
- if (expectedVersion > EtagVersion.Any && expectedVersion != currentVersion)
- {
- throw new WrongEventVersionException(currentVersion, expectedVersion);
- }
-
- var commit = BuildCommit(commitId, streamName, expectedVersion >= -1 ? expectedVersion : currentVersion, events);
-
- for (var attempt = 0; attempt < MaxWriteAttempts; attempt++)
- {
- try
- {
- await documentClient.CreateDocumentAsync(collectionUri, commit);
-
- return;
- }
- catch (DocumentClientException ex)
- {
- if (ex.StatusCode == HttpStatusCode.Conflict)
- {
- currentVersion = await GetEventStreamOffsetAsync(streamName);
-
- if (expectedVersion > EtagVersion.Any)
- {
- throw new WrongEventVersionException(currentVersion, expectedVersion);
- }
-
- if (attempt < MaxWriteAttempts)
- {
- expectedVersion = currentVersion;
- }
- else
- {
- throw new TimeoutException("Could not acquire a free slot for the commit within the provided time.");
- }
- }
- else
- {
- throw;
- }
- }
- }
- }
- }
-
- private async Task GetEventStreamOffsetAsync(string streamName)
- {
- var query =
- documentClient.CreateDocumentQuery(collectionUri,
- FilterBuilder.LastPosition(streamName));
-
- var document = await query.FirstOrDefaultAsync();
-
- if (document != null)
- {
- return document.EventStreamOffset + document.EventsCount;
- }
-
- return EtagVersion.Empty;
- }
-
- private static CosmosDbEventCommit BuildCommit(Guid commitId, string streamName, long expectedVersion, ICollection events)
- {
- var commitEvents = new CosmosDbEvent[events.Count];
-
- var i = 0;
-
- foreach (var e in events)
- {
- var mongoEvent = CosmosDbEvent.FromEventData(e);
-
- commitEvents[i++] = mongoEvent;
- }
-
- var mongoCommit = new CosmosDbEventCommit
- {
- Id = commitId,
- Events = commitEvents,
- EventsCount = events.Count,
- EventStream = streamName,
- EventStreamOffset = expectedVersion,
- Timestamp = SystemClock.Instance.GetCurrentInstant().ToUnixTimeTicks()
- };
-
- return mongoCommit;
- }
- }
-}
\ No newline at end of file
diff --git a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbSubscription.cs b/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbSubscription.cs
deleted file mode 100644
index 97ff67e3d..000000000
--- a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/CosmosDbSubscription.cs
+++ /dev/null
@@ -1,143 +0,0 @@
-// ==========================================================================
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex UG (haftungsbeschraenkt)
-// All rights reserved. Licensed under the MIT license.
-// ==========================================================================
-
-using System;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Azure.Documents;
-using Microsoft.Azure.Documents.ChangeFeedProcessor.FeedProcessing;
-using Builder = Microsoft.Azure.Documents.ChangeFeedProcessor.ChangeFeedProcessorBuilder;
-using Collection = Microsoft.Azure.Documents.ChangeFeedProcessor.DocumentCollectionInfo;
-using Options = Microsoft.Azure.Documents.ChangeFeedProcessor.ChangeFeedProcessorOptions;
-
-#pragma warning disable IDE0017 // Simplify object initialization
-
-namespace Squidex.Infrastructure.EventSourcing
-{
- internal sealed class CosmosDbSubscription : IEventSubscription, IChangeFeedObserverFactory, IChangeFeedObserver
- {
- private readonly TaskCompletionSource processorStopRequested = new TaskCompletionSource();
- private readonly CosmosDbEventStore store;
- private readonly Regex regex;
- private readonly string hostName;
- private readonly IEventSubscriber subscriber;
-
- public CosmosDbSubscription(CosmosDbEventStore store, IEventSubscriber subscriber, string? streamFilter, string? position = null)
- {
- this.store = store;
-
- var fromBeginning = string.IsNullOrWhiteSpace(position);
-
- if (fromBeginning)
- {
- hostName = $"squidex.{DateTime.UtcNow.Ticks}";
- }
- else
- {
- hostName = position ?? "none";
- }
-
- if (!StreamFilter.IsAll(streamFilter))
- {
- regex = new Regex(streamFilter);
- }
-
- this.subscriber = subscriber;
-
- Task.Run(async () =>
- {
- try
- {
- var processor =
- await new Builder()
- .WithFeedCollection(CreateCollection(store, Constants.Collection))
- .WithLeaseCollection(CreateCollection(store, Constants.LeaseCollection))
- .WithHostName(hostName)
- .WithProcessorOptions(new Options { StartFromBeginning = fromBeginning, LeasePrefix = hostName })
- .WithObserverFactory(this)
- .BuildAsync();
-
- await processor.StartAsync();
- await processorStopRequested.Task;
- await processor.StopAsync();
- }
- catch (Exception ex)
- {
- await subscriber.OnErrorAsync(this, ex);
- }
- });
- }
-
- private static Collection CreateCollection(CosmosDbEventStore store, string name)
- {
- var collection = new Collection();
-
- collection.CollectionName = name;
- collection.DatabaseName = store.DatabaseId;
- collection.MasterKey = store.MasterKey;
- collection.Uri = store.ServiceUri;
-
- return collection;
- }
-
- public IChangeFeedObserver CreateObserver()
- {
- return this;
- }
-
- public async Task CloseAsync(IChangeFeedObserverContext context, ChangeFeedObserverCloseReason reason)
- {
- if (reason == ChangeFeedObserverCloseReason.ObserverError)
- {
- await subscriber.OnErrorAsync(this, new InvalidOperationException("Change feed observer failed."));
- }
- }
-
- public Task OpenAsync(IChangeFeedObserverContext context)
- {
- return Task.CompletedTask;
- }
-
- public async Task ProcessChangesAsync(IChangeFeedObserverContext context, IReadOnlyList docs,
- CancellationToken cancellationToken)
- {
- if (!processorStopRequested.Task.IsCompleted)
- {
- foreach (var document in docs)
- {
- if (!processorStopRequested.Task.IsCompleted)
- {
- var streamName = document.GetPropertyValue("eventStream");
-
- if (regex == null || regex.IsMatch(streamName))
- {
- var commit = store.JsonSerializer.Deserialize(document.ToString());
-
- var eventStreamOffset = (int)commit.EventStreamOffset;
-
- foreach (var @event in commit.Events)
- {
- eventStreamOffset++;
-
- var eventData = @event.ToEventData();
-
- await subscriber.OnEventAsync(this, new StoredEvent(commit.EventStream, hostName, eventStreamOffset, eventData));
- }
- }
- }
- }
- }
- }
-
- public void Unsubscribe()
- {
- processorStopRequested.SetResult(true);
- }
- }
-}
diff --git a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/FilterBuilder.cs b/backend/src/Squidex.Infrastructure.Azure/EventSourcing/FilterBuilder.cs
deleted file mode 100644
index f24d50f8c..000000000
--- a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/FilterBuilder.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-// ==========================================================================
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex UG (haftungsbeschraenkt)
-// All rights reserved. Licensed under the MIT license.
-// ==========================================================================
-
-using System.Collections.Generic;
-using Microsoft.Azure.Documents;
-
-namespace Squidex.Infrastructure.EventSourcing
-{
- internal static class FilterBuilder
- {
- public static SqlQuerySpec AllIds(string streamName)
- {
- var query =
- $"SELECT TOP 1 " +
- $" e.id," +
- $" e.eventsCount " +
- $"FROM {Constants.Collection} e " +
- $"WHERE " +
- $" e.eventStream = @name " +
- $"ORDER BY e.eventStreamOffset DESC";
-
- var parameters = new SqlParameterCollection
- {
- new SqlParameter("@name", streamName)
- };
-
- return new SqlQuerySpec(query, parameters);
- }
-
- public static SqlQuerySpec LastPosition(string streamName)
- {
- var query =
- $"SELECT TOP 1 " +
- $" e.eventStreamOffset," +
- $" e.eventsCount " +
- $"FROM {Constants.Collection} e " +
- $"WHERE " +
- $" e.eventStream = @name " +
- $"ORDER BY e.eventStreamOffset DESC";
-
- var parameters = new SqlParameterCollection
- {
- new SqlParameter("@name", streamName)
- };
-
- return new SqlQuerySpec(query, parameters);
- }
-
- public static SqlQuerySpec ByStreamName(string streamName, long streamPosition = 0)
- {
- var query =
- $"SELECT * " +
- $"FROM {Constants.Collection} e " +
- $"WHERE " +
- $" e.eventStream = @name " +
- $"AND e.eventStreamOffset >= @position " +
- $"ORDER BY e.eventStreamOffset ASC";
-
- var parameters = new SqlParameterCollection
- {
- new SqlParameter("@name", streamName),
- new SqlParameter("@position", streamPosition)
- };
-
- return new SqlQuerySpec(query, parameters);
- }
-
- public static SqlQuerySpec ByStreamNameDesc(string streamName, long take)
- {
- var query =
- $"SELECT TOP {take}* " +
- $"FROM {Constants.Collection} e " +
- $"WHERE " +
- $" e.eventStream = @name " +
- $"ORDER BY e.eventStreamOffset DESC";
-
- var parameters = new SqlParameterCollection
- {
- new SqlParameter("@name", streamName)
- };
-
- return new SqlQuerySpec(query, parameters);
- }
-
- public static SqlQuerySpec CreateByFilter(string? streamFilter, StreamPosition streamPosition, string sortOrder, long take)
- {
- var filters = new List();
-
- var parameters = new SqlParameterCollection();
-
- filters.ForPosition(parameters, streamPosition);
- filters.ForRegex(parameters, streamFilter);
-
- return BuildQuery(filters, parameters, sortOrder, take);
- }
-
- private static SqlQuerySpec BuildQuery(IEnumerable filters, SqlParameterCollection parameters, string sortOrder, long take)
- {
- var query = $"SELECT TOP {take} * FROM {Constants.Collection} e WHERE {string.Join(" AND ", filters)} ORDER BY e.timestamp {sortOrder}";
-
- return new SqlQuerySpec(query, parameters);
- }
-
- private static void ForRegex(this ICollection filters, SqlParameterCollection parameters, string? streamFilter)
- {
- if (!StreamFilter.IsAll(streamFilter))
- {
- if (streamFilter.Contains("^"))
- {
- filters.Add("STARTSWITH(e.eventStream, @filter)");
- }
- else
- {
- filters.Add("e.eventStream = @filter");
- }
-
- parameters.Add(new SqlParameter("@filter", streamFilter));
- }
- }
-
- private static void ForPosition(this ICollection filters, SqlParameterCollection parameters, StreamPosition streamPosition)
- {
- if (streamPosition.IsEndOfCommit)
- {
- filters.Add("e.timestamp > @time");
- }
- else
- {
- filters.Add("e.timestamp >= @time");
- }
-
- parameters.Add(new SqlParameter("@time", streamPosition.Timestamp));
- }
- }
-}
diff --git a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/FilterExtensions.cs b/backend/src/Squidex.Infrastructure.Azure/EventSourcing/FilterExtensions.cs
deleted file mode 100644
index 012baf0b6..000000000
--- a/backend/src/Squidex.Infrastructure.Azure/EventSourcing/FilterExtensions.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-// ==========================================================================
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex UG (haftungsbeschraenkt)
-// All rights reserved. Licensed under the MIT license.
-// ==========================================================================
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Azure.Documents;
-using Microsoft.Azure.Documents.Client;
-using Microsoft.Azure.Documents.Linq;
-
-namespace Squidex.Infrastructure.EventSourcing
-{
- internal static class FilterExtensions
- {
- private static readonly FeedOptions CrossPartition = new FeedOptions
- {
- EnableCrossPartitionQuery = true
- };
-
- public static async Task FirstOrDefaultAsync(this IQueryable queryable,
- CancellationToken ct = default)
- {
- var documentQuery = queryable.AsDocumentQuery();
-
- using (documentQuery)
- {
- if (documentQuery.HasMoreResults)
- {
- var results = await documentQuery.ExecuteNextAsync(ct);
-
- return results.FirstOrDefault();
- }
- }
-
- return default!;
- }
-
- public static async IAsyncEnumerable QueryAsync(this DocumentClient documentClient, Uri collectionUri, SqlQuerySpec querySpec,
- [EnumeratorCancellation] CancellationToken ct = default)
- {
- var query = documentClient.CreateDocumentQuery(collectionUri, querySpec, CrossPartition);
-
- var documentQuery = query.AsDocumentQuery();
-
- using (documentQuery)
- {
- while (documentQuery.HasMoreResults && !ct.IsCancellationRequested)
- {
- var items = await documentQuery.ExecuteNextAsync(ct);
-
- foreach (var item in items)
- {
- yield return item;
- }
- }
- }
- }
-
- public static IEnumerable