Implemented centralised audit logging
This commit is contained in:
@@ -1,9 +1,14 @@
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Entities;
|
||||
|
||||
namespace PostFundManagement.Infrastructure.Database;
|
||||
|
||||
public sealed class ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : DbContext(options)
|
||||
public sealed class ApplicationDbContext(DbContextOptions<ApplicationDbContext> options,
|
||||
ITenantContextService tenantService) : DbContext(options)
|
||||
{
|
||||
private bool BypassFilter => tenantService.IsAdmin;
|
||||
private long CurrentTenantId => tenantService.TenantId;
|
||||
|
||||
public DbSet<TenantUser> TenantUsers => Set<TenantUser>();
|
||||
|
||||
public DbSet<TenantOrganisation> TenantOrganisations => Set<TenantOrganisation>();
|
||||
@@ -17,13 +22,13 @@ public sealed class ApplicationDbContext(DbContextOptions<ApplicationDbContext>
|
||||
public DbSet<Activity> Activities => Set<Activity>();
|
||||
|
||||
public DbSet<AuditLog> AuditLogs => Set<AuditLog>();
|
||||
|
||||
|
||||
public DbSet<SiteVisit> SiteVisits => Set<SiteVisit>();
|
||||
|
||||
|
||||
public DbSet<ChangeRequest> ChangeRequests => Set<ChangeRequest>();
|
||||
|
||||
public DbSet<ComplianceItem> ComplianceItems => Set<ComplianceItem>();
|
||||
|
||||
|
||||
public DbSet<Issue> Issues => Set<Issue>();
|
||||
|
||||
public DbSet<Outcome> Outcomes => Set<Outcome>();
|
||||
@@ -31,13 +36,13 @@ public sealed class ApplicationDbContext(DbContextOptions<ApplicationDbContext>
|
||||
public DbSet<Beneficiary> Beneficiaries => Set<Beneficiary>();
|
||||
|
||||
public DbSet<Evidence> Evidences => Set<Evidence>();
|
||||
|
||||
|
||||
public DbSet<Risk> Risks => Set<Risk>();
|
||||
|
||||
|
||||
public DbSet<Indicator> Indicators => Set<Indicator>();
|
||||
|
||||
|
||||
public DbSet<Disbursement> Disbursements => Set<Disbursement>();
|
||||
|
||||
|
||||
public DbSet<Milestone> Milestones => Set<Milestone>();
|
||||
|
||||
public DbSet<Budget> Budgets => Set<Budget>();
|
||||
@@ -57,6 +62,38 @@ public sealed class ApplicationDbContext(DbContextOptions<ApplicationDbContext>
|
||||
public DbSet<Portfolio> Portfolios => Set<Portfolio>();
|
||||
|
||||
public DbSet<Instrument> Instruments => Set<Instrument>();
|
||||
|
||||
|
||||
public DbSet<User> Users => Set<User>();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
modelBuilder.Entity<Portfolio>()
|
||||
.HasQueryFilter(e => BypassFilter || e.TenantId == CurrentTenantId);
|
||||
|
||||
modelBuilder.Entity<Programme>()
|
||||
.HasQueryFilter(e => BypassFilter || e.TenantId == CurrentTenantId);
|
||||
|
||||
modelBuilder.Entity<Project>()
|
||||
.HasQueryFilter(e => BypassFilter || e.TenantId == CurrentTenantId);
|
||||
|
||||
modelBuilder.Entity<Award>()
|
||||
.HasQueryFilter(e => BypassFilter || e.TenantId == CurrentTenantId);
|
||||
|
||||
modelBuilder.Entity<Notification>()
|
||||
.HasQueryFilter(e => BypassFilter || e.TenantId == CurrentTenantId);
|
||||
|
||||
modelBuilder.Entity<TenantOrganisation>()
|
||||
.HasQueryFilter(e => BypassFilter || e.TenantId == CurrentTenantId);
|
||||
|
||||
modelBuilder.Entity<TenantUser>()
|
||||
.HasQueryFilter(e => BypassFilter || e.TenantId == CurrentTenantId);
|
||||
|
||||
modelBuilder.Entity<AuditLog>()
|
||||
.HasQueryFilter(e => BypassFilter || e.TenantId == CurrentTenantId);
|
||||
|
||||
modelBuilder.Entity<Organisation>().HasQueryFilter(o => BypassFilter ||
|
||||
Set<TenantOrganisation>().Any(to => to.TenantId == CurrentTenantId && to.OrganisationId == o.Id));
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ using static PostFundManagement.Domain.Extensions.Constants;
|
||||
|
||||
namespace PostFundManagement.Infrastructure.Database.Factories;
|
||||
|
||||
public sealed class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
|
||||
public sealed partial class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
|
||||
{
|
||||
public ApplicationDbContext CreateDbContext(string[] args)
|
||||
{
|
||||
@@ -14,11 +14,14 @@ public sealed class ApplicationDbContextFactory : IDesignTimeDbContextFactory<Ap
|
||||
|
||||
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||
|
||||
var connectionString = configuration.GetConnectionString(DatabaseConfigName)
|
||||
var connectionString = configuration.GetConnectionString(DatabaseConfigName)
|
||||
?? throw new InvalidOperationException($"Connection string '{DatabaseConfigName}' was not found in configuration.");
|
||||
|
||||
optionsBuilder.UseNpgsql(connectionString, npgsqlOptions => npgsqlOptions.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName));
|
||||
|
||||
return new ApplicationDbContext(optionsBuilder.Options);
|
||||
optionsBuilder.UseNpgsql(connectionString, npgsqlOptions =>
|
||||
npgsqlOptions.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName));
|
||||
|
||||
var designTimeTenantService = new DesignTimeTenantContextService();
|
||||
|
||||
return new ApplicationDbContext(optionsBuilder.Options, designTimeTenantService);
|
||||
}
|
||||
}
|
||||
Generated
+2233
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,370 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedTenant : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "TenantId",
|
||||
table: "Projects",
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
defaultValue: 0L);
|
||||
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "TenantId",
|
||||
table: "Programmes",
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
defaultValue: 0L);
|
||||
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "TenantId",
|
||||
table: "Portfolios",
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
defaultValue: 0L);
|
||||
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "TenantId",
|
||||
table: "Notifications",
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
defaultValue: 0L);
|
||||
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "TenantId",
|
||||
table: "Awards",
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
defaultValue: 0L);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Tenants",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
||||
CreatedBy = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
UpdatedBy = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
Name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
||||
Status = table.Column<int>(type: "integer", nullable: false, defaultValueSql: "1")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Tenants", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Tenants_Users_CreatedBy",
|
||||
column: x => x.CreatedBy,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_Tenants_Users_UpdatedBy",
|
||||
column: x => x.UpdatedBy,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TenantOrganisations",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
||||
CreatedBy = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
TenantId = table.Column<long>(type: "bigint", nullable: false),
|
||||
OrganisationId = table.Column<long>(type: "bigint", nullable: false),
|
||||
Status = table.Column<int>(type: "integer", nullable: false, defaultValueSql: "1")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TenantOrganisations", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TenantOrganisations_Organisations_OrganisationId",
|
||||
column: x => x.OrganisationId,
|
||||
principalTable: "Organisations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_TenantOrganisations_Tenants_TenantId",
|
||||
column: x => x.TenantId,
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_TenantOrganisations_Users_CreatedBy",
|
||||
column: x => x.CreatedBy,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TenantUsers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
||||
CreatedBy = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
TenantId = table.Column<long>(type: "bigint", nullable: false),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Status = table.Column<int>(type: "integer", nullable: false, defaultValueSql: "1")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TenantUsers", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TenantUsers_Tenants_TenantId",
|
||||
column: x => x.TenantId,
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_TenantUsers_Users_CreatedBy",
|
||||
column: x => x.CreatedBy,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_TenantUsers_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Projects_TenantId",
|
||||
table: "Projects",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Programmes_TenantId",
|
||||
table: "Programmes",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Portfolios_TenantId",
|
||||
table: "Portfolios",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Notifications_TenantId",
|
||||
table: "Notifications",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Awards_TenantId",
|
||||
table: "Awards",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TenantOrganisations_CreatedBy",
|
||||
table: "TenantOrganisations",
|
||||
column: "CreatedBy");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TenantOrganisations_OrganisationId",
|
||||
table: "TenantOrganisations",
|
||||
column: "OrganisationId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TenantOrganisations_TenantId",
|
||||
table: "TenantOrganisations",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Tenants_CreatedBy",
|
||||
table: "Tenants",
|
||||
column: "CreatedBy");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Tenants_UpdatedBy",
|
||||
table: "Tenants",
|
||||
column: "UpdatedBy");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TenantUsers_CreatedBy",
|
||||
table: "TenantUsers",
|
||||
column: "CreatedBy");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TenantUsers_TenantId",
|
||||
table: "TenantUsers",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TenantUsers_UserId",
|
||||
table: "TenantUsers",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.Sql(@"
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM ""Users"" WHERE ""Id"" = '18caeb45-65f6-4103-9bda-ddf073a24de2'::uuid) THEN
|
||||
INSERT INTO ""Tenants"" (""Id"", ""Name"", ""Status"", ""CreatedBy"", ""CreatedAt"")
|
||||
OVERRIDING SYSTEM VALUE
|
||||
VALUES (1, 'Default Tenant', 1, '18caeb45-65f6-4103-9bda-ddf073a24de2'::uuid, NOW())
|
||||
ON CONFLICT (""Id"") DO NOTHING;
|
||||
ELSE
|
||||
RAISE EXCEPTION 'Target user 18caeb45-65f6-4103-9bda-ddf073a24de2 does not exist in Users table.';
|
||||
END IF;
|
||||
END $$;
|
||||
");
|
||||
|
||||
migrationBuilder.Sql(@"SELECT setval(pg_get_serial_sequence('""Tenants""', 'Id'), GREATEST(coalesce(max(""Id""), 1), 1)) FROM ""Tenants"";");
|
||||
|
||||
migrationBuilder.Sql("UPDATE \"Notifications\" SET \"TenantId\" = 1 WHERE \"TenantId\" = 0;");
|
||||
migrationBuilder.Sql("UPDATE \"Awards\" SET \"TenantId\" = 1 WHERE \"TenantId\" = 0;");
|
||||
migrationBuilder.Sql("UPDATE \"Portfolios\" SET \"TenantId\" = 1 WHERE \"TenantId\" = 0;");
|
||||
migrationBuilder.Sql("UPDATE \"Programmes\" SET \"TenantId\" = 1 WHERE \"TenantId\" = 0;");
|
||||
migrationBuilder.Sql("UPDATE \"Projects\" SET \"TenantId\" = 1 WHERE \"TenantId\" = 0;");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TenantOrganisations_TenantId_OrganisationId",
|
||||
table: "TenantOrganisations",
|
||||
columns: ["TenantId", "OrganisationId"],
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TenantUsers_TenantId_UserId",
|
||||
table: "TenantUsers",
|
||||
columns: ["TenantId", "UserId"],
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Awards_Tenants_TenantId",
|
||||
table: "Awards",
|
||||
column: "TenantId",
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Notifications_Tenants_TenantId",
|
||||
table: "Notifications",
|
||||
column: "TenantId",
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Portfolios_Tenants_TenantId",
|
||||
table: "Portfolios",
|
||||
column: "TenantId",
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Programmes_Tenants_TenantId",
|
||||
table: "Programmes",
|
||||
column: "TenantId",
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Projects_Tenants_TenantId",
|
||||
table: "Projects",
|
||||
column: "TenantId",
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Awards_Tenants_TenantId",
|
||||
table: "Awards");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Notifications_Tenants_TenantId",
|
||||
table: "Notifications");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Portfolios_Tenants_TenantId",
|
||||
table: "Portfolios");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Programmes_Tenants_TenantId",
|
||||
table: "Programmes");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Projects_Tenants_TenantId",
|
||||
table: "Projects");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TenantOrganisations");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TenantUsers");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Tenants");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_TenantOrganisations_TenantId_OrganisationId",
|
||||
table: "TenantOrganisations");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_TenantUsers_TenantId_UserId",
|
||||
table: "TenantUsers");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Projects_TenantId",
|
||||
table: "Projects");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Programmes_TenantId",
|
||||
table: "Programmes");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Portfolios_TenantId",
|
||||
table: "Portfolios");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Notifications_TenantId",
|
||||
table: "Notifications");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Awards_TenantId",
|
||||
table: "Awards");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TenantId",
|
||||
table: "Projects");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TenantId",
|
||||
table: "Programmes");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TenantId",
|
||||
table: "Portfolios");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TenantId",
|
||||
table: "Notifications");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TenantId",
|
||||
table: "Awards");
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+2246
File diff suppressed because it is too large
Load Diff
+64
@@ -0,0 +1,64 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class UpdateAuditLog : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "EntityId",
|
||||
table: "AuditLogs",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
oldClrType: typeof(long),
|
||||
oldType: "bigint");
|
||||
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "TenantId",
|
||||
table: "AuditLogs",
|
||||
type: "bigint",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AuditLogs_TenantId",
|
||||
table: "AuditLogs",
|
||||
column: "TenantId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_AuditLogs_Tenants_TenantId",
|
||||
table: "AuditLogs",
|
||||
column: "TenantId",
|
||||
principalTable: "Tenants",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_AuditLogs_Tenants_TenantId",
|
||||
table: "AuditLogs");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_AuditLogs_TenantId",
|
||||
table: "AuditLogs");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TenantId",
|
||||
table: "AuditLogs");
|
||||
|
||||
migrationBuilder.AlterColumn<long>(
|
||||
name: "EntityId",
|
||||
table: "AuditLogs",
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "text");
|
||||
}
|
||||
}
|
||||
}
|
||||
+270
-3
@@ -17,7 +17,7 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "10.0.11")
|
||||
.HasAnnotation("ProductVersion", "10.0.12")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
@@ -111,8 +111,9 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
b.PrimitiveCollection<string>("Changes")
|
||||
.HasColumnType("jsonb");
|
||||
|
||||
b.Property<long>("EntityId")
|
||||
.HasColumnType("bigint");
|
||||
b.Property<string>("EntityId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("EntityName")
|
||||
.IsRequired()
|
||||
@@ -122,6 +123,9 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
b.Property<Guid>("PerformedBy")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<long?>("TenantId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<DateTime>("Timestamp")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
@@ -131,6 +135,8 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
|
||||
b.HasIndex("PerformedBy");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.ToTable("AuditLogs", (string)null);
|
||||
});
|
||||
|
||||
@@ -171,6 +177,9 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
.HasColumnType("integer")
|
||||
.HasDefaultValueSql("1");
|
||||
|
||||
b.Property<long>("TenantId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
@@ -189,6 +198,8 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
|
||||
b.HasIndex("ProjectId");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.HasIndex("UpdatedBy");
|
||||
|
||||
b.ToTable("Awards", (string)null);
|
||||
@@ -883,6 +894,9 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<long>("TenantId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
@@ -892,6 +906,8 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
|
||||
b.HasIndex("Recipient");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.ToTable("Notifications", (string)null);
|
||||
});
|
||||
|
||||
@@ -1012,6 +1028,9 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
b.Property<Guid>("OwnedBy")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<long>("TenantId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedBy");
|
||||
@@ -1020,6 +1039,8 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
|
||||
b.HasIndex("OwnedBy");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.ToTable("Portfolios", (string)null);
|
||||
});
|
||||
|
||||
@@ -1055,6 +1076,9 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
.HasColumnType("integer")
|
||||
.HasDefaultValueSql("1");
|
||||
|
||||
b.Property<long>("TenantId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
@@ -1069,6 +1093,8 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
|
||||
b.HasIndex("PortfolioId");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.ToTable("Programmes", (string)null);
|
||||
});
|
||||
|
||||
@@ -1122,6 +1148,9 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
.HasColumnType("integer")
|
||||
.HasDefaultValueSql("1");
|
||||
|
||||
b.Property<long>("TenantId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
@@ -1134,6 +1163,8 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
|
||||
b.HasIndex("ProgrammeId");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.HasIndex("UpdatedBy");
|
||||
|
||||
b.ToTable("Projects", (string)null);
|
||||
@@ -1282,6 +1313,123 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
b.ToTable("SiteVisits", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PostFundManagement.Domain.Entities.Tenant", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<Guid>("CreatedBy")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasDefaultValueSql("1");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid?>("UpdatedBy")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedBy");
|
||||
|
||||
b.HasIndex("UpdatedBy");
|
||||
|
||||
b.ToTable("Tenants", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PostFundManagement.Domain.Entities.TenantOrganisation", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<Guid>("CreatedBy")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<long>("OrganisationId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasDefaultValueSql("1");
|
||||
|
||||
b.Property<long>("TenantId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedBy");
|
||||
|
||||
b.HasIndex("OrganisationId");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.ToTable("TenantOrganisations", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PostFundManagement.Domain.Entities.TenantUser", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasDefaultValueSql("now()");
|
||||
|
||||
b.Property<Guid>("CreatedBy")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasDefaultValueSql("1");
|
||||
|
||||
b.Property<long>("TenantId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedBy");
|
||||
|
||||
b.HasIndex("TenantId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("TenantUsers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PostFundManagement.Domain.Entities.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@@ -1355,7 +1503,14 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PostFundManagement.Domain.Entities.Tenant", "Tenant")
|
||||
.WithMany()
|
||||
.HasForeignKey("TenantId")
|
||||
.OnDelete(DeleteBehavior.NoAction);
|
||||
|
||||
b.Navigation("Performer");
|
||||
|
||||
b.Navigation("Tenant");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PostFundManagement.Domain.Entities.Award", b =>
|
||||
@@ -1388,6 +1543,12 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
.HasForeignKey("ProjectId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.HasOne("PostFundManagement.Domain.Entities.Tenant", "Tenant")
|
||||
.WithMany()
|
||||
.HasForeignKey("TenantId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PostFundManagement.Domain.Entities.User", "Updator")
|
||||
.WithMany()
|
||||
.HasForeignKey("UpdatedBy")
|
||||
@@ -1403,6 +1564,8 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
|
||||
b.Navigation("Project");
|
||||
|
||||
b.Navigation("Tenant");
|
||||
|
||||
b.Navigation("Updator");
|
||||
});
|
||||
|
||||
@@ -1761,9 +1924,17 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PostFundManagement.Domain.Entities.Tenant", "Tenant")
|
||||
.WithMany()
|
||||
.HasForeignKey("TenantId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Organisation");
|
||||
|
||||
b.Navigation("RecipientUser");
|
||||
|
||||
b.Navigation("Tenant");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PostFundManagement.Domain.Entities.Organisation", b =>
|
||||
@@ -1816,11 +1987,19 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PostFundManagement.Domain.Entities.Tenant", "Tenant")
|
||||
.WithMany()
|
||||
.HasForeignKey("TenantId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Creator");
|
||||
|
||||
b.Navigation("Organisation");
|
||||
|
||||
b.Navigation("Owner");
|
||||
|
||||
b.Navigation("Tenant");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PostFundManagement.Domain.Entities.Programme", b =>
|
||||
@@ -1843,11 +2022,19 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PostFundManagement.Domain.Entities.Tenant", "Tenant")
|
||||
.WithMany()
|
||||
.HasForeignKey("TenantId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Creator");
|
||||
|
||||
b.Navigation("Owner");
|
||||
|
||||
b.Navigation("Portfolio");
|
||||
|
||||
b.Navigation("Tenant");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PostFundManagement.Domain.Entities.Project", b =>
|
||||
@@ -1864,6 +2051,12 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PostFundManagement.Domain.Entities.Tenant", "Tenant")
|
||||
.WithMany()
|
||||
.HasForeignKey("TenantId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PostFundManagement.Domain.Entities.User", "Updator")
|
||||
.WithMany()
|
||||
.HasForeignKey("UpdatedBy")
|
||||
@@ -1873,6 +2066,8 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
|
||||
b.Navigation("Programme");
|
||||
|
||||
b.Navigation("Tenant");
|
||||
|
||||
b.Navigation("Updator");
|
||||
});
|
||||
|
||||
@@ -1940,6 +2135,78 @@ namespace PostFundManagement.Infrastructure.Database.Migrations
|
||||
b.Navigation("Project");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PostFundManagement.Domain.Entities.Tenant", b =>
|
||||
{
|
||||
b.HasOne("PostFundManagement.Domain.Entities.User", "Creator")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedBy")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PostFundManagement.Domain.Entities.User", "Updator")
|
||||
.WithMany()
|
||||
.HasForeignKey("UpdatedBy")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
b.Navigation("Creator");
|
||||
|
||||
b.Navigation("Updator");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PostFundManagement.Domain.Entities.TenantOrganisation", b =>
|
||||
{
|
||||
b.HasOne("PostFundManagement.Domain.Entities.User", "Creator")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedBy")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PostFundManagement.Domain.Entities.Organisation", "Organisation")
|
||||
.WithMany()
|
||||
.HasForeignKey("OrganisationId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PostFundManagement.Domain.Entities.Tenant", "Tenant")
|
||||
.WithMany()
|
||||
.HasForeignKey("TenantId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Creator");
|
||||
|
||||
b.Navigation("Organisation");
|
||||
|
||||
b.Navigation("Tenant");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PostFundManagement.Domain.Entities.TenantUser", b =>
|
||||
{
|
||||
b.HasOne("PostFundManagement.Domain.Entities.User", "Creator")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedBy")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PostFundManagement.Domain.Entities.Tenant", "Tenant")
|
||||
.WithMany()
|
||||
.HasForeignKey("TenantId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("PostFundManagement.Domain.Entities.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Creator");
|
||||
|
||||
b.Navigation("Tenant");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("PostFundManagement.Domain.Entities.Activity", b =>
|
||||
{
|
||||
b.Navigation("Evidences");
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
|
||||
namespace PostFundManagement.Infrastructure.Database.Factories;
|
||||
|
||||
public sealed partial class ApplicationDbContextFactory
|
||||
{
|
||||
private sealed class DesignTimeTenantContextService : ITenantContextService
|
||||
{
|
||||
public string? TenantName => "Design Time";
|
||||
public long TenantId => 0L;
|
||||
public bool IsAdmin => true;
|
||||
public bool HasTenantFilter => false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
|
||||
namespace PostFundManagement.Infrastructure.Database.Services;
|
||||
|
||||
public sealed class TenantContextService : ITenantContextService
|
||||
{
|
||||
public string? TenantName { get; }
|
||||
|
||||
public long TenantId { get; }
|
||||
|
||||
public bool IsAdmin { get; }
|
||||
|
||||
public bool HasTenantFilter { get; }
|
||||
|
||||
public TenantContextService(IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
var user = httpContextAccessor.HttpContext?.User;
|
||||
|
||||
IsAdmin = user?.IsInRole("Admin") == true || user?.HasClaim("role", "Admin") == true;
|
||||
|
||||
HasTenantFilter = !IsAdmin;
|
||||
|
||||
var tenantIdClaimVal = user?.FindFirst("tenant_id")?.Value ?? user?.FindFirst("TenantId")?.Value;
|
||||
TenantId = long.TryParse(tenantIdClaimVal, out var id) ? id : 0L;
|
||||
|
||||
var tenantNameClaimVal = user?.FindFirst("tenant")?.Value ?? user?.FindFirst("Tenant")?.Value;
|
||||
TenantName = !string.IsNullOrWhiteSpace(tenantNameClaimVal) ? tenantNameClaimVal : null;
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.12" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.12" />
|
||||
|
||||
<Using Include="Microsoft.AspNetCore.Http" />
|
||||
<Using Include="Microsoft.Extensions.Configuration" />
|
||||
<Using Include="Microsoft.Extensions.DependencyInjection" />
|
||||
</ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user