diff --git a/obj/Data.EntityFrameworkCore.targets b/obj/Data.EntityFrameworkCore.targets
new file mode 100644
index 0000000..7d6485d
--- /dev/null
+++ b/obj/Data.EntityFrameworkCore.targets
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scripts/add-migration.cmd b/scripts/add-migration.cmd
index 4652f25..c196a67 100644
--- a/scripts/add-migration.cmd
+++ b/scripts/add-migration.cmd
@@ -1,3 +1,3 @@
@echo off
set /p migrationName="Migration Name: "
-dotnet ef migrations add %migrationName% --startup-project "../Api" --project "../Data" --context ApplicationContext
\ No newline at end of file
+dotnet ef migrations add %migrationName% --startup-project "../src/dotnet/Suspectus.Gandalf.Palantir.Api" --project "../src/dotnet/Suspectus.Gandalf.Palantir.Data" --context ApplicationContext
\ No newline at end of file
diff --git a/scripts/update-database.cmd b/scripts/update-database.cmd
index 2174d5f..825a7b2 100644
--- a/scripts/update-database.cmd
+++ b/scripts/update-database.cmd
@@ -1,2 +1,2 @@
@echo off
-dotnet ef database update --startup-project "../Api" --project "../Data" --context ApplicationContext
\ No newline at end of file
+dotnet ef database update --startup-project "../src/dotnet/Suspectus.Gandalf.Palantir.Api" --project "../src/dotnet/Suspectus.Gandalf.Palantir.Data" --context ApplicationContext
\ No newline at end of file
diff --git a/src/dotnet/.idea/.idea.Suspectus.Gandalf/.idea/dataSources.xml b/src/dotnet/.idea/.idea.Suspectus.Gandalf/.idea/dataSources.xml
new file mode 100644
index 0000000..2d89c97
--- /dev/null
+++ b/src/dotnet/.idea/.idea.Suspectus.Gandalf/.idea/dataSources.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ postgresql
+ true
+ true
+ org.postgresql.Driver
+ jdbc:postgresql://localhost:5432/gandalf_reborn?logServerErrorDetail=True&password=root&user=root
+ $ProjectFileDir$
+
+
+
\ No newline at end of file
diff --git a/src/dotnet/Suspectus.Gandalf.Palantir.Api/Program.cs b/src/dotnet/Suspectus.Gandalf.Palantir.Api/Program.cs
index 92cf8a3..17d4676 100644
--- a/src/dotnet/Suspectus.Gandalf.Palantir.Api/Program.cs
+++ b/src/dotnet/Suspectus.Gandalf.Palantir.Api/Program.cs
@@ -4,6 +4,7 @@ using HashidsNet;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Suspectus.Gandalf.Palantir.Abstractions;
+using Suspectus.Gandalf.Palantir.Api.Services;
using Suspectus.Gandalf.Palantir.Security.Scheme;
using Suspectus.Gandalf.Palantir.Data.Database;
using Suspectus.Gandalf.Palantir.Data.Database.Repositories;
@@ -51,13 +52,13 @@ builder.Services.AddMediatR(config =>
{
config.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
});
+builder.Services.AddTransient();
builder.Services.AddOpenApi();
var app = builder.Build();
var scope = app.Services.CreateScope();
-var applicationContext = scope.ServiceProvider.GetRequiredService();
-applicationContext.Database.EnsureCreated();
-applicationContext.AddVersionTriggers();
+var initService = scope.ServiceProvider.GetRequiredService();
+await initService.InitializeAsync();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
diff --git a/src/dotnet/Suspectus.Gandalf.Palantir.Api/Services/InitService.cs b/src/dotnet/Suspectus.Gandalf.Palantir.Api/Services/InitService.cs
new file mode 100644
index 0000000..6b96847
--- /dev/null
+++ b/src/dotnet/Suspectus.Gandalf.Palantir.Api/Services/InitService.cs
@@ -0,0 +1,134 @@
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using Suspectus.Gandalf.Palantir.Abstractions;
+using Suspectus.Gandalf.Palantir.Api.Commands;
+using Suspectus.Gandalf.Palantir.Api.Extensions;
+using Suspectus.Gandalf.Palantir.Data.Database;
+using Suspectus.Gandalf.Palantir.Data.Entities.App;
+using Suspectus.Gandalf.Palantir.Data.Entities.Base;
+using Suspectus.Gandalf.Palantir.Data.Entities.Subject;
+using Suspectus.Gandalf.Palantir.Data.Entities.Subject.SignIn;
+using Suspectus.Gandalf.Palantir.Data.Entities.Tenant;
+
+namespace Suspectus.Gandalf.Palantir.Api.Services;
+
+public class InitService
+{
+ private const string HousemasterUserName = "housemaster";
+
+ private readonly ApplicationContext _applicationContext;
+ private readonly IMediator _mediator;
+ private readonly ILogger _logger;
+ private readonly InvokerContext _invokerContext;
+
+ public InitService(ApplicationContext applicationContext, IMediator mediator, ILogger logger, InvokerContext invokerContext)
+ {
+ _applicationContext = applicationContext;
+ _mediator = mediator;
+ _logger = logger;
+ _invokerContext = invokerContext;
+ }
+
+
+ private static string GeneratePassword(int length = 20)
+ {
+ const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ var random = new Random();
+ return new string(
+ Enumerable.Repeat(0, length)
+ .Select(_ => chars[random.Next(chars.Length)]).ToArray()
+ );
+ }
+
+ private async Task InitializeDatabaseAsync()
+ {
+ await _applicationContext.Database.EnsureCreatedAsync();
+ await _applicationContext.AddVersionTriggers();
+ }
+
+ private async Task InitializeMaster()
+ {
+ var masterTenant = await _applicationContext.Tenants.SingleOrDefaultAsync(x => x.Id == 0);
+
+ if (masterTenant is not null)
+ return;
+
+ var masterTenantPassword = GeneratePassword();
+ var masterTenantPasswordHashResult = await _mediator.Send(new HashPasswordCommand { RawPassword = masterTenantPassword });
+
+ if (masterTenantPasswordHashResult.IsFaulted)
+ return;
+
+ var masterTenantPasswordHash = masterTenantPasswordHashResult.GetValue();
+
+ var housemasterUser = new SubjectEntity
+ {
+ Visibility = EntityVisibility.Active,
+ Name = HousemasterUserName,
+ SignInMethods =
+ [
+ new SignInEntity
+ {
+ Visibility = EntityVisibility.Active,
+ Method = SignInMethod.Simple,
+ IsLegacy = false,
+ PasswordHash = masterTenantPasswordHash
+ }
+ ]
+ };
+
+ _applicationContext.Subjects.Add(housemasterUser);
+ await _applicationContext.SaveChangesAsync();
+
+ _invokerContext.Invoker = new Invoker
+ {
+ SubjectId = housemasterUser.Id!.Value,
+ TenantAuthorityDictionary = new Dictionary>(),
+ AppAuthorityDictionary = new Dictionary>(),
+ IsAuthenticated = true
+ };
+
+ masterTenant = new TenantEntity
+ {
+ Visibility = EntityVisibility.Active,
+ Name = "Master",
+ OwnerId = housemasterUser.Id!.Value,
+ };
+
+ _applicationContext.Tenants.Add(masterTenant);
+ await _applicationContext.SaveChangesAsync();
+
+ var masterApp = new AppEntity
+ {
+ Visibility = EntityVisibility.Active,
+ TenantId = masterTenant.Id!.Value,
+ Name = "Master"
+ };
+
+ _applicationContext.Apps.Add(masterApp);
+ await _applicationContext.SaveChangesAsync();
+
+ var appSubjectRelation = new AppSubjectRelationEntity
+ {
+ AppId = masterApp.Id!.Value,
+ SubjectId = housemasterUser.Id!.Value
+ };
+
+ _applicationContext.AppSubjectRelations.Add(appSubjectRelation);
+ await _applicationContext.SaveChangesAsync();
+
+ _logger.LogInformation($"""
+ ----- Housemaster initial login information -----
+ username: {housemasterUser.Name}
+ password: {masterTenantPassword}
+ Please change the password after the first login.
+ -------------------------------------------------
+ """);
+ }
+
+ public async Task InitializeAsync()
+ {
+ await InitializeDatabaseAsync();
+ await InitializeMaster();
+ }
+}
\ No newline at end of file
diff --git a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Database/ApplicationContext.cs b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Database/ApplicationContext.cs
index 9e8fcf7..37a666d 100644
--- a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Database/ApplicationContext.cs
+++ b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Database/ApplicationContext.cs
@@ -117,7 +117,7 @@ public sealed class ApplicationContext(DbContextOptions opti
});
}
- public void AddVersionTriggers()
+ public async Task AddVersionTriggers()
{
foreach (var (entityType, versionType) in EntityToVersionEntityMap)
{
@@ -159,7 +159,7 @@ public sealed class ApplicationContext(DbContextOptions opti
""";
#pragma warning disable EF1002
- Database.ExecuteSqlRaw(sql);
+ await Database.ExecuteSqlRawAsync(sql);
#pragma warning restore EF1002
}
}
diff --git a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Database/CoreContext.cs b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Database/CoreContext.cs
index 5489d9f..2470811 100644
--- a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Database/CoreContext.cs
+++ b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Database/CoreContext.cs
@@ -12,14 +12,14 @@ public abstract class CoreContext(DbContextOptions options) : DbContext(op
{
public DbSet Tenants { get; set; }
public DbSet Subjects { get; set; }
- public DbSet Apps { get; set; }
+ public DbSet Apps { get; set; }
public DbSet TenantSubjectRelations { get; set; }
public DbSet AppSubjectRelations { get; set; }
public DbSet AuthorityEntities { get; set; }
public DbSet TokenMetadata { get; set; }
public DbSet AuthCodes { get; set; }
- public DbSet AppsVersions { get; set; }
+ public DbSet AppsVersions { get; set; }
public DbSet TenantVersions { get; set; }
public DbSet AppSubjectRelationVersions { get; set; }
public DbSet TenantSubjectRelationVersions { get; set; }
@@ -93,14 +93,6 @@ public abstract class CoreContext(DbContextOptions options) : DbContext(op
.HasIndex(x => x.Name)
.IsUnique();
- subjectBuilder
- .HasData(new SubjectEntity
- {
- Id = 1,
- Visibility = EntityVisibility.Active,
- Name = "chris"
- });
-
#endregion
#region SighnIns
@@ -115,7 +107,7 @@ public abstract class CoreContext(DbContextOptions options) : DbContext(op
#region App
- var appBuilder = builder.Entity();
+ var appBuilder = builder.Entity();
appBuilder
.HasMany(x => x.Subjects)
diff --git a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/App/AppRelationEntity.cs b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/App/AppEntity.cs
similarity index 69%
rename from src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/App/AppRelationEntity.cs
rename to src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/App/AppEntity.cs
index 9524b3d..ccfcac6 100644
--- a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/App/AppRelationEntity.cs
+++ b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/App/AppEntity.cs
@@ -5,22 +5,22 @@ using Suspectus.Gandalf.Palantir.Data.Entities.Version;
namespace Suspectus.Gandalf.Palantir.Data.Entities.App;
-public class AppRelationEntity : AppRelationData, IVersionableEntity
+public class AppEntity : AppData, IVersionableEntity
{
public TenantEntity? Tenant { get; set; }
public HashSet Subjects { get; set; } = [];
}
-public class AppRelationVersionEntity : AppRelationData, IVersionEntity
+public class AppVersionEntity : AppData, IVersionEntity
{
public SubjectEntity? Suspect { get; set; }
public long SuspectId { get; set; }
public VersionAction Action { get; set; }
public DateTimeOffset At { get; set; }
- public AppRelationEntity? Reference { get; set; }
+ public AppEntity? Reference { get; set; }
}
-public abstract class AppRelationData : TenantRelationData
+public abstract class AppData : TenantRelationData
{
public required string Name { get; set; }
}
\ No newline at end of file
diff --git a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/App/AppSubjectRelationEntity.cs b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/App/AppSubjectRelationEntity.cs
index 412ba1e..62e4c48 100644
--- a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/App/AppSubjectRelationEntity.cs
+++ b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/App/AppSubjectRelationEntity.cs
@@ -9,7 +9,7 @@ namespace Suspectus.Gandalf.Palantir.Data.Entities.App;
public class AppSubjectRelationEntity : AppSubjectRelationData, IMappingEntity, IVersionableEntity
{
public HashSet InternalAuthorities { get; set; } = [];
- public AppRelationEntity? App { get; set; }
+ public AppEntity? App { get; set; }
public SubjectEntity? Subject { get; set; }
}
diff --git a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/Subject/SubjectEntity.cs b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/Subject/SubjectEntity.cs
index 8f60f45..e22056c 100644
--- a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/Subject/SubjectEntity.cs
+++ b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/Subject/SubjectEntity.cs
@@ -10,5 +10,5 @@ public class SubjectEntity : VisibilityData
public required string Name { get; set; }
public HashSet SignInMethods { get; set; } = [];
public HashSet Tenants { get; set; } = [];
- public HashSet Apps { get; set; } = [];
+ public HashSet Apps { get; set; } = [];
}
\ No newline at end of file
diff --git a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/Tenant/TenantEntity.cs b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/Tenant/TenantEntity.cs
index d19a214..43d5728 100644
--- a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/Tenant/TenantEntity.cs
+++ b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Entities/Tenant/TenantEntity.cs
@@ -8,7 +8,7 @@ public class TenantEntity : TenantData, IVersionableEntity
{
public SubjectEntity? Owner { get; set; }
public HashSet Subjects { get; set; } = [];
- public HashSet Apps { get; set; } = [];
+ public HashSet Apps { get; set; } = [];
}
public interface IVersionableEntity;
diff --git a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/20250525155339_cringe1.Designer.cs b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/20250525155339_cringe1.Designer.cs
new file mode 100644
index 0000000..a4150ea
--- /dev/null
+++ b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/20250525155339_cringe1.Designer.cs
@@ -0,0 +1,718 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using Suspectus.Gandalf.Palantir.Data.Database;
+
+#nullable disable
+
+namespace W542.GandalfReborn.Data.Migrations
+{
+ [DbContext(typeof(ApplicationContext))]
+ [Migration("20250525155339_cringe1")]
+ partial class cringe1
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "9.0.2")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppRelationEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("TenantId")
+ .HasColumnType("bigint");
+
+ b.Property("Visibility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId");
+
+ b.ToTable("AppRelation", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppRelationVersionEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("bigint");
+
+ b.Property("At")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("SuspectId")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnType("bigint");
+
+ b.Property("Visibility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id", "At");
+
+ b.HasIndex("SuspectId");
+
+ b.ToTable("AppRelationVersion", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("AppId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "AppId");
+
+ b.HasIndex("AppId");
+
+ b.ToTable("AppSubjectRelation", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("AppId")
+ .HasColumnType("bigint");
+
+ b.Property("At")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("SuspectId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "AppId", "At");
+
+ b.HasIndex("SuspectId");
+
+ b.ToTable("AppSubjectRelationVersion", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("AppId")
+ .HasColumnType("bigint");
+
+ b.Property("InternalAuthorityId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
+
+ b.HasIndex("InternalAuthorityId");
+
+ b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("AppId")
+ .HasColumnType("bigint");
+
+ b.Property("InternalAuthorityId")
+ .HasColumnType("bigint");
+
+ b.Property("At")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("SuspectId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
+
+ b.HasIndex("SuspectId");
+
+ b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AuthCodeEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Algorithm")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Challenge")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Code")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Expiration")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsRevoked")
+ .HasColumnType("boolean");
+
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.ToTable("AuthCode", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AuthorityEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Description")
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Authority", "gr");
+
+ b.HasData(
+ new
+ {
+ Id = 1L,
+ Description = "Allows users to read tenants",
+ Name = "Tenant_Read",
+ Type = "Tenant"
+ },
+ new
+ {
+ Id = 2L,
+ Description = "Allows users to read apps",
+ Name = "App_Read",
+ Type = "App"
+ });
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnType("bigint");
+
+ b.Property("InternalAuthorityId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
+
+ b.HasIndex("InternalAuthorityId");
+
+ b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnType("bigint");
+
+ b.Property("InternalAuthorityId")
+ .HasColumnType("bigint");
+
+ b.Property("At")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("SuspectId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
+
+ b.HasIndex("SuspectId");
+
+ b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.TokenMetadataEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Expiration")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsRevoked")
+ .HasColumnType("boolean");
+
+ b.Property("TokenType")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("UsedBy")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.ToTable("TokenMetadata", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SignIn.SignInEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Email")
+ .HasColumnType("text");
+
+ b.Property("IsLegacy")
+ .HasColumnType("boolean");
+
+ b.Property("Method")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("PasswordHash")
+ .HasColumnType("text");
+
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("Visibility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Email")
+ .IsUnique();
+
+ b.HasIndex("SubjectId");
+
+ b.ToTable("SignIn", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Visibility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Subject", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("OwnerId")
+ .HasColumnType("bigint");
+
+ b.Property("Visibility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OwnerId");
+
+ b.ToTable("Tenant", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "TenantId");
+
+ b.HasIndex("TenantId");
+
+ b.ToTable("TenantSubjectRelation", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnType("bigint");
+
+ b.Property("At")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("SuspectId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "TenantId", "At");
+
+ b.HasIndex("SuspectId");
+
+ b.ToTable("TenantSubjectRelationVersion", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantVersionEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("bigint");
+
+ b.Property("At")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("OwnerId")
+ .HasColumnType("bigint");
+
+ b.Property("SuspectId")
+ .HasColumnType("bigint");
+
+ b.Property("Visibility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id", "At");
+
+ b.HasIndex("SuspectId");
+
+ b.ToTable("TenantVersion", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppRelationEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantEntity", "Tenant")
+ .WithMany("Apps")
+ .HasForeignKey("TenantId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Tenant");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppRelationVersionEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.App.AppRelationEntity", "Reference")
+ .WithMany()
+ .HasForeignKey("Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Suspect")
+ .WithMany()
+ .HasForeignKey("SuspectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reference");
+
+ b.Navigation("Suspect");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.App.AppRelationEntity", "App")
+ .WithMany()
+ .HasForeignKey("AppId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Subject")
+ .WithMany()
+ .HasForeignKey("SubjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("App");
+
+ b.Navigation("Subject");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Suspect")
+ .WithMany()
+ .HasForeignKey("SuspectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationEntity", "Reference")
+ .WithMany()
+ .HasForeignKey("SubjectId", "AppId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reference");
+
+ b.Navigation("Suspect");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
+ .WithMany()
+ .HasForeignKey("InternalAuthorityId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
+ .WithMany()
+ .HasForeignKey("SubjectId", "AppId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("AppSubjectRelation");
+
+ b.Navigation("InternalAuthority");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Suspect")
+ .WithMany()
+ .HasForeignKey("SuspectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
+ .WithMany()
+ .HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reference");
+
+ b.Navigation("Suspect");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
+ .WithMany()
+ .HasForeignKey("InternalAuthorityId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
+ .WithMany()
+ .HasForeignKey("SubjectId", "TenantId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("InternalAuthority");
+
+ b.Navigation("TenantSubjectRelation");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Suspect")
+ .WithMany()
+ .HasForeignKey("SuspectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
+ .WithMany()
+ .HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reference");
+
+ b.Navigation("Suspect");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SignIn.SignInEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Subject")
+ .WithMany("SignInMethods")
+ .HasForeignKey("SubjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Subject");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Owner")
+ .WithMany()
+ .HasForeignKey("OwnerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Owner");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Subject")
+ .WithMany()
+ .HasForeignKey("SubjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantEntity", "Tenant")
+ .WithMany()
+ .HasForeignKey("TenantId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Subject");
+
+ b.Navigation("Tenant");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Suspect")
+ .WithMany()
+ .HasForeignKey("SuspectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
+ .WithMany()
+ .HasForeignKey("SubjectId", "TenantId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reference");
+
+ b.Navigation("Suspect");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantVersionEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantEntity", "Reference")
+ .WithMany()
+ .HasForeignKey("Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Suspect")
+ .WithMany()
+ .HasForeignKey("SuspectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reference");
+
+ b.Navigation("Suspect");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", b =>
+ {
+ b.Navigation("SignInMethods");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantEntity", b =>
+ {
+ b.Navigation("Apps");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/20250525155339_cringe1.cs b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/20250525155339_cringe1.cs
new file mode 100644
index 0000000..85aa528
--- /dev/null
+++ b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/20250525155339_cringe1.cs
@@ -0,0 +1,30 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace W542.GandalfReborn.Data.Migrations
+{
+ ///
+ public partial class cringe1 : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DeleteData(
+ schema: "gr",
+ table: "Subject",
+ keyColumn: "Id",
+ keyValue: 1L);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.InsertData(
+ schema: "gr",
+ table: "Subject",
+ columns: new[] { "Id", "Name", "Visibility" },
+ values: new object[] { 1L, "chris", "Active" });
+ }
+ }
+}
diff --git a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/20250525162427_cringe2.Designer.cs b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/20250525162427_cringe2.Designer.cs
new file mode 100644
index 0000000..d294744
--- /dev/null
+++ b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/20250525162427_cringe2.Designer.cs
@@ -0,0 +1,718 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using Suspectus.Gandalf.Palantir.Data.Database;
+
+#nullable disable
+
+namespace W542.GandalfReborn.Data.Migrations
+{
+ [DbContext(typeof(ApplicationContext))]
+ [Migration("20250525162427_cringe2")]
+ partial class cringe2
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "9.0.2")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("TenantId")
+ .HasColumnType("bigint");
+
+ b.Property("Visibility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId");
+
+ b.ToTable("App", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("AppId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "AppId");
+
+ b.HasIndex("AppId");
+
+ b.ToTable("AppSubjectRelation", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("AppId")
+ .HasColumnType("bigint");
+
+ b.Property("At")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("SuspectId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "AppId", "At");
+
+ b.HasIndex("SuspectId");
+
+ b.ToTable("AppSubjectRelationVersion", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppVersionEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("bigint");
+
+ b.Property("At")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("SuspectId")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnType("bigint");
+
+ b.Property("Visibility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id", "At");
+
+ b.HasIndex("SuspectId");
+
+ b.ToTable("AppVersion", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("AppId")
+ .HasColumnType("bigint");
+
+ b.Property("InternalAuthorityId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "AppId", "InternalAuthorityId");
+
+ b.HasIndex("InternalAuthorityId");
+
+ b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("AppId")
+ .HasColumnType("bigint");
+
+ b.Property("InternalAuthorityId")
+ .HasColumnType("bigint");
+
+ b.Property("At")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("SuspectId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "AppId", "InternalAuthorityId", "At");
+
+ b.HasIndex("SuspectId");
+
+ b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AuthCodeEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Algorithm")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Challenge")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Code")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Expiration")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsRevoked")
+ .HasColumnType("boolean");
+
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.ToTable("AuthCode", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AuthorityEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Description")
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Authority", "gr");
+
+ b.HasData(
+ new
+ {
+ Id = 1L,
+ Description = "Allows users to read tenants",
+ Name = "Tenant_Read",
+ Type = "Tenant"
+ },
+ new
+ {
+ Id = 2L,
+ Description = "Allows users to read apps",
+ Name = "App_Read",
+ Type = "App"
+ });
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnType("bigint");
+
+ b.Property("InternalAuthorityId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "TenantId", "InternalAuthorityId");
+
+ b.HasIndex("InternalAuthorityId");
+
+ b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnType("bigint");
+
+ b.Property("InternalAuthorityId")
+ .HasColumnType("bigint");
+
+ b.Property("At")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("SuspectId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "TenantId", "InternalAuthorityId", "At");
+
+ b.HasIndex("SuspectId");
+
+ b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.TokenMetadataEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Expiration")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsRevoked")
+ .HasColumnType("boolean");
+
+ b.Property("TokenType")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("UsedBy")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.ToTable("TokenMetadata", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SignIn.SignInEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Email")
+ .HasColumnType("text");
+
+ b.Property("IsLegacy")
+ .HasColumnType("boolean");
+
+ b.Property("Method")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("PasswordHash")
+ .HasColumnType("text");
+
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("Visibility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Email")
+ .IsUnique();
+
+ b.HasIndex("SubjectId");
+
+ b.ToTable("SignIn", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Visibility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Subject", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("OwnerId")
+ .HasColumnType("bigint");
+
+ b.Property("Visibility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OwnerId");
+
+ b.ToTable("Tenant", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "TenantId");
+
+ b.HasIndex("TenantId");
+
+ b.ToTable("TenantSubjectRelation", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("TenantId")
+ .HasColumnType("bigint");
+
+ b.Property("At")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("SuspectId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "TenantId", "At");
+
+ b.HasIndex("SuspectId");
+
+ b.ToTable("TenantSubjectRelationVersion", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantVersionEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("bigint");
+
+ b.Property("At")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("OwnerId")
+ .HasColumnType("bigint");
+
+ b.Property("SuspectId")
+ .HasColumnType("bigint");
+
+ b.Property("Visibility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id", "At");
+
+ b.HasIndex("SuspectId");
+
+ b.ToTable("TenantVersion", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantEntity", "Tenant")
+ .WithMany("Apps")
+ .HasForeignKey("TenantId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Tenant");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.App.AppEntity", "App")
+ .WithMany()
+ .HasForeignKey("AppId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Subject")
+ .WithMany()
+ .HasForeignKey("SubjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("App");
+
+ b.Navigation("Subject");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Suspect")
+ .WithMany()
+ .HasForeignKey("SuspectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationEntity", "Reference")
+ .WithMany()
+ .HasForeignKey("SubjectId", "AppId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reference");
+
+ b.Navigation("Suspect");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppVersionEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.App.AppEntity", "Reference")
+ .WithMany()
+ .HasForeignKey("Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Suspect")
+ .WithMany()
+ .HasForeignKey("SuspectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reference");
+
+ b.Navigation("Suspect");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
+ .WithMany()
+ .HasForeignKey("InternalAuthorityId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationEntity", "AppSubjectRelation")
+ .WithMany()
+ .HasForeignKey("SubjectId", "AppId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("AppSubjectRelation");
+
+ b.Navigation("InternalAuthority");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Suspect")
+ .WithMany()
+ .HasForeignKey("SuspectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", "Reference")
+ .WithMany()
+ .HasForeignKey("SubjectId", "AppId", "InternalAuthorityId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reference");
+
+ b.Navigation("Suspect");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Security.AuthorityEntity", "InternalAuthority")
+ .WithMany()
+ .HasForeignKey("InternalAuthorityId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantSubjectRelationEntity", "TenantSubjectRelation")
+ .WithMany()
+ .HasForeignKey("SubjectId", "TenantId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("InternalAuthority");
+
+ b.Navigation("TenantSubjectRelation");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Suspect")
+ .WithMany()
+ .HasForeignKey("SuspectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", "Reference")
+ .WithMany()
+ .HasForeignKey("SubjectId", "TenantId", "InternalAuthorityId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reference");
+
+ b.Navigation("Suspect");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SignIn.SignInEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Subject")
+ .WithMany("SignInMethods")
+ .HasForeignKey("SubjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Subject");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Owner")
+ .WithMany()
+ .HasForeignKey("OwnerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Owner");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantSubjectRelationEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Subject")
+ .WithMany()
+ .HasForeignKey("SubjectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantEntity", "Tenant")
+ .WithMany()
+ .HasForeignKey("TenantId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Subject");
+
+ b.Navigation("Tenant");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantSubjectRelationVersionEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Suspect")
+ .WithMany()
+ .HasForeignKey("SuspectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantSubjectRelationEntity", "Reference")
+ .WithMany()
+ .HasForeignKey("SubjectId", "TenantId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reference");
+
+ b.Navigation("Suspect");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantVersionEntity", b =>
+ {
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantEntity", "Reference")
+ .WithMany()
+ .HasForeignKey("Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", "Suspect")
+ .WithMany()
+ .HasForeignKey("SuspectId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Reference");
+
+ b.Navigation("Suspect");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Subject.SubjectEntity", b =>
+ {
+ b.Navigation("SignInMethods");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Tenant.TenantEntity", b =>
+ {
+ b.Navigation("Apps");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/20250525162427_cringe2.cs b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/20250525162427_cringe2.cs
new file mode 100644
index 0000000..0115b2a
--- /dev/null
+++ b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/20250525162427_cringe2.cs
@@ -0,0 +1,230 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace W542.GandalfReborn.Data.Migrations
+{
+ ///
+ public partial class cringe2 : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_AppRelation_Tenant_TenantId",
+ schema: "gr",
+ table: "AppRelation");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_AppRelationVersion_AppRelation_Id",
+ schema: "gr",
+ table: "AppRelationVersion");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_AppRelationVersion_Subject_SuspectId",
+ schema: "gr",
+ table: "AppRelationVersion");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_AppSubjectRelation_AppRelation_AppId",
+ schema: "gr",
+ table: "AppSubjectRelation");
+
+ migrationBuilder.DropPrimaryKey(
+ name: "PK_AppRelationVersion",
+ schema: "gr",
+ table: "AppRelationVersion");
+
+ migrationBuilder.DropPrimaryKey(
+ name: "PK_AppRelation",
+ schema: "gr",
+ table: "AppRelation");
+
+ migrationBuilder.RenameTable(
+ name: "AppRelationVersion",
+ schema: "gr",
+ newName: "AppVersion",
+ newSchema: "gr");
+
+ migrationBuilder.RenameTable(
+ name: "AppRelation",
+ schema: "gr",
+ newName: "App",
+ newSchema: "gr");
+
+ migrationBuilder.RenameIndex(
+ name: "IX_AppRelationVersion_SuspectId",
+ schema: "gr",
+ table: "AppVersion",
+ newName: "IX_AppVersion_SuspectId");
+
+ migrationBuilder.RenameIndex(
+ name: "IX_AppRelation_TenantId",
+ schema: "gr",
+ table: "App",
+ newName: "IX_App_TenantId");
+
+ migrationBuilder.AddPrimaryKey(
+ name: "PK_AppVersion",
+ schema: "gr",
+ table: "AppVersion",
+ columns: new[] { "Id", "At" });
+
+ migrationBuilder.AddPrimaryKey(
+ name: "PK_App",
+ schema: "gr",
+ table: "App",
+ column: "Id");
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_App_Tenant_TenantId",
+ schema: "gr",
+ table: "App",
+ column: "TenantId",
+ principalSchema: "gr",
+ principalTable: "Tenant",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_AppSubjectRelation_App_AppId",
+ schema: "gr",
+ table: "AppSubjectRelation",
+ column: "AppId",
+ principalSchema: "gr",
+ principalTable: "App",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_AppVersion_App_Id",
+ schema: "gr",
+ table: "AppVersion",
+ column: "Id",
+ principalSchema: "gr",
+ principalTable: "App",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_AppVersion_Subject_SuspectId",
+ schema: "gr",
+ table: "AppVersion",
+ column: "SuspectId",
+ principalSchema: "gr",
+ principalTable: "Subject",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_App_Tenant_TenantId",
+ schema: "gr",
+ table: "App");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_AppSubjectRelation_App_AppId",
+ schema: "gr",
+ table: "AppSubjectRelation");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_AppVersion_App_Id",
+ schema: "gr",
+ table: "AppVersion");
+
+ migrationBuilder.DropForeignKey(
+ name: "FK_AppVersion_Subject_SuspectId",
+ schema: "gr",
+ table: "AppVersion");
+
+ migrationBuilder.DropPrimaryKey(
+ name: "PK_AppVersion",
+ schema: "gr",
+ table: "AppVersion");
+
+ migrationBuilder.DropPrimaryKey(
+ name: "PK_App",
+ schema: "gr",
+ table: "App");
+
+ migrationBuilder.RenameTable(
+ name: "AppVersion",
+ schema: "gr",
+ newName: "AppRelationVersion",
+ newSchema: "gr");
+
+ migrationBuilder.RenameTable(
+ name: "App",
+ schema: "gr",
+ newName: "AppRelation",
+ newSchema: "gr");
+
+ migrationBuilder.RenameIndex(
+ name: "IX_AppVersion_SuspectId",
+ schema: "gr",
+ table: "AppRelationVersion",
+ newName: "IX_AppRelationVersion_SuspectId");
+
+ migrationBuilder.RenameIndex(
+ name: "IX_App_TenantId",
+ schema: "gr",
+ table: "AppRelation",
+ newName: "IX_AppRelation_TenantId");
+
+ migrationBuilder.AddPrimaryKey(
+ name: "PK_AppRelationVersion",
+ schema: "gr",
+ table: "AppRelationVersion",
+ columns: new[] { "Id", "At" });
+
+ migrationBuilder.AddPrimaryKey(
+ name: "PK_AppRelation",
+ schema: "gr",
+ table: "AppRelation",
+ column: "Id");
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_AppRelation_Tenant_TenantId",
+ schema: "gr",
+ table: "AppRelation",
+ column: "TenantId",
+ principalSchema: "gr",
+ principalTable: "Tenant",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_AppRelationVersion_AppRelation_Id",
+ schema: "gr",
+ table: "AppRelationVersion",
+ column: "Id",
+ principalSchema: "gr",
+ principalTable: "AppRelation",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_AppRelationVersion_Subject_SuspectId",
+ schema: "gr",
+ table: "AppRelationVersion",
+ column: "SuspectId",
+ principalSchema: "gr",
+ principalTable: "Subject",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_AppSubjectRelation_AppRelation_AppId",
+ schema: "gr",
+ table: "AppSubjectRelation",
+ column: "AppId",
+ principalSchema: "gr",
+ principalTable: "AppRelation",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ }
+ }
+}
diff --git a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/ApplicationContextModelSnapshot.cs b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/ApplicationContextModelSnapshot.cs
index 097bd4d..bcbe32a 100644
--- a/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/ApplicationContextModelSnapshot.cs
+++ b/src/dotnet/Suspectus.Gandalf.Palantir.Data/Migrations/ApplicationContextModelSnapshot.cs
@@ -17,18 +17,18 @@ namespace W542.GandalfReborn.Data.Migrations
{
#pragma warning disable 612, 618
modelBuilder
- .HasAnnotation("ProductVersion", "8.0.8")
+ .HasAnnotation("ProductVersion", "9.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
- modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationEntity", b =>
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppEntity", b =>
{
- b.Property("Id")
+ b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
b.Property("Name")
.IsRequired()
@@ -45,12 +45,52 @@ namespace W542.GandalfReborn.Data.Migrations
b.HasIndex("TenantId");
- b.ToTable("AppRelation", "gr");
+ b.ToTable("App", "gr");
});
- modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppRelationVersionEntity", b =>
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationEntity", b =>
{
- b.Property("Id")
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("AppId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "AppId");
+
+ b.HasIndex("AppId");
+
+ b.ToTable("AppSubjectRelation", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
+ {
+ b.Property("SubjectId")
+ .HasColumnType("bigint");
+
+ b.Property("AppId")
+ .HasColumnType("bigint");
+
+ b.Property("At")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("SuspectId")
+ .HasColumnType("bigint");
+
+ b.HasKey("SubjectId", "AppId", "At");
+
+ b.HasIndex("SuspectId");
+
+ b.ToTable("AppSubjectRelationVersion", "gr");
+ });
+
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.App.AppVersionEntity", b =>
+ {
+ b.Property("Id")
.HasColumnType("bigint");
b.Property("At")
@@ -78,50 +118,10 @@ namespace W542.GandalfReborn.Data.Migrations
b.HasIndex("SuspectId");
- b.ToTable("AppRelationVersion", "gr");
+ b.ToTable("AppVersion", "gr");
});
- modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationEntity", b =>
- {
- b.Property("SubjectId")
- .HasColumnType("bigint");
-
- b.Property("AppId")
- .HasColumnType("bigint");
-
- b.HasKey("SubjectId", "AppId");
-
- b.HasIndex("AppId");
-
- b.ToTable("AppSubjectRelation", "gr");
- });
-
- modelBuilder.Entity("W542.GandalfReborn.Data.Entities.App.AppSubjectRelationVersionEntity", b =>
- {
- b.Property("SubjectId")
- .HasColumnType("bigint");
-
- b.Property("AppId")
- .HasColumnType("bigint");
-
- b.Property("At")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Action")
- .IsRequired()
- .HasColumnType("text");
-
- b.Property("SuspectId")
- .HasColumnType("bigint");
-
- b.HasKey("SubjectId", "AppId", "At");
-
- b.HasIndex("SuspectId");
-
- b.ToTable("AppSubjectRelationVersion", "gr");
- });
-
- modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property("SubjectId")
.HasColumnType("bigint");
@@ -139,7 +139,7 @@ namespace W542.GandalfReborn.Data.Migrations
b.ToTable("AppSubjectRelationInternalAuthorityRelation", "gr");
});
- modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AppSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property("SubjectId")
.HasColumnType("bigint");
@@ -167,13 +167,13 @@ namespace W542.GandalfReborn.Data.Migrations
b.ToTable("AppSubjectRelationInternalAuthorityRelationVersion", "gr");
});
- modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthCodeEntity", b =>
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AuthCodeEntity", b =>
{
- b.Property("Id")
+ b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
b.Property("Algorithm")
.IsRequired()
@@ -201,13 +201,13 @@ namespace W542.GandalfReborn.Data.Migrations
b.ToTable("AuthCode", "gr");
});
- modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.AuthorityEntity", b =>
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.AuthorityEntity", b =>
{
- b.Property("Id")
+ b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
b.Property("Description")
.HasColumnType("text");
@@ -244,7 +244,7 @@ namespace W542.GandalfReborn.Data.Migrations
});
});
- modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationEntity", b =>
{
b.Property("SubjectId")
.HasColumnType("bigint");
@@ -262,7 +262,7 @@ namespace W542.GandalfReborn.Data.Migrations
b.ToTable("TenantSubjectRelationInternalAuthorityRelation", "gr");
});
- modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.TenantSubjectRelationInternalAuthorityRelationVersionEntity", b =>
{
b.Property("SubjectId")
.HasColumnType("bigint");
@@ -290,13 +290,13 @@ namespace W542.GandalfReborn.Data.Migrations
b.ToTable("TenantSubjectRelationInternalAuthorityRelationVersion", "gr");
});
- modelBuilder.Entity("W542.GandalfReborn.Data.Entities.Security.TokenMetadataEntity", b =>
+ modelBuilder.Entity("Suspectus.Gandalf.Palantir.Data.Entities.Security.TokenMetadataEntity", b =>
{
- b.Property("Id")
+ b.Property