diff --git a/Altinn.Authorization.sln b/Altinn.Authorization.sln
index 621f47f3..7fad1303 100644
--- a/Altinn.Authorization.sln
+++ b/Altinn.Authorization.sln
@@ -9,25 +9,25 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Altinn.Authorization.Hostin
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{6F9E4C3C-5339-452F-A22B-2072CEDDB407}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.Authorization.Hosting", "src\libs\Altinn.Authorization.Hosting\src\Altinn.Authorization.Hosting\Altinn.Authorization.Hosting.csproj", "{676C7114-4829-4760-B32B-91C396AB39D2}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.Hosting", "src\libs\Altinn.Authorization.Hosting\src\Altinn.Authorization.Hosting\Altinn.Authorization.Hosting.csproj", "{676C7114-4829-4760-B32B-91C396AB39D2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{46F86171-0313-48FC-B0F1-BC8EFE8109D6}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.Authorization.Hosting.Tests", "src\libs\Altinn.Authorization.Hosting\tests\Altinn.Authorization.Hosting.Tests\Altinn.Authorization.Hosting.Tests.csproj", "{7724C311-DBD5-4E8B-BDA3-C8B910CCF8C6}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.Hosting.Tests", "src\libs\Altinn.Authorization.Hosting\tests\Altinn.Authorization.Hosting.Tests\Altinn.Authorization.Hosting.Tests.csproj", "{7724C311-DBD5-4E8B-BDA3-C8B910CCF8C6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Altinn.Authorization.Configuration", "Altinn.Authorization.Configuration", "{57F7EADB-D618-4D20-9751-9E953CB25573}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{47DBC3CF-755F-49C9-BB0C-0499937A43D1}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.Authorization.Configuration", "src\libs\Altinn.Authorization.Configuration\src\Altinn.Authorization.Configuration\Altinn.Authorization.Configuration.csproj", "{D9C86932-3DF0-442C-9E16-01B5EAE3F7F4}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.Configuration", "src\libs\Altinn.Authorization.Configuration\src\Altinn.Authorization.Configuration\Altinn.Authorization.Configuration.csproj", "{D9C86932-3DF0-442C-9E16-01B5EAE3F7F4}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.Authorization.Configuration.OpenTelemetry", "src\libs\Altinn.Authorization.Configuration\src\Altinn.Authorization.Configuration.OpenTelemetry\Altinn.Authorization.Configuration.OpenTelemetry.csproj", "{EE4433FE-68B9-4F09-96AF-567A4A6701FF}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.Configuration.OpenTelemetry", "src\libs\Altinn.Authorization.Configuration\src\Altinn.Authorization.Configuration.OpenTelemetry\Altinn.Authorization.Configuration.OpenTelemetry.csproj", "{EE4433FE-68B9-4F09-96AF-567A4A6701FF}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.Authorization.Configuration.Postgres", "src\libs\Altinn.Authorization.Configuration\src\Altinn.Authorization.Configuration.Postgres\Altinn.Authorization.Configuration.Postgres.csproj", "{BADE7097-AFD5-4096-9378-3CCDB0EC95B9}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.Configuration.Postgres", "src\libs\Altinn.Authorization.Configuration\src\Altinn.Authorization.Configuration.Postgres\Altinn.Authorization.Configuration.Postgres.csproj", "{BADE7097-AFD5-4096-9378-3CCDB0EC95B9}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{DCA1F893-53AA-4C9E-9794-215F901E0B61}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.Authorization.Configuration.Tests", "src\libs\Altinn.Authorization.Configuration\tests\Altinn.Authorization.Configuration.Tests\Altinn.Authorization.Configuration.Tests.csproj", "{66B2E84E-FF2C-4503-9081-5093928CD20C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.Configuration.Tests", "src\libs\Altinn.Authorization.Configuration\tests\Altinn.Authorization.Configuration.Tests\Altinn.Authorization.Configuration.Tests.csproj", "{66B2E84E-FF2C-4503-9081-5093928CD20C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "apps", "apps", "{15B73811-7124-43E0-9DAF-895121B12EBA}"
EndProject
@@ -35,19 +35,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Altinn.Authorization.Index"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{50EE64F2-349A-46A5-87EB-282BAAE0DA63}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.Authorization.Index", "src\apps\Altinn.Authorization.Index\src\Altinn.Authorization.Index\Altinn.Authorization.Index.csproj", "{8D1DB300-7C01-45BF-B677-8C402A2E1B65}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.Index", "src\apps\Altinn.Authorization.Index\src\Altinn.Authorization.Index\Altinn.Authorization.Index.csproj", "{8D1DB300-7C01-45BF-B677-8C402A2E1B65}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Altinn.Authorization.AccessPackages", "Altinn.Authorization.AccessPackages", "{7EB60BDC-609B-4A73-9765-F4B9BFADB007}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C38C05DD-A87C-4166-8D30-58E9305E1FB1}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.Authorization.AccessPackages", "src\apps\Altinn.Authorization.AccessPackages\src\Altinn.Authorization.AccessPackages\Altinn.Authorization.AccessPackages.csproj", "{3E719CAF-CE38-4412-B372-D73FFA3DFADE}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.Authorization.AccessPackages.Models", "src\apps\Altinn.Authorization.AccessPackages\src\Altinn.Authorization.AccessPackages.Models\Altinn.Authorization.AccessPackages.Models.csproj", "{AF91ACE5-6AE2-47B2-9BD1-064064AA910A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.AccessPackages", "src\apps\Altinn.Authorization.AccessPackages\src\Altinn.Authorization.AccessPackages\Altinn.Authorization.AccessPackages.csproj", "{3E719CAF-CE38-4412-B372-D73FFA3DFADE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Altinn.Authorization.DeployApi", "Altinn.Authorization.DeployApi", "{400D49D3-87B7-4960-B553-C8693CDB5755}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.Authorization.DeployApi", "src\apps\Altinn.Authorization.DeployApi\src\Altinn.Authorization.DeployApi\Altinn.Authorization.DeployApi.csproj", "{3238A95C-CC93-4E46-B11F-EADABDD1D17B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.DeployApi", "src\apps\Altinn.Authorization.DeployApi\src\Altinn.Authorization.DeployApi\Altinn.Authorization.DeployApi.csproj", "{3238A95C-CC93-4E46-B11F-EADABDD1D17B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -87,10 +85,6 @@ Global
{3E719CAF-CE38-4412-B372-D73FFA3DFADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E719CAF-CE38-4412-B372-D73FFA3DFADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E719CAF-CE38-4412-B372-D73FFA3DFADE}.Release|Any CPU.Build.0 = Release|Any CPU
- {AF91ACE5-6AE2-47B2-9BD1-064064AA910A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {AF91ACE5-6AE2-47B2-9BD1-064064AA910A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {AF91ACE5-6AE2-47B2-9BD1-064064AA910A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {AF91ACE5-6AE2-47B2-9BD1-064064AA910A}.Release|Any CPU.Build.0 = Release|Any CPU
{3238A95C-CC93-4E46-B11F-EADABDD1D17B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3238A95C-CC93-4E46-B11F-EADABDD1D17B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3238A95C-CC93-4E46-B11F-EADABDD1D17B}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -118,7 +112,6 @@ Global
{7EB60BDC-609B-4A73-9765-F4B9BFADB007} = {15B73811-7124-43E0-9DAF-895121B12EBA}
{C38C05DD-A87C-4166-8D30-58E9305E1FB1} = {7EB60BDC-609B-4A73-9765-F4B9BFADB007}
{3E719CAF-CE38-4412-B372-D73FFA3DFADE} = {C38C05DD-A87C-4166-8D30-58E9305E1FB1}
- {AF91ACE5-6AE2-47B2-9BD1-064064AA910A} = {C38C05DD-A87C-4166-8D30-58E9305E1FB1}
{400D49D3-87B7-4960-B553-C8693CDB5755} = {15B73811-7124-43E0-9DAF-895121B12EBA}
{3238A95C-CC93-4E46-B11F-EADABDD1D17B} = {400D49D3-87B7-4960-B553-C8693CDB5755}
EndGlobalSection
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index 6aeb1641..b61f431a 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -10,11 +10,16 @@
+
+
+
+
-
+
+
@@ -23,13 +28,14 @@
-
+
+
-
+
@@ -37,18 +43,20 @@
-
+
+
-
+
+
-
+
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/AccessPackages.Aspire.csproj b/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/AccessPackages.Aspire.csproj
new file mode 100644
index 00000000..a289ae62
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/AccessPackages.Aspire.csproj
@@ -0,0 +1,23 @@
+
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+ true
+ 2163e793-201c-46c9-9d8f-a586a3aaf7b5
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/Program.cs b/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/Program.cs
new file mode 100644
index 00000000..f63c4435
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/Program.cs
@@ -0,0 +1,13 @@
+using Projects;
+
+var builder = DistributedApplication.CreateBuilder(args);
+
+builder.AddProject("cli");
+builder.AddProject("api");
+builder.AddProject("web");
+
+/*
+builder.AddProject("brreg");
+*/
+
+builder.Build().Run();
diff --git a/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/Properties/launchSettings.json b/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/Properties/launchSettings.json
new file mode 100644
index 00000000..8b1da8d2
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/Properties/launchSettings.json
@@ -0,0 +1,29 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "https": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "https://localhost:17031;http://localhost:15251",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "DOTNET_ENVIRONMENT": "Development",
+ "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21039",
+ "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22174"
+ }
+ },
+ "http": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "http://localhost:15251",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "DOTNET_ENVIRONMENT": "Development",
+ "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19065",
+ "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20170"
+ }
+ }
+ }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/appsettings.Development.json b/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/appsettings.Development.json
new file mode 100644
index 00000000..0c208ae9
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/appsettings.json b/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/appsettings.json
new file mode 100644
index 00000000..31c092aa
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/AccessPackages.Aspire/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning",
+ "Aspire.Hosting.Dcp": "Warning"
+ }
+ }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/Altinn.Authorization.AccessPackages.sln b/src/apps/Altinn.Authorization.AccessPackages/Altinn.Authorization.AccessPackages.sln
index 3e839456..077b4c5c 100644
--- a/src/apps/Altinn.Authorization.AccessPackages/Altinn.Authorization.AccessPackages.sln
+++ b/src/apps/Altinn.Authorization.AccessPackages/Altinn.Authorization.AccessPackages.sln
@@ -5,30 +5,82 @@ VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9287E06E-BAF1-4F4B-B795-0B53B745DA50}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.Authorization.AccessPackages", "src\Altinn.Authorization.AccessPackages\Altinn.Authorization.AccessPackages.csproj", "{ABF49F87-89DB-4EE2-9941-A1FCFD5DE7FF}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.AccessPackages.Common", "src\Altinn.Authorization.AccessPackages.Common\Altinn.Authorization.AccessPackages.Common.csproj", "{88E1FB4F-863D-479E-9AF7-E11B2E896BD4}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.Authorization.AccessPackages.Models", "src\Altinn.Authorization.AccessPackages.Models\Altinn.Authorization.AccessPackages.Models.csproj", "{B19D6F9C-4F08-41B8-AE2D-DF9F9F2A43C1}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.AccessPackages.DbAccess", "src\Altinn.Authorization.AccessPackages.DbAccess\Altinn.Authorization.AccessPackages.DbAccess.csproj", "{5630D7FB-7DF6-4803-A828-A02CC21974E5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.AccessPackages.Repo", "src\Altinn.Authorization.AccessPackages.Repo\Altinn.Authorization.AccessPackages.Repo.csproj", "{A187084E-5459-45D1-A897-56FEEEAD5879}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.AccessPackages.CLI", "src\Altinn.Authorization.AccessPackages.CLI\Altinn.Authorization.AccessPackages.CLI.csproj", "{B67A1BE1-FC3E-48A6-841D-474F27B7296F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.AccessPackages", "src\Altinn.Authorization.AccessPackages\Altinn.Authorization.AccessPackages.csproj", "{F8894253-1209-4076-ADDC-598AFFF69D12}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Styx", "..\..\..\..\..\poc\Styx\Styx\Styx.csproj", "{C8F95A18-0794-46B9-8C84-8A9138274334}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.FFB", "src\Altinn.Authorization.AccessPackages.FFB\Altinn.Authorization.FFB.csproj", "{D11A8DD1-692C-46D6-9C7A-0E2A5B468ED5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Authorization.Importers.BRREG", "src\Altinn.Authorization.Importers.BRREG\Altinn.Authorization.Importers.BRREG.csproj", "{FA0ECB21-12E4-4299-88A0-72D4EB5A2B86}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AccessPackages.Aspire", "AccessPackages.Aspire\AccessPackages.Aspire.csproj", "{3758A91B-C5D8-4263-B292-5E099B8F8063}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {88E1FB4F-863D-479E-9AF7-E11B2E896BD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {88E1FB4F-863D-479E-9AF7-E11B2E896BD4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {88E1FB4F-863D-479E-9AF7-E11B2E896BD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {88E1FB4F-863D-479E-9AF7-E11B2E896BD4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5630D7FB-7DF6-4803-A828-A02CC21974E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5630D7FB-7DF6-4803-A828-A02CC21974E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5630D7FB-7DF6-4803-A828-A02CC21974E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5630D7FB-7DF6-4803-A828-A02CC21974E5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A187084E-5459-45D1-A897-56FEEEAD5879}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A187084E-5459-45D1-A897-56FEEEAD5879}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A187084E-5459-45D1-A897-56FEEEAD5879}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A187084E-5459-45D1-A897-56FEEEAD5879}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B67A1BE1-FC3E-48A6-841D-474F27B7296F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B67A1BE1-FC3E-48A6-841D-474F27B7296F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B67A1BE1-FC3E-48A6-841D-474F27B7296F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B67A1BE1-FC3E-48A6-841D-474F27B7296F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F8894253-1209-4076-ADDC-598AFFF69D12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F8894253-1209-4076-ADDC-598AFFF69D12}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F8894253-1209-4076-ADDC-598AFFF69D12}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F8894253-1209-4076-ADDC-598AFFF69D12}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C8F95A18-0794-46B9-8C84-8A9138274334}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C8F95A18-0794-46B9-8C84-8A9138274334}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C8F95A18-0794-46B9-8C84-8A9138274334}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C8F95A18-0794-46B9-8C84-8A9138274334}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D11A8DD1-692C-46D6-9C7A-0E2A5B468ED5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D11A8DD1-692C-46D6-9C7A-0E2A5B468ED5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D11A8DD1-692C-46D6-9C7A-0E2A5B468ED5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D11A8DD1-692C-46D6-9C7A-0E2A5B468ED5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FA0ECB21-12E4-4299-88A0-72D4EB5A2B86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FA0ECB21-12E4-4299-88A0-72D4EB5A2B86}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FA0ECB21-12E4-4299-88A0-72D4EB5A2B86}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FA0ECB21-12E4-4299-88A0-72D4EB5A2B86}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3758A91B-C5D8-4263-B292-5E099B8F8063}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3758A91B-C5D8-4263-B292-5E099B8F8063}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3758A91B-C5D8-4263-B292-5E099B8F8063}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3758A91B-C5D8-4263-B292-5E099B8F8063}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {ABF49F87-89DB-4EE2-9941-A1FCFD5DE7FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {ABF49F87-89DB-4EE2-9941-A1FCFD5DE7FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {ABF49F87-89DB-4EE2-9941-A1FCFD5DE7FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {ABF49F87-89DB-4EE2-9941-A1FCFD5DE7FF}.Release|Any CPU.Build.0 = Release|Any CPU
- {B19D6F9C-4F08-41B8-AE2D-DF9F9F2A43C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B19D6F9C-4F08-41B8-AE2D-DF9F9F2A43C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B19D6F9C-4F08-41B8-AE2D-DF9F9F2A43C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B19D6F9C-4F08-41B8-AE2D-DF9F9F2A43C1}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {ABF49F87-89DB-4EE2-9941-A1FCFD5DE7FF} = {9287E06E-BAF1-4F4B-B795-0B53B745DA50}
- {B19D6F9C-4F08-41B8-AE2D-DF9F9F2A43C1} = {9287E06E-BAF1-4F4B-B795-0B53B745DA50}
+ {88E1FB4F-863D-479E-9AF7-E11B2E896BD4} = {9287E06E-BAF1-4F4B-B795-0B53B745DA50}
+ {5630D7FB-7DF6-4803-A828-A02CC21974E5} = {9287E06E-BAF1-4F4B-B795-0B53B745DA50}
+ {A187084E-5459-45D1-A897-56FEEEAD5879} = {9287E06E-BAF1-4F4B-B795-0B53B745DA50}
+ {B67A1BE1-FC3E-48A6-841D-474F27B7296F} = {9287E06E-BAF1-4F4B-B795-0B53B745DA50}
+ {F8894253-1209-4076-ADDC-598AFFF69D12} = {9287E06E-BAF1-4F4B-B795-0B53B745DA50}
+ {C8F95A18-0794-46B9-8C84-8A9138274334} = {9287E06E-BAF1-4F4B-B795-0B53B745DA50}
+ {D11A8DD1-692C-46D6-9C7A-0E2A5B468ED5} = {9287E06E-BAF1-4F4B-B795-0B53B745DA50}
+ {FA0ECB21-12E4-4299-88A0-72D4EB5A2B86} = {9287E06E-BAF1-4F4B-B795-0B53B745DA50}
+ {3758A91B-C5D8-4263-B292-5E099B8F8063} = {9287E06E-BAF1-4F4B-B795-0B53B745DA50}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {5EBE6D29-F6B8-4EE6-9C6C-A70E98E65748}
EndGlobalSection
EndGlobal
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.CLI/Altinn.Authorization.AccessPackages.CLI.csproj b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.CLI/Altinn.Authorization.AccessPackages.CLI.csproj
new file mode 100644
index 00000000..295fb734
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.CLI/Altinn.Authorization.AccessPackages.CLI.csproj
@@ -0,0 +1,23 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.CLI/Class1.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.CLI/Class1.cs
new file mode 100644
index 00000000..9bcf71fa
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.CLI/Class1.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Altinn.Authorization.AccessPackages.CLI;
+
+public static class Telemetry
+{
+ public static ActivitySource Source = new ActivitySource("Altinn.Authorization.AccessPackages.CLI", "1.0.0");
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.CLI/Program.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.CLI/Program.cs
new file mode 100644
index 00000000..8126094b
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.CLI/Program.cs
@@ -0,0 +1,106 @@
+using Altinn.Authorization.AccessPackages.CLI;
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+using Altinn.Authorization.AccessPackages.DbAccess.Ingest.Models;
+using Altinn.Authorization.AccessPackages.DbAccess.Migrate.Models;
+using Altinn.Authorization.AccessPackages.Repo.Data.Contracts;
+using Altinn.Authorization.AccessPackages.Repo.Extensions;
+using Altinn.Authorization.Importers.BRREG;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using OpenTelemetry;
+using OpenTelemetry.Logs;
+using OpenTelemetry.Resources;
+using OpenTelemetry.Trace;
+
+
+
+HostApplicationBuilder builder = Host.CreateApplicationBuilder();
+builder.Configuration.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
+
+builder.Services.AddLogging();
+
+builder.Services.Configure(builder.Configuration.GetRequiredSection("DbObjDefConfig"));
+builder.Services.AddSingleton();
+
+builder.Services.Configure(builder.Configuration.GetSection("DbMigration"));
+builder.Services.AddDbAccessMigrations();
+
+builder.Services.Configure(builder.Configuration.GetSection("JsonIngest"));
+builder.Services.AddDbAccessIngests();
+
+builder.Services.AddDbAccessData();
+
+builder.Services.AddSingleton();
+builder.Services.AddSingleton();
+
+var host = builder.Build();
+
+using var tracerProvider = Sdk.CreateTracerProviderBuilder()
+ .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("AccessPackages", serviceInstanceId: "cli"))
+ .AddSource("Altinn.Authorization.AccessPackages.Repo")
+ .AddOtlpExporter()
+ .Build();
+
+using var tracerProvider2 = Sdk.CreateTracerProviderBuilder()
+ .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("DbAccess", serviceInstanceId: "cli"))
+ .AddSource("Altinn.Authorization.DbAccess")
+ .AddOtlpExporter()
+ .Build();
+
+var definitions = host.Services.GetRequiredService();
+definitions.SetDatabaseDefinitions();
+
+await host.Services.UseDbAccessMigrations();
+await host.Services.UseDbAccessIngests();
+
+var ingestor = host.Services.GetRequiredService();
+//await ingestor.IngestAll();
+
+//var importer = host.Services.GetRequiredService();
+/*
+await importer.ImportUnit();
+await importer.ImportSubUnit();
+await importer.ImportRoles();
+importer.WriteChangeRefsToConsole();
+*/
+
+/* Testing stuff */
+
+using var a = Telemetry.Source.StartActivity();
+a?.AddEvent(new System.Diagnostics.ActivityEvent("dfdfdf"));
+
+var providerService = host.Services.GetRequiredService();
+var res = await providerService.Get();
+foreach (var item in res)
+{
+ Console.WriteLine(item.Name);
+}
+
+
+/*
+// Test Provider
+var providerService = host.Services.GetRequiredService();
+var providerResult = await providerService.Repo.Get(requestOption);
+foreach (var item in providerResult)
+{
+ Console.WriteLine($"{item.Id}:{item.Name}");
+}
+
+// Test Variant
+var variantService = host.Services.GetRequiredService();
+var variantResult = await variantService.Repo.Get(requestOption);
+foreach (var item in variantResult)
+{
+ Console.WriteLine($"{item.Id}:{item.Name}");
+}
+
+// Test Package
+var packageService = host.Services.GetRequiredService();
+var packageResult = await packageService.Repo.Get(requestOption);
+foreach (var item in packageResult)
+{
+ Console.WriteLine($"{item.Id}:{item.Name}");
+}
+*/
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.CLI/appsettings.json b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.CLI/appsettings.json
new file mode 100644
index 00000000..7ccfe3a0
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.CLI/appsettings.json
@@ -0,0 +1,41 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*",
+ "DbObjDefConfig": {
+ "BaseSchema": "dbo",
+ "TranslationSchema": "translation",
+ "HistorySchema": "history",
+ "TranslateObjects": [
+ "Area",
+ "AreaGroup",
+ "EntityType",
+ "Package",
+ "Role",
+ "Tag",
+ "TagGroup"
+ ],
+ "HistoryObjects": [""]
+ },
+ "DataService": {
+ "ConnectionString": "Database=wiggin02;Host=localhost;Username=wigg;Password=jw8s0F4;Include Error Detail=true"
+ },
+ "DbMigration": {
+ "ConnectionString": "Database=wiggin02;Host=localhost;Username=wigg;Password=jw8s0F4;Include Error Detail=true",
+ "CollectionId": "AccessPackages",
+ "DefaultSchema": "dbo",
+ "TranslationSchema": "translation",
+ "HistorySchema": "history"
+ },
+ "JsonIngest": {
+ "BasePath": "..\\Altinn.Authorization.AccessPackages.Repo\\Ingest\\JsonData\\",
+ "Languages": [
+ "nno",
+ "eng"
+ ]
+ }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Altinn.Authorization.AccessPackages.Common.csproj b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Altinn.Authorization.AccessPackages.Common.csproj
new file mode 100644
index 00000000..029b5c61
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Altinn.Authorization.AccessPackages.Common.csproj
@@ -0,0 +1,10 @@
+
+
+
+ net8.0
+ enable
+ enable
+ SA1122;SA1516;8618
+
+
+
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Area.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Area.cs
new file mode 100644
index 00000000..0b9a70c1
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Area.cs
@@ -0,0 +1,43 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// Area to organize accesspackages stuff
+///
+public class Area
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// Name
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Description
+ ///
+ public string Description { get; set; }
+
+ ///
+ /// IconName
+ ///
+ public string IconName { get; set; }
+
+ ///
+ /// GroupId
+ ///
+ public Guid GroupId { get; set; }
+}
+
+///
+/// Extended Area
+///
+public class ExtArea : Area
+{
+ ///
+ /// Group
+ ///
+ public AreaGroup Group { get; set; }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/AreaGroup.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/AreaGroup.cs
new file mode 100644
index 00000000..c5e4a818
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/AreaGroup.cs
@@ -0,0 +1,22 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// For grouping of Areas
+///
+public class AreaGroup
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// Name
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Description
+ ///
+ public string Description { get; set; }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Entity.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Entity.cs
new file mode 100644
index 00000000..a22ad8a4
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Entity.cs
@@ -0,0 +1,48 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// Entity
+///
+public class Entity
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// TypeId
+ ///
+ public Guid TypeId { get; set; }
+
+ ///
+ /// VariantId
+ ///
+ public Guid VariantId { get; set; }
+
+ ///
+ /// Name
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// RefId
+ ///
+ public string RefId { get; set; }
+}
+
+///
+/// Extended Entity
+///
+public class ExtEntity : Entity
+{
+ ///
+ /// Type
+ ///
+ public EntityType Type { get; set; }
+
+ ///
+ /// Variant
+ ///
+ public EntityVariant Variant { get; set; }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/EntityType.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/EntityType.cs
new file mode 100644
index 00000000..350342b1
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/EntityType.cs
@@ -0,0 +1,33 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// EntityType
+///
+public class EntityType
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// ProviderId
+ ///
+ public Guid ProviderId { get; set; }
+
+ ///
+ /// Name
+ ///
+ public string Name { get; set; }
+}
+
+///
+/// Extended EntityType
+///
+public class ExtEntityType : EntityType
+{
+ ///
+ /// Provider
+ ///
+ public Provider Provider { get; set; }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/EntityVariant.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/EntityVariant.cs
new file mode 100644
index 00000000..60237143
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/EntityVariant.cs
@@ -0,0 +1,38 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// EntityVariant
+///
+public class EntityVariant
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// TypeId
+ ///
+ public Guid TypeId { get; set; }
+
+ ///
+ /// Name
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Description
+ ///
+ public string Description { get; set; }
+}
+
+///
+/// Extended EntityVariant
+///
+public class ExtEntityVariant : EntityVariant
+{
+ ///
+ /// Type
+ ///
+ public EntityType Type { get; set; }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/EntityVariantRole.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/EntityVariantRole.cs
new file mode 100644
index 00000000..500730ed
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/EntityVariantRole.cs
@@ -0,0 +1,38 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// EntityVariantRole
+///
+public class EntityVariantRole
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// VariantId
+ ///
+ public Guid VariantId { get; set; }
+
+ ///
+ /// RoleId
+ ///
+ public Guid RoleId { get; set; }
+}
+
+///
+/// Extended EntityVariantRole
+///
+public class ExtEntityVariantRole : EntityVariantRole
+{
+ ///
+ /// Variant
+ ///
+ public EntityVariant Variant { get; set; }
+
+ ///
+ /// Role
+ ///
+ public Role Role { get; set; }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Package.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Package.cs
new file mode 100644
index 00000000..3d1f0fca
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Package.cs
@@ -0,0 +1,87 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// Package
+///
+public class Package
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// ProviderId
+ ///
+ public Guid ProviderId { get; set; }
+
+ ///
+ /// EntityTypeId
+ ///
+ public Guid EntityTypeId { get; set; }
+
+ ///
+ /// AreaId
+ ///
+ public Guid AreaId { get; set; }
+
+ ///
+ /// Name
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Description
+ ///
+ public string Description { get; set; }
+
+ ///
+ /// IsDelegable
+ ///
+ public bool IsDelegable { get; set; }
+}
+
+///
+/// Extended Package
+///
+public class ExtPackage : Package
+{
+ ///
+ /// Provider
+ ///
+ public Provider Provider { get; set; }
+
+ ///
+ /// EntityType
+ ///
+ public EntityType EntityType { get; set; }
+
+ ///
+ /// Area
+ ///
+ public Area Area { get; set; }
+}
+
+public class Meta
+{
+ public Guid Id { get; set; }
+ public string Title { get; set; }
+ public string Ingress { get; set; }
+ public string Body { get; set; }
+}
+
+public class MetaSection
+{
+ public Guid Id { get; set; }
+ public Guid MetaId { get; set; }
+ public string Title { get; set; }
+ public string Body { get; set; }
+}
+
+public class MetaLink
+{
+ public Guid Id { get; set; }
+ public Guid MetaId { get; set; }
+ public string Title { get; set; }
+ public string Body { get; set; }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/PackageDelegation.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/PackageDelegation.cs
new file mode 100644
index 00000000..c994756d
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/PackageDelegation.cs
@@ -0,0 +1,58 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// PackageDelegation
+///
+public class PackageDelegation
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// PackageId
+ ///
+ public Guid PackageId { get; set; }
+
+ ///
+ /// ForId
+ ///
+ public Guid ForId { get; set; }
+
+ ///
+ /// ToId
+ ///
+ public Guid ToId { get; set; }
+
+ ///
+ /// ById
+ ///
+ public Guid ById { get; set; }
+}
+
+///
+/// Extended PackageDelegation
+///
+public class ExtPackageDelegation : PackageDelegation
+{
+ ///
+ /// Package
+ ///
+ public Package Package { get; set; }
+
+ ///
+ /// For (Entity)
+ ///
+ public Entity For { get; set; }
+
+ ///
+ /// To (Entity)
+ ///
+ public Entity To { get; set; }
+
+ ///
+ /// By (Entity)
+ ///
+ public Entity By { get; set; }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/PackageResource.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/PackageResource.cs
new file mode 100644
index 00000000..e2adaa0a
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/PackageResource.cs
@@ -0,0 +1,53 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// PackageResource
+///
+public class PackageResource
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// PackageId
+ ///
+ public Guid PackageId { get; set; }
+
+ ///
+ /// ResourceId
+ ///
+ public Guid ResourceId { get; set; }
+
+ ///
+ /// Read
+ ///
+ public bool Read { get; set; }
+
+ ///
+ /// Write
+ ///
+ public bool Write { get; set; }
+
+ ///
+ /// Sign
+ ///
+ public bool Sign { get; set; }
+}
+
+///
+/// Extended PackageResource
+///
+public class ExtPackageResource : PackageResource
+{
+ ///
+ /// Package
+ ///
+ public Package Package { get; set; }
+
+ ///
+ /// Resource
+ ///
+ public Resource Resource { get; set; }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/PackageTag.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/PackageTag.cs
new file mode 100644
index 00000000..894bbcbe
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/PackageTag.cs
@@ -0,0 +1,38 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// PackageTag
+///
+public class PackageTag
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// PackageId
+ ///
+ public Guid PackageId { get; set; }
+
+ ///
+ /// TagId
+ ///
+ public Guid TagId { get; set; }
+}
+
+///
+/// Extended PackageTag
+///
+public class ExtPackageTag : PackageTag
+{
+ ///
+ /// Package
+ ///
+ public Package Package { get; set; }
+
+ ///
+ /// Tag
+ ///
+ public Tag Tag { get; set; }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Provider.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Provider.cs
new file mode 100644
index 00000000..3d1a410f
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Provider.cs
@@ -0,0 +1,17 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// Provider
+///
+public class Provider
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// Name
+ ///
+ public string Name { get; set; }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Resource.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Resource.cs
new file mode 100644
index 00000000..e866e4a8
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Resource.cs
@@ -0,0 +1,53 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// Resource
+///
+public class Resource
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// ProviderId
+ ///
+ public Guid ProviderId { get; set; }
+
+ ///
+ /// GroupId
+ ///
+ public Guid GroupId { get; set; }
+
+ ///
+ /// TypeId
+ ///
+ public Guid TypeId { get; set; }
+
+ ///
+ /// Name
+ ///
+ public string Name { get; set; }
+}
+
+///
+/// Extended Resource
+///
+public class ExtResource : Resource
+{
+ ///
+ /// Provider
+ ///
+ public Provider Provider { get; set; }
+
+ ///
+ /// Group
+ ///
+ public ResourceGroup Group { get; set; }
+
+ ///
+ /// Type
+ ///
+ public ResourceType Type { get; set; }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/ResourceGroup.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/ResourceGroup.cs
new file mode 100644
index 00000000..1d5bc548
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/ResourceGroup.cs
@@ -0,0 +1,33 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// ResourceGroup
+///
+public class ResourceGroup
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// ProviderId
+ ///
+ public Guid ProviderId { get; set; }
+
+ ///
+ /// Name
+ ///
+ public string Name { get; set; }
+}
+
+///
+/// Extended ResourceGroup
+///
+public class ExtResourceGroup : ResourceGroup
+{
+ ///
+ /// Provider
+ ///
+ public Provider Provider { get; set; }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/ResourceType.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/ResourceType.cs
new file mode 100644
index 00000000..17db048c
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/ResourceType.cs
@@ -0,0 +1,17 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// ResourceType
+///
+public class ResourceType
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// Name
+ ///
+ public string Name { get; set; }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Role.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Role.cs
new file mode 100644
index 00000000..8ea61b32
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Role.cs
@@ -0,0 +1,63 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// Role
+///
+public class Role
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// EntityTypeId
+ /// e.g Organization
+ ///
+ public Guid EntityTypeId { get; set; }
+
+ ///
+ /// ProviderId
+ ///
+ public Guid ProviderId { get; set; }
+
+ ///
+ /// Name
+ /// e.g Dagligleder
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Code
+ /// e.g DAGL
+ ///
+ public string Code { get; set; }
+
+ ///
+ /// Description
+ /// e.g The main operator of the organization
+ ///
+ public string Description { get; set; }
+
+ ///
+ /// Urn
+ /// e.g altinn:role:dagl
+ ///
+ public string Urn { get; set; }
+}
+
+///
+/// Extended Role
+///
+public class ExtRole : Role
+{
+ ///
+ /// EntityType
+ ///
+ public EntityType EntityType { get; set; }
+
+ ///
+ /// Provider
+ ///
+ public Provider Provider { get; set; }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/RoleAssignment.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/RoleAssignment.cs
new file mode 100644
index 00000000..0bfcba94
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/RoleAssignment.cs
@@ -0,0 +1,48 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// RoleAssignment
+///
+public class RoleAssignment
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// RoleId
+ ///
+ public Guid RoleId { get; set; }
+
+ ///
+ /// ForId
+ ///
+ public Guid ForId { get; set; }
+
+ ///
+ /// ToId
+ ///
+ public Guid ToId { get; set; }
+}
+
+///
+/// Extended RoleAssignment
+///
+public class ExtRoleAssignment : RoleAssignment
+{
+ ///
+ /// Role
+ ///
+ public Role Role { get; set; }
+
+ ///
+ /// For (Entity)
+ ///
+ public Entity For { get; set; }
+
+ ///
+ /// To (Entity)
+ ///
+ public Entity To { get; set; }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/RoleMap.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/RoleMap.cs
new file mode 100644
index 00000000..bac4e5ad
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/RoleMap.cs
@@ -0,0 +1,39 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// RoleMap
+/// Entities with a one roile can also get another one
+///
+public class RoleMap
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// HasRoleId
+ ///
+ public Guid HasRoleId { get; set; }
+
+ ///
+ /// GetRoleId
+ ///
+ public Guid GetRoleId { get; set; }
+}
+
+///
+/// Extended RoleMap
+///
+public class ExtRoleMap : RoleMap
+{
+ ///
+ /// HasRole (Role)
+ ///
+ public Role HasRole { get; set; }
+
+ ///
+ /// GetRole (Role)
+ ///
+ public Role GetRole { get; set; }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/RolePackage.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/RolePackage.cs
new file mode 100644
index 00000000..a16de1d1
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/RolePackage.cs
@@ -0,0 +1,60 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// RolePackage
+///
+public class RolePackage
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// RoleId
+ ///
+ public Guid RoleId { get; set; }
+
+ ///
+ /// PackageId
+ ///
+ public Guid PackageId { get; set; }
+
+ ///
+ /// EntityVariantId (optional)
+ ///
+ public Guid? EntityVariantId { get; set; }
+
+ ///
+ /// IsActor
+ /// TODO : Rename => HasAccess
+ ///
+ public bool IsActor { get; set; } // Is this the right place? Or is it Package Permission? No.... Or PackageResource?
+
+ ///
+ /// IsAdmin
+ /// TODO : Rename => CanDelegate
+ ///
+ public bool IsAdmin { get; set; } // Is this the right place?
+}
+
+///
+/// Extended RolePackage
+///
+public class ExtRolePackage : RolePackage
+{
+ ///
+ /// Role
+ ///
+ public Role Role { get; set; }
+
+ ///
+ /// Package
+ ///
+ public Package Package { get; set; }
+
+ ///
+ /// Variant (optional)
+ ///
+ public EntityVariant? EntityVariant { get; set; }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Tag.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Tag.cs
new file mode 100644
index 00000000..5c798dee
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/Tag.cs
@@ -0,0 +1,43 @@
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// Tag
+///
+public class Tag
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// GroupId
+ ///
+ public Guid? GroupId { get; set; }
+
+ ///
+ /// ParentId
+ ///
+ public Guid? ParentId { get; set; }
+
+ ///
+ /// Name
+ ///
+ public string Name { get; set; }
+}
+
+///
+/// Extended tag
+///
+public class ExtTag : Tag
+{
+ ///
+ /// Group (optional)
+ ///
+ public TagGroup? Group { get; set; }
+
+ ///
+ /// Parent (optional)
+ ///
+ public Tag? Parent { get; set; }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/TagGroup.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/TagGroup.cs
new file mode 100644
index 00000000..6d41e385
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.Common/Models/TagGroup.cs
@@ -0,0 +1,31 @@
+using System.Diagnostics.CodeAnalysis;
+
+namespace Altinn.Authorization.AccessPackages.Models;
+
+///
+/// TagGroup
+///
+public class TagGroup
+{
+ ///
+ /// Id
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// Name
+ ///
+ public string Name { get; set; }
+}
+
+///
+/// TagGroup
+///
+[Experimental("ExpandList")]
+public class ExtTagGroup : TagGroup
+{
+ ///
+ /// Tags
+ ///
+ public IEnumerable Tags { get; set; }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Altinn.Authorization.AccessPackages.DbAccess.csproj b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Altinn.Authorization.AccessPackages.DbAccess.csproj
new file mode 100644
index 00000000..8d170056
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Altinn.Authorization.AccessPackages.DbAccess.csproj
@@ -0,0 +1,24 @@
+
+
+
+ net8.0
+ enable
+ enable
+ SA1122;SA1516;CS8618;CA1860
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbBasicConverter.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbBasicConverter.cs
new file mode 100644
index 00000000..927dfa65
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbBasicConverter.cs
@@ -0,0 +1,25 @@
+using System.Data;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Contracts;
+
+///
+/// Converters for rows to objects
+///
+/// BasicType
+public interface IDbBasicConverter
+{
+ ///
+ /// Convert list of basic object from DataReader
+ ///
+ /// IDataReader
+ ///
+ List ConvertBasic(IDataReader reader);
+
+ ///
+ /// Convert single basic object from DataReader
+ ///
+ /// IDataReader
+ /// Column prefix
+ ///
+ T? ConvertSingleBasic(IDataReader reader, string prefix);
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbBasicDataService.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbBasicDataService.cs
new file mode 100644
index 00000000..564c1def
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbBasicDataService.cs
@@ -0,0 +1,145 @@
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Contracts;
+
+///
+/// Basic data service
+///
+///
+public interface IDbBasicDataService
+{
+ ///
+ /// Data repository
+ ///
+ IDbBasicRepo Repo { get; }
+
+ ///
+ /// Get all entities
+ ///
+ /// RequestOptions
+ /// CancellationToken
+ /// T representing the result of the asynchronous operation.
+ Task> Get(RequestOptions? options = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// Get single entity based on identity
+ ///
+ /// Identity
+ /// RequestOptions
+ /// CancellationToken
+ /// T representing the result of the asynchronous operation.
+ Task Get(Guid id, RequestOptions? options = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// Get Entities based on property and value
+ ///
+ /// Filter property
+ /// Filter value
+ /// RequestOptions
+ /// CancellationToken
+ /// T representing the result of the asynchronous operation.
+ Task> Get(string property, Guid value, RequestOptions? options = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// Get Entities based on property and value
+ ///
+ /// Filter property
+ /// Filter value
+ /// RequestOptions
+ /// CancellationToken
+ /// T representing the result of the asynchronous operation.
+ Task> Get(string property, int value, RequestOptions? options = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// Get Entities based on property and value
+ ///
+ /// Filter property
+ /// Filter value
+ /// RequestOptions
+ /// CancellationToken
+ /// T representing the result of the asynchronous operation.
+ Task> Get(string property, string value, RequestOptions? options = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// Get Entities based on filters
+ ///
+ /// Filters
+ /// RequestOptions
+ /// CancellationToken
+ /// T representing the result of the asynchronous operation.
+ Task> Get(Dictionary parameters, RequestOptions? options = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// Search for entities
+ ///
+ /// Term to filter on
+ /// RequestOptions
+ /// CancellationToken
+ /// T representing the result of the asynchronous operation.
+ Task> Search(string term, RequestOptions? options = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// Search for entities
+ ///
+ /// Term to filter on
+ /// RequestOptions
+ /// CancellationToken
+ /// T representing the result of the asynchronous operation.
+ Task<(IEnumerable Data, PagedResult PageInfo)> SearchPaged(string term, RequestOptions options, CancellationToken cancellationToken = default);
+
+ ///
+ /// Create entity
+ ///
+ /// Entity to create
+ /// CancellationToken
+ Task Create(T entity, CancellationToken cancellationToken = default);
+
+ ///
+ /// Create entities
+ ///
+ /// Entities to create
+ /// CancellationToken
+ Task Create(List entities, CancellationToken cancellationToken = default);
+
+ ///
+ /// Update entity
+ ///
+ /// Identity
+ /// Entity to update
+ /// CancellationToken
+ Task Update(Guid id, T entity, CancellationToken cancellationToken = default);
+
+ ///
+ /// Update single property on entity
+ ///
+ /// Identity
+ /// Property to update
+ /// Updated value
+ /// CancellationToken
+ Task Update(Guid id, string property, string value, CancellationToken cancellationToken = default);
+
+ ///
+ /// Update single property on entity
+ ///
+ /// Identity
+ /// Property to update
+ /// Updated value
+ /// CancellationToken
+ Task Update(Guid id, string property, int value, CancellationToken cancellationToken = default);
+
+ ///
+ /// Update single property on entity
+ ///
+ /// Identity
+ /// Property to update
+ /// Updated value
+ /// CancellationToken
+ Task Update(Guid id, string property, Guid value, CancellationToken cancellationToken = default);
+
+ ///
+ /// Delete entity
+ ///
+ /// Identity
+ /// CancellationToken
+ Task Delete(Guid id, CancellationToken cancellationToken = default);
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbBasicRepo.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbBasicRepo.cs
new file mode 100644
index 00000000..4fcbdd19
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbBasicRepo.cs
@@ -0,0 +1,91 @@
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+using Npgsql;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Contracts;
+
+///
+/// Basic data access
+///
+///
+public interface IDbBasicRepo
+{
+ #region NEW
+
+ ///
+ /// Get single entity based on identity
+ ///
+ /// GenericFilter
+ /// RequestOptions
+ /// CancellationToken
+ /// T representing the result of the asynchronous operation.
+ Task> Get(List? parameters = null, RequestOptions? options = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// Create entity
+ ///
+ /// Entity to create
+ /// CancellationToken
+ Task Create(T entity, CancellationToken cancellationToken = default);
+
+ ///
+ /// Update single property on entity
+ ///
+ /// Identity
+ /// GenericParameters
+ /// CancellationToken
+ Task Update(Guid id, List parameters, CancellationToken cancellationToken = default);
+
+ ///
+ /// Update entity
+ ///
+ /// Identity
+ /// Entity to update
+ /// CancellationToken
+ Task Update(Guid id, T entity, CancellationToken cancellationToken = default);
+
+ ///
+ /// Delete entity
+ ///
+ /// Identity
+ /// CancellationToken
+ Task Delete(Guid id, CancellationToken cancellationToken = default);
+
+ ///
+ /// Search for entities
+ ///
+ /// Term to filter on
+ /// RequestOptions
+ /// CancellationToken
+ /// T representing the result of the asynchronous operation.
+ Task<(IEnumerable Data, PagedResult PageInfo)> Search(string term, RequestOptions options, CancellationToken cancellationToken = default);
+ #endregion
+
+ #region OLD
+
+ ///
+ /// Ingest entities using bulk methods
+ ///
+ /// Entities to ingest
+ /// CancellationToken
+ ///
+ Task Ingest(List data, CancellationToken cancellationToken = default);
+
+ ///
+ /// Creates translation for entity
+ ///
+ /// Entity to create translation for
+ /// Languagecode (e.g nob, bbo, eng)
+ /// CancellationToken
+ Task CreateTranslation(T entity, string language, CancellationToken cancellationToken = default);
+
+ ///
+ /// Updates translation for entity
+ ///
+ /// Identity
+ /// Entity to update translation for
+ /// Languagecode (e.g nob, bbo, eng)
+ /// CancellationToken
+ Task UpdateTranslation(Guid id, T entity, string language, CancellationToken cancellationToken = default);
+
+ #endregion
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbCrossConverter.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbCrossConverter.cs
new file mode 100644
index 00000000..496806b9
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbCrossConverter.cs
@@ -0,0 +1,26 @@
+using System.Data;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Contracts;
+
+///
+/// Converters for rows to extendedobjects
+///
+/// A Table
+/// Cross join table
+/// B Table
+public interface IDbCrossConverter : IDbBasicConverter
+{
+ ///
+ /// Convert list of TA objects from DataReader
+ ///
+ /// IDataReader
+ ///
+ List ConvertA(IDataReader reader);
+
+ ///
+ /// Convert list of TB objects from DataReader
+ ///
+ /// IDataReader
+ ///
+ List ConvertB(IDataReader reader);
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbCrossDataService.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbCrossDataService.cs
new file mode 100644
index 00000000..5866b2a1
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbCrossDataService.cs
@@ -0,0 +1,33 @@
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Contracts;
+
+///
+/// Data repo interface for cross joined objects
+///
+/// TA Type
+/// Cross Type
+/// TB Type
+public interface IDbCrossDataService : IDbBasicDataService
+{
+ ///
+ /// Actual repo implementation
+ ///
+ IDbCrossRepo CrossRepo { get; }
+
+ ///
+ /// Using a cross join table to return TA objects based on TB.Id
+ ///
+ /// Identity for TB object
+ /// RequestOptions
+ ///
+ Task> GetA(Guid BId, RequestOptions? options = null);
+
+ ///
+ /// Using a cross join table to return TB objects based on TA.Id
+ ///
+ /// Identity for TA object
+ /// RequestOptions
+ ///
+ Task> GetB(Guid AId, RequestOptions? options = null);
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbCrossRepo.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbCrossRepo.cs
new file mode 100644
index 00000000..e9fd22cb
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbCrossRepo.cs
@@ -0,0 +1,37 @@
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Contracts;
+
+///
+/// Interface to retrive data from cross join tables
+///
+/// A Table
+/// Cross join table
+/// B Table
+public interface IDbCrossRepo : IDbBasicRepo
+{
+ ///
+ /// Override default column names for the cross table
+ ///
+ /// Columnname in TResult for TA
+ /// Columnname in TResult for TB
+ void SetCrossColumns(string xAColumn, string xBColumn);
+
+ ///
+ /// Using a cross join table to return TA objects based on TB.Id
+ ///
+ /// Identity for TB object
+ /// RequestOptions
+ /// CancellationToken
+ ///
+ Task> ExecuteForA(Guid BId, RequestOptions? options = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// Using a cross join table to return TB objects based on TA.Id
+ ///
+ /// Identity for TA object
+ /// RequestOptions
+ /// CancellationToken
+ ///
+ Task> ExecuteForB(Guid AId, RequestOptions? options = null, CancellationToken cancellationToken = default);
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbExtendedConverter.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbExtendedConverter.cs
new file mode 100644
index 00000000..3306dbb6
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbExtendedConverter.cs
@@ -0,0 +1,18 @@
+using System.Data;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Contracts;
+
+///
+/// Converters for rows to extendedobjects
+///
+/// BasicType
+/// ExtendedType
+public interface IDbExtendedConverter : IDbBasicConverter
+{
+ ///
+ /// Convert list of extended objects from DataReader
+ ///
+ /// IDataReader
+ ///
+ List ConvertExtended(IDataReader reader);
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbExtendedDataService.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbExtendedDataService.cs
new file mode 100644
index 00000000..b335998e
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbExtendedDataService.cs
@@ -0,0 +1,61 @@
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Contracts;
+
+///
+/// Data repo interface for extended objects
+///
+/// Base Type
+/// Extendtet Type
+public interface IDbExtendedDataService : IDbBasicDataService
+{
+ ///
+ /// Actual repo implementation
+ ///
+ IDbExtendedRepo ExtendedRepo { get; }
+
+ ///
+ /// Get all
+ ///
+ /// RequestOptions
+ Task> GetExtended(RequestOptions? options = null);
+
+ ///
+ /// Get based on property
+ ///
+ /// Filter property
+ /// Filter value
+ /// RequestOptions
+ Task> GetExtended(string property, Guid value, RequestOptions? options = null);
+
+ ///
+ /// Get based on property
+ ///
+ /// Filter property
+ /// Filter value
+ /// RequestOptions
+ Task> GetExtended(string property, int value, RequestOptions? options = null);
+
+ ///
+ /// Get based on property
+ ///
+ /// Filter property
+ /// Filter value
+ /// RequestOptions
+ Task> GetExtended(string property, string value, RequestOptions? options = null);
+
+ ///
+ /// Get based on identifer
+ ///
+ /// Identifier
+ /// RequestOptions
+ Task GetExtended(Guid id, RequestOptions? options = null);
+
+ ///
+ /// Search
+ ///
+ /// Searchterm
+ /// RequestOptions
+ /// Starts with
+ Task<(IEnumerable Data, PagedResult PageInfo)> SearchExtended(string term, RequestOptions options, bool startsWith = false);
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbExtendedRepo.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbExtendedRepo.cs
new file mode 100644
index 00000000..5aa0e26e
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Contracts/IDbExtendedRepo.cs
@@ -0,0 +1,36 @@
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Contracts;
+
+///
+/// Extended repo for extendable objects
+///
+/// BaseType (e.g EntityType)
+/// ExtendedType (e.g ExtEntityType)
+public interface IDbExtendedRepo : IDbBasicRepo
+{
+ ///
+ /// Get extended object
+ ///
+ /// GenericFilter
+ /// RequestOptions
+ Task> GetExtended(List? filters = null, RequestOptions? options = null);
+
+ ///
+ /// Search
+ ///
+ /// Searchterm
+ /// RequestOptions
+ /// Starts with
+ Task<(IEnumerable Data, PagedResult PageInfo)> SearchExtended(string term, RequestOptions options, bool startsWith = false);
+
+ ///
+ /// Adds join to configuration
+ ///
+ ///
+ /// Alias
+ /// Property on base object to join from
+ /// Property on join object to join to
+ /// Is this optional
+ void Join(string alias = "", string baseJoinProperty = "", string joinProperty = "Id", bool optional = false);
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DataTypes.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DataTypes.cs
new file mode 100644
index 00000000..ecaef7ad
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DataTypes.cs
@@ -0,0 +1,66 @@
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+///
+/// Common DataTypes
+///
+public static class DataTypes
+{
+ ///
+ /// Guid
+ ///
+ public static CommonDataType Guid => new("uniqueidentifier", "uuid");
+
+ ///
+ /// Bool
+ ///
+ public static CommonDataType Bool => new("bit", "boolean");
+
+ ///
+ /// Int
+ ///
+ public static CommonDataType Int => new("int", "int");
+
+ ///
+ /// String
+ ///
+ /// Length (default: 250)
+ ///
+ public static CommonDataType String(int length = 250) => new($"nvarchar({length})", "text");
+
+ ///
+ /// StringMax
+ ///
+ public static CommonDataType StringMax => new("nvarchar(max)", "text");
+
+ ///
+ /// DateTimeOffset
+ ///
+ public static CommonDataType DateTimeOffset => new("datetimeoffset(7)", "timestamptz");
+}
+
+///
+/// Common DataType
+///
+public readonly struct CommonDataType
+{
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// MSSQL variant
+ /// Postgres variant
+ public CommonDataType(string mssql, string postgres) : this()
+ {
+ MsSql = mssql;
+ Postgres = postgres;
+ }
+
+ ///
+ /// MSSQL variant
+ ///
+ public string Postgres { get; }
+
+ ///
+ /// Postgres variant
+ ///
+ public string MsSql { get; }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DbDefinitions.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DbDefinitions.cs
new file mode 100644
index 00000000..7b22b96f
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DbDefinitions.cs
@@ -0,0 +1,42 @@
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+///
+/// Static resource holding Database Definitions ()
+///
+public static class DbDefinitions
+{
+ private static Dictionary DbObjects { get; set; } = new Dictionary();
+
+ ///
+ /// Add a definition
+ ///
+ /// Type
+ /// DbObjDefConfig
+ public static void Add(DbObjDefConfig config)
+ {
+ if (!DbObjects.ContainsKey(typeof(T)))
+ {
+ DbObjects.Add(typeof(T), new ObjectDefinition(typeof(T), config));
+ }
+ }
+
+ ///
+ /// Gets a definition
+ ///
+ /// Type
+ ///
+ public static ObjectDefinition? Get()
+ {
+ return Get(type: typeof(T));
+ }
+
+ ///
+ /// Gets a definition
+ ///
+ /// Type
+ ///
+ public static ObjectDefinition? Get(Type type)
+ {
+ return DbObjects.ContainsKey(type) ? DbObjects.First(t => t.Key == type).Value : null;
+ }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DbObjDefConfig.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DbObjDefConfig.cs
new file mode 100644
index 00000000..9e3ab3c3
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DbObjDefConfig.cs
@@ -0,0 +1,34 @@
+using Microsoft.Extensions.Options;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+///
+/// Database Object Configuration
+///
+public class DbObjDefConfig
+{
+ ///
+ /// Base schema
+ ///
+ public string BaseSchema { get; set; }
+
+ ///
+ /// Translation schema
+ ///
+ public string TranslationSchema { get; set; }
+
+ ///
+ /// History schema
+ ///
+ public string HistorySchema { get; set; }
+
+ ///
+ /// Ovbjects with translations
+ ///
+ public List TranslateObjects { get; set; }
+
+ ///
+ /// Objects with history
+ ///
+ public List HistoryObjects { get; set; }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DbObject.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DbObject.cs
new file mode 100644
index 00000000..1cda5702
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DbObject.cs
@@ -0,0 +1,86 @@
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+///
+/// Database Object
+///
+public class DbObject
+{
+ ///
+ /// Type
+ ///
+ public Type Type { get; set; }
+
+ ///
+ /// Schema
+ ///
+ public string Schema { get; set; }
+
+ ///
+ /// Name
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Alias
+ ///
+ public string Alias { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Type
+ /// Name
+ /// Schema
+ /// Alias
+ public DbObject(Type type, string name, string schema, string alias = "")
+ {
+ Type = type;
+ Name = name;
+ Schema = schema;
+ Alias = string.IsNullOrEmpty(alias) ? name : alias;
+ }
+
+ ///
+ /// Gets Sql definition
+ ///
+ /// Include alias (default: true)
+ /// Use AsOf (default: false)
+ ///
+ public string GetSqlDefinition(bool includeAlias = true, bool useAsOf = false)
+ {
+ var res = $"[{Schema}].[{Name}]";
+ if (useAsOf)
+ {
+ res += " FOR SYSTEM_TIME AS OF @_AsOf ";
+ }
+
+ if (includeAlias)
+ {
+ res += $" AS [{Alias}]";
+ }
+
+ return res;
+ }
+
+ ///
+ /// Gets Postgres definition
+ ///
+ /// Include alias (default: true)
+ /// Use AsOf (default: false)
+ ///
+ public string GetPostgresDefinition(bool includeAlias = true, bool useAsOf = false)
+ {
+ var res = $"{Schema}.{Name}";
+ if (useAsOf)
+ {
+ Console.WriteLine("AsOf feature is not available on postgres");
+ }
+
+ if (includeAlias)
+ {
+ res += $" AS {Alias}";
+ }
+
+ return res;
+ }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DbPageResult.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DbPageResult.cs
new file mode 100644
index 00000000..64deee59
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/DbPageResult.cs
@@ -0,0 +1,18 @@
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+///
+/// DbPageResult
+/// Used to extract data from query result
+///
+public class DbPageResult
+{
+ ///
+ /// Total pages
+ ///
+ public int TotalPages { get; set; }
+
+ ///
+ /// Total items
+ ///
+ public int TotalItems { get; set; }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/GenericFilter.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/GenericFilter.cs
new file mode 100644
index 00000000..9b44b593
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/GenericFilter.cs
@@ -0,0 +1,126 @@
+using System.Data.SqlClient;
+using Npgsql;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+///
+/// Generic filter
+///
+public class GenericFilter
+{
+ ///
+ /// Key
+ ///
+ public string Key { get; set; }
+
+ ///
+ /// Comparer
+ ///
+ public DbOperator Comparer { get; set; }
+
+ ///
+ /// Value
+ ///
+ public object Value { get; set; }
+
+ ///
+ /// Constructor
+ ///
+ public GenericFilter(string key, object value, DbOperator? comparer = null)
+ {
+ Key = key;
+ Comparer = comparer ?? DbOperators.EqualTo;
+ Value = value;
+ }
+}
+
+///
+/// DbOperators
+///
+public static class DbOperators
+{
+ ///
+ /// EqualTo
+ ///
+ public static DbOperator EqualTo => new("=", "{$Key} = {$Value}");
+
+ ///
+ /// NotEqualTo
+ ///
+ public static DbOperator NotEqualTo => new("<>", "{$Key} <> {$Value}");
+
+ ///
+ /// In
+ ///
+ public static DbOperator In => new("in", "{$Key} IN({$Value})");
+
+ ///
+ /// NotIn
+ ///
+ public static DbOperator NotIn => new("not in", "{$Key} NOT IN({$Value})");
+
+ ///
+ /// Contains
+ ///
+ public static DbOperator Contains => new("like", "{$Key} LIKE '%{$}%'");
+
+ ///
+ /// NotContains
+ ///
+ public static DbOperator NotContains => new("not like", "{$Key} NOT LIKE '%{$Value}%'");
+
+ ///
+ /// StartsWith
+ ///
+ public static DbOperator StartsWith => new("like", "LIKE '{$}%'");
+
+ ///
+ /// EndsWith
+ ///
+ public static DbOperator EndsWith => new("like", "LIKE '%{$}'");
+}
+
+///
+/// DbOperator
+///
+/// Name (used for ToString override)
+/// Code
+public readonly struct DbOperator(string name, string code)
+{
+ ///
+ /// Name (used for ToString override)
+ ///
+ public string Name { get; } = name;
+
+ ///
+ /// Code
+ ///
+ public string Code { get; } = code;
+
+ ///
+ /// Returns Name
+ ///
+ ///
+ public override string ToString()
+ {
+ return Name;
+ }
+}
+
+///
+/// Generic Parameter
+///
+/// Key
+/// Value
+public class GenericParameter(string key, object value)
+{
+ ///
+ /// Key
+ ///
+ public string Key { get; set; } = key;
+
+ ///
+ /// Value
+ ///
+ public object Value { get; set; } = value;
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/Join.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/Join.cs
new file mode 100644
index 00000000..13ae3a62
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/Join.cs
@@ -0,0 +1,66 @@
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+///
+/// Join definition
+///
+public class Join
+{
+ ///
+ /// Alias
+ ///
+ public string Alias { get; set; }
+
+ ///
+ /// Join is optional
+ ///
+ public bool Optional { get; set; }
+
+ ///
+ /// DbObject that holds the refrenceId
+ /// e.g. Entity
+ ///
+ public ObjectDefinition BaseObj { get; set; }
+
+ ///
+ /// Refrence column on BaseObj
+ /// e.g. GroupId
+ ///
+ public string BaseJoinProperty { get; set; }
+
+ ///
+ /// DbObject that is refrenced
+ /// e.g. Group
+ ///
+ public ObjectDefinition JoinObj { get; set; }
+
+ ///
+ /// Column in JoinObj that is refrenced
+ /// e.g. Id
+ ///
+ public string JoinProperty { get; set; }
+
+ ///
+ /// Additional filter on for the join statement
+ /// e.g. delete is null
+ ///
+ public List Filter { get; set; } = [];
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Alias
+ /// Base objecttype
+ /// Join objecttype
+ /// Base join property
+ /// Join property
+ /// Optional
+ public Join(string alias, Type baseType, Type joinType, string baseJoinProperty = "", string joinProperty = "Id", bool optional = false)
+ {
+ BaseObj = DbDefinitions.Get(baseType) ?? throw new Exception($"Definition for '{baseType.Name}' not found");
+ JoinObj = DbDefinitions.Get(joinType) ?? throw new Exception($"Definition for '{joinType.Name}' not found");
+ Alias = alias;
+ BaseJoinProperty = string.IsNullOrEmpty(baseJoinProperty) ? alias + "Id" : baseJoinProperty;
+ JoinProperty = joinProperty;
+ Optional = optional;
+ }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/ObjectDefinition.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/ObjectDefinition.cs
new file mode 100644
index 00000000..09eb1da7
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/ObjectDefinition.cs
@@ -0,0 +1,68 @@
+using System.Reflection;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+///
+/// Database Object Definition
+///
+public class ObjectDefinition
+{
+ ///
+ /// Base object definition
+ ///
+ public DbObject BaseDbObject { get; set; }
+
+ ///
+ /// Translation object definition
+ ///
+ public DbObject TranslationDbObject { get; set; }
+
+ ///
+ /// History object definition
+ ///
+ public DbObject HistoryDbObject { get; set; }
+
+ ///
+ /// Use translation
+ ///
+ public bool UseTranslation { get; set; } = false;
+
+ ///
+ /// Use history
+ ///
+ public bool UseHistory { get; set; } = false;
+
+ ///
+ /// Properties
+ ///
+ public Dictionary Properties { get; set; }
+
+ ///
+ /// New Database Object Definition
+ ///
+ /// Type
+ /// DbObjDefConfig
+ public ObjectDefinition(Type type, DbObjDefConfig config)
+ {
+ var name = type.Name;
+ Properties = new Dictionary();
+ foreach (var property in type.GetProperties())
+ {
+ Properties.Add(property.Name, property);
+ }
+
+ BaseDbObject = new DbObject(type, name, config.BaseSchema, name);
+ TranslationDbObject = new DbObject(type, name, config.TranslationSchema, "Translation" + name);
+ HistoryDbObject = new DbObject(type, name, config.HistorySchema, "History" + name);
+
+ if (config.TranslateObjects != null && config.TranslateObjects.Contains(name))
+ {
+ UseTranslation = true;
+ }
+
+ if (config.HistoryObjects != null && config.HistoryObjects.Contains(name))
+ {
+ UseHistory = true;
+ }
+ }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/PagedResult.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/PagedResult.cs
new file mode 100644
index 00000000..ae370885
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/PagedResult.cs
@@ -0,0 +1,36 @@
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+///
+/// To be formated to HTTP Headers
+///
+public class PagedResult
+{
+ ///
+ /// Current page
+ /// Header: x-page-current
+ ///
+ public int CurrentPage { get; set; }
+
+ ///
+ /// Item count
+ /// Header: x-page-itemcount
+ ///
+ public int ItemCount { get; set; }
+
+ ///
+ /// Page size
+ /// Header: x-page-size
+ ///
+ public int PageSize { get; set; }
+
+ ///
+ /// Page count
+ /// Header: x-page-count
+ ///
+ public int PageCount { get; set; }
+
+ ///
+ /// Links
+ ///
+ public Dictionary Links { get; set; }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/RequestOptions.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/RequestOptions.cs
new file mode 100644
index 00000000..1af760c5
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Models/RequestOptions.cs
@@ -0,0 +1,37 @@
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+///
+/// RequestOptions
+///
+public class RequestOptions
+{
+ ///
+ /// Language
+ ///
+ public string Language { get; set; }
+
+ ///
+ /// AsOf
+ ///
+ public DateTimeOffset? AsOf { get; set; }
+
+ ///
+ /// OrderBy
+ ///
+ public string OrderBy { get; set; }
+
+ ///
+ /// UsePaging (default: false)
+ ///
+ public bool UsePaging { get; set; } = false;
+
+ ///
+ /// PageSize (default: 25)
+ ///
+ public int PageSize { get; set; } = 25;
+
+ ///
+ /// PageNumber (default: 1)
+ ///
+ public int PageNumber { get; set; } = 1;
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Services/BaseCrossDataService.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Services/BaseCrossDataService.cs
new file mode 100644
index 00000000..128b6f11
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Services/BaseCrossDataService.cs
@@ -0,0 +1,34 @@
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Contracts;
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Services;
+
+///
+public class BaseCrossDataService : BaseDataService, IDbCrossDataService
+{
+ ///
+ /// Cross repo
+ ///
+ public IDbCrossRepo CrossRepo { get; }
+
+ ///
+ /// Base data service
+ ///
+ /// ExtendedRepo
+ public BaseCrossDataService(IDbCrossRepo repo) : base(repo)
+ {
+ CrossRepo = repo;
+ }
+
+ ///
+ public async Task> GetA(Guid bId, RequestOptions? options = null)
+ {
+ return await CrossRepo.ExecuteForA(bId, options);
+ }
+
+ ///
+ public async Task> GetB(Guid aId, RequestOptions? options = null)
+ {
+ return await CrossRepo.ExecuteForB(aId, options);
+ }
+}
\ No newline at end of file
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Services/BaseDataService.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Services/BaseDataService.cs
new file mode 100644
index 00000000..f102a60f
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Services/BaseDataService.cs
@@ -0,0 +1,159 @@
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Contracts;
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+using Microsoft.Extensions.Logging;
+using Npgsql;
+using OpenTelemetry;
+using OpenTelemetry.Metrics;
+using OpenTelemetry.Trace;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Services;
+
+public static class Logs
+{
+ public static ILoggerFactory LoggerFactory { get; set; } = new LoggerFactory();
+
+}
+
+///
+public class BaseDataService : IDbBasicDataService
+{
+ ///
+ /// Extended repo
+ ///
+ public IDbBasicRepo Repo { get; }
+ public ILogger Logger { get; }
+
+ ///
+ /// Base data service
+ ///
+ /// ExtendedRepo
+ public BaseDataService(IDbBasicRepo repo)
+ {
+ Repo = repo;
+ Logger = Logs.LoggerFactory.CreateLogger(typeof(BaseDataService));
+ }
+
+ ///
+ public async Task> Get(RequestOptions? options = null, CancellationToken cancellationToken = default)
+ {
+ using var a = Telemetry.StartActivity("Get");
+ return await Repo.Get(parameters: new List(), options, cancellationToken: cancellationToken);
+ }
+
+ ///
+ public async Task Get(Guid id, RequestOptions? options = null, CancellationToken cancellationToken = default)
+ {
+ using var a = Telemetry.StartActivity("Get");
+ try
+ {
+ var res = await Repo.Get([new GenericFilter("Id", id)], options, cancellationToken: cancellationToken);
+ if (res != null)
+ {
+ return res.First();
+ }
+
+ return default;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ throw;
+ }
+ }
+
+ ///
+ public async Task> Get(string property, Guid value, RequestOptions? options = null, CancellationToken cancellationToken = default)
+ {
+ using var a = Telemetry.StartActivity("Get");
+ return await Repo.Get([new GenericFilter(property, value)], options, cancellationToken: cancellationToken);
+ }
+
+ ///
+ public async Task> Get(string property, int value, RequestOptions? options = null, CancellationToken cancellationToken = default)
+ {
+ using var a = Telemetry.StartActivity("Get");
+ return await Repo.Get([new GenericFilter(property, value)], options, cancellationToken: cancellationToken);
+ }
+
+ ///
+ public async Task> Get(string property, string value, RequestOptions? options = null, CancellationToken cancellationToken = default)
+ {
+ using var a = Telemetry.StartActivity("Get");
+ return await Repo.Get([new GenericFilter(property, value)], options, cancellationToken: cancellationToken);
+ }
+
+ ///
+ public async Task> Get(Dictionary parameters, RequestOptions? options = null, CancellationToken cancellationToken = default)
+ {
+ using var a = Telemetry.StartActivity("Get");
+ var param = new List();
+ foreach (var p in parameters)
+ {
+ param.Add(new GenericFilter(p.Key, p.Value));
+ }
+
+ return await Repo.Get(param, options, cancellationToken: cancellationToken);
+ }
+
+ ///
+ public async Task> Search(string term, RequestOptions? options = null, CancellationToken cancellationToken = default)
+ {
+ using var a = Telemetry.StartActivity("Search");
+ return await Repo.Get([new GenericFilter("Name", term, comparer: DbOperators.Contains)], options, cancellationToken: cancellationToken);
+ }
+
+ ///
+ public Task<(IEnumerable Data, PagedResult PageInfo)> SearchPaged(string term, RequestOptions? options = null, CancellationToken cancellationToken = default)
+ {
+ using var a = Telemetry.StartActivity("SearchPaged");
+ return Repo.Search(term, options ?? new RequestOptions(), cancellationToken);
+ }
+
+ ///
+ public async Task Create(List entities, CancellationToken cancellationToken = default)
+ {
+ int count = 0;
+ foreach (var entity in entities)
+ {
+ count += await Create(entity, cancellationToken: cancellationToken);
+ }
+
+ return count;
+ }
+
+ ///
+ public async Task Create(T entity, CancellationToken cancellationToken = default)
+ {
+ return await Repo.Create(entity, cancellationToken: cancellationToken);
+ }
+
+ ///
+ public async Task Update(Guid id, T entity, CancellationToken cancellationToken = default)
+ {
+ return await Repo.Update(id, entity, cancellationToken: cancellationToken);
+ }
+
+ ///
+ public async Task Update(Guid id, string property, Guid value, CancellationToken cancellationToken = default)
+ {
+ return await Repo.Update(id, [new GenericParameter(property, value)], cancellationToken: cancellationToken);
+ }
+
+ ///
+ public async Task Update(Guid id, string property, string value, CancellationToken cancellationToken = default)
+ {
+ return await Repo.Update(id, [new GenericParameter(property, value)], cancellationToken: cancellationToken);
+ }
+
+ ///
+ public async Task Update(Guid id, string property, int value, CancellationToken cancellationToken = default)
+ {
+ return await Repo.Update(id, [new GenericParameter(property, value)], cancellationToken: cancellationToken);
+ }
+
+ ///
+ public async Task Delete(Guid id, CancellationToken cancellationToken = default)
+ {
+ return await Repo.Delete(id, cancellationToken);
+ }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Services/BaseExtendedDataService.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Services/BaseExtendedDataService.cs
new file mode 100644
index 00000000..22eac5dd
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Services/BaseExtendedDataService.cs
@@ -0,0 +1,64 @@
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Contracts;
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Services;
+
+///
+public class BaseExtendedDataService : BaseDataService, IDbExtendedDataService
+{
+ ///
+ /// Extended repo
+ ///
+ public IDbExtendedRepo ExtendedRepo { get; }
+
+ ///
+ /// Base data service
+ ///
+ /// ExtendedRepo
+ public BaseExtendedDataService(IDbExtendedRepo repo) : base(repo)
+ {
+ ExtendedRepo = repo;
+ }
+
+ ///
+ public async Task GetExtended(Guid id, RequestOptions? options = null)
+ {
+ var result = await ExtendedRepo.GetExtended([new GenericFilter("Id", id)], options);
+ if (result != null)
+ {
+ return result.First();
+ }
+
+ throw new Exception("Not found");
+ }
+
+ ///
+ public async Task> GetExtended(RequestOptions? options = null)
+ {
+ return await ExtendedRepo.GetExtended(filters: [], options: options);
+ }
+
+ ///
+ public async Task> GetExtended(string property, string value, RequestOptions? options = null)
+ {
+ return await ExtendedRepo.GetExtended([new GenericFilter(property, value)], options);
+ }
+
+ ///
+ public async Task> GetExtended(string property, int value, RequestOptions? options = null)
+ {
+ return await ExtendedRepo.GetExtended([new GenericFilter(property, value)], options);
+ }
+
+ ///
+ public async Task> GetExtended(string property, Guid value, RequestOptions? options = null)
+ {
+ return await ExtendedRepo.GetExtended([new GenericFilter(property, value)], options);
+ }
+
+ ///
+ public async Task<(IEnumerable Data, PagedResult PageInfo)> SearchExtended(string term, RequestOptions? options = null, bool startsWith = false)
+ {
+ return await ExtendedRepo.SearchExtended(term, options ?? new RequestOptions(), startsWith);
+ }
+}
diff --git a/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Services/Mssql/SqlBasicRepo.cs b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Services/Mssql/SqlBasicRepo.cs
new file mode 100644
index 00000000..3fa239eb
--- /dev/null
+++ b/src/apps/Altinn.Authorization.AccessPackages/src/Altinn.Authorization.AccessPackages.DbAccess/Data/Services/Mssql/SqlBasicRepo.cs
@@ -0,0 +1,488 @@
+using System.Data;
+using System.Data.SqlClient;
+using System.Reflection;
+using System.Text;
+using System.Text.Json;
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Contracts;
+using Altinn.Authorization.AccessPackages.DbAccess.Data.Models;
+using FastMember;
+using Microsoft.Extensions.Configuration;
+
+namespace Altinn.Authorization.AccessPackages.DbAccess.Data.Services.Mssql;
+
+///
+/// Data Service
+///
+/// For type
+public class SqlBasicRepo : IDbBasicRepo
+ where T : class
+{
+ private readonly SqlConnection connection;
+ private readonly string connectionString;
+
+ ///
+ /// Database definition of type
+ ///
+ public ObjectDefinition DbObjDef { get; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Configuration
+ public SqlBasicRepo(IConfiguration config)
+ {
+ var configSection = config.GetRequiredSection("SqlBasicRepo");
+ connectionString = configSection["ConnectionString"] ?? throw new Exception("Missing connectionstring");
+ connection = new SqlConnection(connectionString);
+
+ DbObjDef = DbDefinitions.Get() ?? throw new Exception($"Definition for '{typeof(T).Name}' not found");
+ }
+
+ ///
+ public async Task> Get(List? parameters = null, RequestOptions? options = null, CancellationToken cancellationToken = default)
+ {
+ var jsonResult = await GetJson(parameters, options, cancellationToken);
+ if (string.IsNullOrEmpty(jsonResult))
+ {
+ return [];
+ }
+
+ return JsonSerializer.Deserialize>(jsonResult) ?? throw new Exception("Unable to deserialize data");
+ }
+
+ ///
+ public async Task<(IEnumerable Data, PagedResult PageInfo)> Search(string term, RequestOptions options, CancellationToken cancellationToken = default)
+ {
+ try
+ {
+ var json = await GetJson([new GenericFilter("Name", term, comparer: DbOperators.Contains)], options, cancellationToken);
+ var data = JsonSerializer.Deserialize>(json) ?? throw new Exception("Unable to deserialize data");
+ var pageInfo = JsonSerializer.Deserialize>(json) ?? throw new Exception("Unable to deserialize page data");
+
+ var info = pageInfo.First();
+ var paged = new PagedResult()
+ {
+ PageCount = (info.TotalItems + options.PageSize - 1) / options.PageSize,
+ ItemCount = pageInfo.First().TotalItems
+ };
+ paged.CurrentPage = options.PageNumber;
+ paged.PageSize = options.PageSize;
+
+ return (data, paged);
+ }
+ catch
+ {
+ return default;
+ }
+ }
+
+ ///
+ public async Task Ingest(List data, CancellationToken cancellationToken = default)
+ {
+ using var conn = new SqlConnection(connection.ConnectionString);
+ using (var bcp = new SqlBulkCopy(connection))
+ using (var reader = ObjectReader.Create(data, DbObjDef.Properties.Select(t => t.Key).ToArray()))
+ {
+ // bcp.NotifyAfter = 1000;
+ bcp.BatchSize = 1000;
+ bcp.BulkCopyTimeout = 1000;
+ bcp.DestinationTableName = DbObjDef.BaseDbObject.GetSqlDefinition(includeAlias: false);
+ await bcp.WriteToServerAsync(reader, cancellationToken);
+ }
+ }
+
+ ///
+ public async Task CreateTranslation(T entity, string language, CancellationToken cancellationToken = default)
+ {
+ if (DbObjDef.TranslationDbObject == null)
+ {
+ return 0;
+ }
+
+ var param = GetTranslationEntityAsSqlParameter(entity);
+ param.Add("Language", new SqlParameter("Language", language));
+ using var cmd = connection.CreateCommand();
+ cmd.CommandText = $"INSERT {DbObjDef.TranslationDbObject.GetSqlDefinition(includeAlias: false)} ({InsertColumns([.. param.Keys])}) VALUES({InsertValues([.. param.Keys])})";
+ cmd.Parameters.AddRange([.. param.Values]);
+ return await ExecuteCommand(cmd, cancellationToken);
+ }
+
+ ///
+ public async Task Create(T entity, CancellationToken cancellationToken = default)
+ {
+ var param = GetEntityAsSqlParameter(entity);
+ using var cmd = connection.CreateCommand();
+ cmd.CommandText = $"INSERT {DbObjDef.BaseDbObject.GetSqlDefinition(includeAlias: false)} ({InsertColumns([.. param.Keys])}) VALUES({InsertValues([.. param.Keys])})";
+ cmd.Parameters.AddRange([.. param.Values]);
+ return await ExecuteCommand(cmd, cancellationToken);
+ }
+
+ private string GetCommand(RequestOptions? options = null, List? filters = null, CancellationToken cancellationToken = default)
+ {
+ options ??= new RequestOptions();
+ StringBuilder sb = new StringBuilder();
+
+ if (options.UsePaging)
+ {
+ sb.AppendLine("WITH [PagedResult] AS (");
+ }
+
+ sb.AppendLine("SELECT ");
+ sb.AppendLine(GenerateColumns(options));
+ if (options.UsePaging)
+ {
+ string orderBy = string.IsNullOrEmpty(options.OrderBy) ? "Id" : options.OrderBy;
+ sb.AppendLine($",ROW_NUMBER() OVER (ORDER BY [{DbObjDef.BaseDbObject.Alias}].[{orderBy}]) AS [_RowNum]");
+ }
+
+ sb.AppendLine(" FROM " + GenerateSource(options));
+
+ if (filters != null && filters.Count > 0)
+ {
+ sb.AppendLine("WHERE " + string.Join(" AND ", filters.Select(t => $"[{DbObjDef.BaseDbObject.Alias}].[{t.Key}] {t.Comparer} @{t.Key}")));
+ }
+
+ if (options.UsePaging)
+ {
+ sb.AppendLine(")");
+ sb.AppendLine("SELECT *");
+ sb.AppendLine("FROM [PagedResult], (SELECT MAX([PagedResult].[_RowNum]) AS [TotalItems] FROM [PagedResult]) AS PageInfo");
+ sb.AppendLine($"ORDER BY [_RowNum] OFFSET {options.PageSize * (options.PageNumber - 1)} ROWS FETCH NEXT {options.PageSize} ROWS ONLY");
+ }
+
+ return sb.ToString();
+ }
+
+ private async Task GetJson(List? parameters = null, RequestOptions? options = null, CancellationToken cancellationToken = default)
+ {
+ options ??= new RequestOptions();
+ parameters ??= [];
+
+ var cmd = GetCommand(options, parameters);
+
+ if (options.Language != null)
+ {
+ parameters.Add(new GenericFilter("Language", options.Language));
+ }
+
+ if (options.AsOf.HasValue)
+ {
+ parameters.Add(new GenericFilter("_AsOf", options.AsOf.Value));
+ }
+
+ return await ExecuteForJson(cmd, parameters: parameters, singleResult: false, cancellationToken);
+ }
+
+ private string InsertColumns(List values)
+ {
+ return string.Join(',', values.OrderBy(t => t).Select(t => $"[{t}]").ToList());
+ }
+
+ private string InsertValues(List values)
+ {
+ return string.Join(',', values.OrderBy(t => t).Select(t => $"@{t}").ToList());
+ }
+
+ ///
+ public async Task UpdateTranslation(Guid id, T entity, string language, CancellationToken cancellationToken = default)
+ {
+ if (DbObjDef.TranslationDbObject == null)
+ {
+ return 0;
+ }
+
+ var param = GetTranslationEntityAsSqlParameter(entity);
+ using var cmd = connection.CreateCommand();
+ cmd.Parameters.AddRange([.. param.Values]);
+ cmd.Parameters.Add(new SqlParameter("_id", id));
+ cmd.Parameters.Add(new SqlParameter("_language", language));
+ cmd.CommandText = $"UPDATE {DbObjDef.TranslationDbObject.GetSqlDefinition(includeAlias: false)} SET {UpdateSetStatement([.. param.Keys])} WHERE [Id] = @_id AND [Language] = @_language";
+ return await ExecuteCommand(cmd, cancellationToken);
+ }
+
+ ///
+ public async Task Update(Guid id, T entity, CancellationToken cancellationToken = default)
+ {
+ var param = GetEntityAsSqlParameter(entity);
+ using var cmd = connection.CreateCommand();
+ cmd.Parameters.AddRange([.. param.Values]);
+ cmd.Parameters.Add(new SqlParameter("_id", id));
+ cmd.CommandText = $"UPDATE {DbObjDef.BaseDbObject.GetSqlDefinition(includeAlias: false)} SET {UpdateSetStatement([.. param.Keys])} WHERE [Id] = @_id";
+ return await ExecuteCommand(cmd, cancellationToken);
+ }
+
+ ///
+ public async Task Update(Guid id, List parameters, CancellationToken cancellationToken = default)
+ {
+ var param = new Dictionary();
+ foreach (var parameter in parameters)
+ {
+ param.Add(parameter.Key, new SqlParameter(parameter.Key, parameter.Value));
+ }
+
+ using var cmd = connection.CreateCommand();
+ cmd.Parameters.AddRange([.. param.Values]);
+ cmd.Parameters.Add(new SqlParameter("_id", id));
+ cmd.CommandText = $"UPDATE {DbObjDef.BaseDbObject.GetSqlDefinition(includeAlias: false)} SET {UpdateSetStatement([.. param.Keys])} WHERE [Id] = @_id";
+ return await ExecuteCommand(cmd, cancellationToken);
+ }
+
+ private string UpdateSetStatement(List values)
+ {
+ return string.Join(',', values.OrderBy(t => t).Select(t => $"[{t}] = @{t}").ToList());
+ }
+
+ ///
+ public async Task Delete(Guid id, CancellationToken cancellationToken = default)
+ {
+ using var cmd = connection.CreateCommand();
+ cmd.Parameters.Add(new SqlParameter("_id", id));
+ cmd.CommandText = $"DELETE {DbObjDef.BaseDbObject.GetSqlDefinition(includeAlias: false)} WHERE [Id] = @_id";
+ return await ExecuteCommand(cmd, cancellationToken);
+ }
+
+ private async Task CheckIfTranslationExists(Guid id, string language, CancellationToken cancellationToken = default)
+ {
+ if (DbObjDef.TranslationDbObject == null)
+ {
+ return false;
+ }
+
+ using var cmd = connection.CreateCommand();
+ cmd.Parameters.Add(new SqlParameter("Id", id));
+ cmd.Parameters.Add(new SqlParameter("Language", language));
+ cmd.CommandText = $"SELECT COUNT(*) AS [Cnt] FROM {DbObjDef.TranslationDbObject.GetSqlDefinition(includeAlias: false)} WHERE [Id] = @Id AND [Language] = @Language";
+ var res = await ExecuteScalarCommand(cmd, cancellationToken);
+ _ = int.TryParse(res?.ToString(), out int rowCount);
+
+ if (rowCount > 0)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private async Task