feat: add phase five operations foundation

This commit is contained in:
2026-07-28 09:57:50 +08:00
parent 71793a2de0
commit f22f329d33
39 changed files with 4810 additions and 160 deletions

View File

@@ -13,7 +13,7 @@ using Tiku.Infrastructure.Persistence;
namespace Tiku.Infrastructure.Persistence.Migrations
{
[DbContext(typeof(TikuDbContext))]
[Migration("20260727093301_InitialSchema")]
[Migration("20260728014412_InitialSchema")]
partial class InitialSchema
{
/// <inheritdoc />
@@ -9879,6 +9879,268 @@ namespace Tiku.Infrastructure.Persistence.Migrations
b.ToTable("audit_logs", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.BackendMenu", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<string>("Area")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("area");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("code");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("Icon")
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("icon");
b.Property<bool>("IsActive")
.HasColumnType("boolean")
.HasColumnName("is_active");
b.Property<string>("ParentCode")
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("parent_code");
b.Property<string>("Path")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)")
.HasColumnName("path");
b.Property<string>("PermissionCode")
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("permission_code");
b.Property<int>("SortOrder")
.HasColumnType("integer")
.HasColumnName("sort_order");
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("title");
b.Property<DateTimeOffset>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_backend_menus");
b.HasAlternateKey("Code")
.HasName("ak_backend_menus_code");
b.HasIndex("Code")
.IsUnique()
.HasDatabaseName("ix_backend_menus_code");
b.HasIndex("PermissionCode")
.HasDatabaseName("ix_backend_menus_permission_code");
b.HasIndex("Area", "ParentCode", "SortOrder")
.HasDatabaseName("ix_backend_menus_area_parent_code_sort_order");
b.ToTable("backend_menus", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.BackendPermission", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<string>("Area")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("area");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("code");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("character varying(1000)")
.HasColumnName("description");
b.Property<bool>("IsSystem")
.HasColumnType("boolean")
.HasColumnName("is_system");
b.Property<string>("Module")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("module");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("name");
b.Property<int>("SortOrder")
.HasColumnType("integer")
.HasColumnName("sort_order");
b.Property<DateTimeOffset>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_backend_permissions");
b.HasAlternateKey("Code")
.HasName("ak_backend_permissions_code");
b.HasIndex("Code")
.IsUnique()
.HasDatabaseName("ix_backend_permissions_code");
b.HasIndex("Area", "Module", "SortOrder")
.HasDatabaseName("ix_backend_permissions_area_module_sort_order");
b.ToTable("backend_permissions", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.BackgroundJob", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset?>("CompletedAt")
.HasColumnType("timestamp with time zone")
.HasColumnName("completed_at");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("JobType")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("job_type");
b.Property<string>("LastError")
.HasMaxLength(4000)
.HasColumnType("character varying(4000)")
.HasColumnName("last_error");
b.Property<DateTimeOffset?>("LockExpiresAt")
.HasColumnType("timestamp with time zone")
.HasColumnName("lock_expires_at");
b.Property<string>("LockedBy")
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("locked_by");
b.Property<int>("MaxRetries")
.HasColumnType("integer")
.HasColumnName("max_retries");
b.Property<Guid?>("OutputAssetId")
.HasColumnType("uuid")
.HasColumnName("output_asset_id");
b.Property<JsonElement>("Payload")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("payload")
.HasDefaultValueSql("'{}'::jsonb");
b.Property<JsonElement>("Result")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("result")
.HasDefaultValueSql("'{}'::jsonb");
b.Property<int>("RetryCount")
.HasColumnType("integer")
.HasColumnName("retry_count");
b.Property<DateTimeOffset?>("RunAfter")
.HasColumnType("timestamp with time zone")
.HasColumnName("run_after");
b.Property<DateTimeOffset?>("StartedAt")
.HasColumnType("timestamp with time zone")
.HasColumnName("started_at");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("status");
b.Property<Guid>("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property<DateTimeOffset>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_background_jobs");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_background_jobs_tenant_id_id");
b.HasIndex("TenantId", "OutputAssetId")
.HasDatabaseName("ix_background_jobs_tenant_id_output_asset_id");
b.HasIndex("TenantId", "JobType", "Status", "CreatedAt")
.HasDatabaseName("ix_background_jobs_tenant_id_job_type_status_created_at");
b.HasIndex("TenantId", "Status", "RunAfter", "CreatedAt")
.HasDatabaseName("ix_background_jobs_tenant_id_status_run_after_created_at");
b.ToTable("background_jobs", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.Badge", b =>
{
b.Property<Guid>("Id")
@@ -10138,6 +10400,381 @@ namespace Tiku.Infrastructure.Persistence.Migrations
b.ToTable("faqs", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("code");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("character varying(1000)")
.HasColumnName("description");
b.Property<bool>("IsSystem")
.HasColumnType("boolean")
.HasColumnName("is_system");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("name");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("status");
b.Property<DateTimeOffset>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_platform_backend_roles");
b.HasIndex("Code")
.IsUnique()
.HasDatabaseName("ix_platform_backend_roles_code");
b.HasIndex("Status", "Code")
.HasDatabaseName("ix_platform_backend_roles_status_code");
b.ToTable("platform_backend_roles", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendRoleMenu", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("MenuCode")
.IsRequired()
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("menu_code");
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id");
b.HasKey("Id")
.HasName("pk_platform_backend_role_menus");
b.HasIndex("MenuCode")
.HasDatabaseName("ix_platform_backend_role_menus_menu_code");
b.HasIndex("RoleId", "MenuCode")
.IsUnique()
.HasDatabaseName("ix_platform_backend_role_menus_role_id_menu_code");
b.ToTable("platform_backend_role_menus", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendRolePermission", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("PermissionCode")
.IsRequired()
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("permission_code");
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id");
b.HasKey("Id")
.HasName("pk_platform_backend_role_permissions");
b.HasIndex("PermissionCode")
.HasDatabaseName("ix_platform_backend_role_permissions_permission_code");
b.HasIndex("RoleId", "PermissionCode")
.IsUnique()
.HasDatabaseName("ix_platform_backend_role_permissions_role_id_permission_code");
b.ToTable("platform_backend_role_permissions", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendUserRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id");
b.Property<Guid>("UserId")
.HasColumnType("uuid")
.HasColumnName("user_id");
b.HasKey("Id")
.HasName("pk_platform_backend_user_roles");
b.HasIndex("RoleId")
.HasDatabaseName("ix_platform_backend_user_roles_role_id");
b.HasIndex("UserId", "RoleId")
.IsUnique()
.HasDatabaseName("ix_platform_backend_user_roles_user_id_role_id");
b.ToTable("platform_backend_user_roles", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("code");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<JsonElement>("DataScope")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("data_scope")
.HasDefaultValueSql("'{}'::jsonb");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("character varying(1000)")
.HasColumnName("description");
b.Property<bool>("IsSystem")
.HasColumnType("boolean")
.HasColumnName("is_system");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("name");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("status");
b.Property<Guid>("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property<DateTimeOffset>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_tenant_backend_roles");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_tenant_backend_roles_tenant_id_id");
b.HasIndex("TenantId", "Code")
.IsUnique()
.HasDatabaseName("ix_tenant_backend_roles_tenant_id_code");
b.HasIndex("TenantId", "Status", "Code")
.HasDatabaseName("ix_tenant_backend_roles_tenant_id_status_code");
b.ToTable("tenant_backend_roles", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendRoleMenu", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("MenuCode")
.IsRequired()
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("menu_code");
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id");
b.Property<Guid>("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.HasKey("Id")
.HasName("pk_tenant_backend_role_menus");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_tenant_backend_role_menus_tenant_id_id");
b.HasIndex("MenuCode")
.HasDatabaseName("ix_tenant_backend_role_menus_menu_code");
b.HasIndex("TenantId", "RoleId", "MenuCode")
.IsUnique()
.HasDatabaseName("ix_tenant_backend_role_menus_tenant_id_role_id_menu_code");
b.ToTable("tenant_backend_role_menus", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendRolePermission", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("PermissionCode")
.IsRequired()
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("permission_code");
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id");
b.Property<Guid>("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.HasKey("Id")
.HasName("pk_tenant_backend_role_permissions");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_tenant_backend_role_permissions_tenant_id_id");
b.HasIndex("PermissionCode")
.HasDatabaseName("ix_tenant_backend_role_permissions_permission_code");
b.HasIndex("TenantId", "RoleId", "PermissionCode")
.IsUnique()
.HasDatabaseName("ix_tenant_backend_role_permissions_tenant_id_role_id_permissio~");
b.ToTable("tenant_backend_role_permissions", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendUserRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id");
b.Property<Guid>("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property<Guid>("UserId")
.HasColumnType("uuid")
.HasColumnName("user_id");
b.HasKey("Id")
.HasName("pk_tenant_backend_user_roles");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_tenant_backend_user_roles_tenant_id_id");
b.HasIndex("UserId")
.HasDatabaseName("ix_tenant_backend_user_roles_user_id");
b.HasIndex("TenantId", "RoleId")
.HasDatabaseName("ix_tenant_backend_user_roles_tenant_id_role_id");
b.HasIndex("TenantId", "UserId", "RoleId")
.IsUnique()
.HasDatabaseName("ix_tenant_backend_user_roles_tenant_id_user_id_role_id");
b.ToTable("tenant_backend_user_roles", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantContentNotification", b =>
{
b.Property<Guid>("Id")
@@ -15994,6 +16631,33 @@ namespace Tiku.Infrastructure.Persistence.Migrations
.HasConstraintName("fk_audit_logs_tenants_tenant_id");
});
modelBuilder.Entity("Tiku.Domain.Operations.BackendMenu", b =>
{
b.HasOne("Tiku.Domain.Operations.BackendPermission", null)
.WithMany()
.HasForeignKey("PermissionCode")
.HasPrincipalKey("Code")
.OnDelete(DeleteBehavior.SetNull)
.HasConstraintName("fk_backend_menus_backend_permissions_permission_code");
});
modelBuilder.Entity("Tiku.Domain.Operations.BackgroundJob", b =>
{
b.HasOne("Tiku.Domain.Tenancy.Tenant", null)
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_background_jobs_tenants_tenant_id");
b.HasOne("Tiku.Domain.Content.ContentAsset", null)
.WithMany()
.HasForeignKey("TenantId", "OutputAssetId")
.HasPrincipalKey("TenantId", "Id")
.OnDelete(DeleteBehavior.SetNull)
.HasConstraintName("fk_background_jobs_content_assets_tenant_id_output_asset_id");
});
modelBuilder.Entity("Tiku.Domain.Operations.Badge", b =>
{
b.HasOne("Tiku.Domain.Tenancy.Tenant", null)
@@ -16038,6 +16702,125 @@ namespace Tiku.Infrastructure.Persistence.Migrations
.HasConstraintName("fk_faqs_regions_tenant_id_region_id");
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendRoleMenu", b =>
{
b.HasOne("Tiku.Domain.Operations.BackendMenu", null)
.WithMany()
.HasForeignKey("MenuCode")
.HasPrincipalKey("Code")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("fk_platform_backend_role_menus_backend_menus_menu_code");
b.HasOne("Tiku.Domain.Operations.PlatformBackendRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_platform_backend_role_menus_platform_backend_roles_role_id");
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendRolePermission", b =>
{
b.HasOne("Tiku.Domain.Operations.BackendPermission", null)
.WithMany()
.HasForeignKey("PermissionCode")
.HasPrincipalKey("Code")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("fk_platform_backend_role_permissions_backend_permissions_permi~");
b.HasOne("Tiku.Domain.Operations.PlatformBackendRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_platform_backend_role_permissions_platform_backend_roles_ro~");
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendUserRole", b =>
{
b.HasOne("Tiku.Domain.Operations.PlatformBackendRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_platform_backend_user_roles_platform_backend_roles_role_id");
b.HasOne("Tiku.Domain.Identity.User", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_platform_backend_user_roles_users_user_id");
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendRole", b =>
{
b.HasOne("Tiku.Domain.Tenancy.Tenant", null)
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_tenant_backend_roles_tenants_tenant_id");
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendRoleMenu", b =>
{
b.HasOne("Tiku.Domain.Operations.BackendMenu", null)
.WithMany()
.HasForeignKey("MenuCode")
.HasPrincipalKey("Code")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("fk_tenant_backend_role_menus_backend_menus_menu_code");
b.HasOne("Tiku.Domain.Operations.TenantBackendRole", null)
.WithMany()
.HasForeignKey("TenantId", "RoleId")
.HasPrincipalKey("TenantId", "Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_tenant_backend_role_menus_tenant_backend_roles_tenant_id_ro~");
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendRolePermission", b =>
{
b.HasOne("Tiku.Domain.Operations.BackendPermission", null)
.WithMany()
.HasForeignKey("PermissionCode")
.HasPrincipalKey("Code")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("fk_tenant_backend_role_permissions_backend_permissions_permiss~");
b.HasOne("Tiku.Domain.Operations.TenantBackendRole", null)
.WithMany()
.HasForeignKey("TenantId", "RoleId")
.HasPrincipalKey("TenantId", "Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_tenant_backend_role_permissions_tenant_backend_roles_tenant~");
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendUserRole", b =>
{
b.HasOne("Tiku.Domain.Identity.User", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_tenant_backend_user_roles_users_user_id");
b.HasOne("Tiku.Domain.Operations.TenantBackendRole", null)
.WithMany()
.HasForeignKey("TenantId", "RoleId")
.HasPrincipalKey("TenantId", "Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_tenant_backend_user_roles_tenant_backend_roles_tenant_id_ro~");
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantContentNotification", b =>
{
b.HasOne("Tiku.Domain.Identity.User", null)

View File

@@ -1,6 +1,7 @@
using System;
using System.Text.Json;
using Microsoft.EntityFrameworkCore.Migrations;
using Tiku.Infrastructure.Persistence;
#nullable disable
@@ -16,6 +17,45 @@ namespace Tiku.Infrastructure.Persistence.Migrations
.Annotation("Npgsql:PostgresExtension:citext", ",,")
.Annotation("Npgsql:PostgresExtension:ltree", ",,");
migrationBuilder.CreateTable(
name: "backend_permissions",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: false),
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
area = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
module = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
description = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
is_system = table.Column<bool>(type: "boolean", nullable: false),
sort_order = table.Column<int>(type: "integer", nullable: false),
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
},
constraints: table =>
{
table.PrimaryKey("pk_backend_permissions", x => x.id);
table.UniqueConstraint("ak_backend_permissions_code", x => x.code);
});
migrationBuilder.CreateTable(
name: "platform_backend_roles",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
is_system = table.Column<bool>(type: "boolean", nullable: false),
description = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
},
constraints: table =>
{
table.PrimaryKey("pk_platform_backend_roles", x => x.id);
});
migrationBuilder.CreateTable(
name: "platform_dunning_notification_channels",
columns: table => new
@@ -116,6 +156,87 @@ namespace Tiku.Infrastructure.Persistence.Migrations
table.PrimaryKey("pk_users", x => x.id);
});
migrationBuilder.CreateTable(
name: "backend_menus",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: false),
parent_code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: true),
title = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
area = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
path = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
icon = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
permission_code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: true),
sort_order = table.Column<int>(type: "integer", nullable: false),
is_active = table.Column<bool>(type: "boolean", nullable: false),
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
},
constraints: table =>
{
table.PrimaryKey("pk_backend_menus", x => x.id);
table.UniqueConstraint("ak_backend_menus_code", x => x.code);
table.ForeignKey(
name: "fk_backend_menus_backend_permissions_permission_code",
column: x => x.permission_code,
principalTable: "backend_permissions",
principalColumn: "code",
onDelete: ReferentialAction.SetNull);
});
migrationBuilder.CreateTable(
name: "platform_backend_role_permissions",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
role_id = table.Column<Guid>(type: "uuid", nullable: false),
permission_code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: false),
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
},
constraints: table =>
{
table.PrimaryKey("pk_platform_backend_role_permissions", x => x.id);
table.ForeignKey(
name: "fk_platform_backend_role_permissions_backend_permissions_permi~",
column: x => x.permission_code,
principalTable: "backend_permissions",
principalColumn: "code",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "fk_platform_backend_role_permissions_platform_backend_roles_ro~",
column: x => x.role_id,
principalTable: "platform_backend_roles",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "platform_backend_user_roles",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
user_id = table.Column<Guid>(type: "uuid", nullable: false),
role_id = table.Column<Guid>(type: "uuid", nullable: false),
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
},
constraints: table =>
{
table.PrimaryKey("pk_platform_backend_user_roles", x => x.id);
table.ForeignKey(
name: "fk_platform_backend_user_roles_platform_backend_roles_role_id",
column: x => x.role_id,
principalTable: "platform_backend_roles",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_platform_backend_user_roles_users_user_id",
column: x => x.user_id,
principalTable: "users",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "tenants",
columns: table => new
@@ -171,6 +292,32 @@ namespace Tiku.Infrastructure.Persistence.Migrations
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "platform_backend_role_menus",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
role_id = table.Column<Guid>(type: "uuid", nullable: false),
menu_code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: false),
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
},
constraints: table =>
{
table.PrimaryKey("pk_platform_backend_role_menus", x => x.id);
table.ForeignKey(
name: "fk_platform_backend_role_menus_backend_menus_menu_code",
column: x => x.menu_code,
principalTable: "backend_menus",
principalColumn: "code",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "fk_platform_backend_role_menus_platform_backend_roles_role_id",
column: x => x.role_id,
principalTable: "platform_backend_roles",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "announcements",
columns: table => new
@@ -1087,6 +1234,33 @@ namespace Tiku.Infrastructure.Persistence.Migrations
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "tenant_backend_roles",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
is_system = table.Column<bool>(type: "boolean", nullable: false),
description = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
data_scope = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
},
constraints: table =>
{
table.PrimaryKey("pk_tenant_backend_roles", x => x.id);
table.UniqueConstraint("ak_tenant_backend_roles_tenant_id_id", x => new { x.tenant_id, x.id });
table.ForeignKey(
name: "fk_tenant_backend_roles_tenants_tenant_id",
column: x => x.tenant_id,
principalTable: "tenants",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "tenant_billing_profiles",
columns: table => new
@@ -2499,6 +2673,90 @@ namespace Tiku.Infrastructure.Persistence.Migrations
onDelete: ReferentialAction.SetNull);
});
migrationBuilder.CreateTable(
name: "tenant_backend_role_menus",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
role_id = table.Column<Guid>(type: "uuid", nullable: false),
menu_code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: false),
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
},
constraints: table =>
{
table.PrimaryKey("pk_tenant_backend_role_menus", x => x.id);
table.UniqueConstraint("ak_tenant_backend_role_menus_tenant_id_id", x => new { x.tenant_id, x.id });
table.ForeignKey(
name: "fk_tenant_backend_role_menus_backend_menus_menu_code",
column: x => x.menu_code,
principalTable: "backend_menus",
principalColumn: "code",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "fk_tenant_backend_role_menus_tenant_backend_roles_tenant_id_ro~",
columns: x => new { x.tenant_id, x.role_id },
principalTable: "tenant_backend_roles",
principalColumns: new[] { "tenant_id", "id" },
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "tenant_backend_role_permissions",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
role_id = table.Column<Guid>(type: "uuid", nullable: false),
permission_code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: false),
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
},
constraints: table =>
{
table.PrimaryKey("pk_tenant_backend_role_permissions", x => x.id);
table.UniqueConstraint("ak_tenant_backend_role_permissions_tenant_id_id", x => new { x.tenant_id, x.id });
table.ForeignKey(
name: "fk_tenant_backend_role_permissions_backend_permissions_permiss~",
column: x => x.permission_code,
principalTable: "backend_permissions",
principalColumn: "code",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "fk_tenant_backend_role_permissions_tenant_backend_roles_tenant~",
columns: x => new { x.tenant_id, x.role_id },
principalTable: "tenant_backend_roles",
principalColumns: new[] { "tenant_id", "id" },
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "tenant_backend_user_roles",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
user_id = table.Column<Guid>(type: "uuid", nullable: false),
role_id = table.Column<Guid>(type: "uuid", nullable: false),
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
},
constraints: table =>
{
table.PrimaryKey("pk_tenant_backend_user_roles", x => x.id);
table.UniqueConstraint("ak_tenant_backend_user_roles_tenant_id_id", x => new { x.tenant_id, x.id });
table.ForeignKey(
name: "fk_tenant_backend_user_roles_tenant_backend_roles_tenant_id_ro~",
columns: x => new { x.tenant_id, x.role_id },
principalTable: "tenant_backend_roles",
principalColumns: new[] { "tenant_id", "id" },
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_tenant_backend_user_roles_users_user_id",
column: x => x.user_id,
principalTable: "users",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "tenant_invoice_items",
columns: table => new
@@ -4799,6 +5057,46 @@ namespace Tiku.Infrastructure.Persistence.Migrations
onDelete: ReferentialAction.SetNull);
});
migrationBuilder.CreateTable(
name: "background_jobs",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
job_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
retry_count = table.Column<int>(type: "integer", nullable: false),
max_retries = table.Column<int>(type: "integer", nullable: false),
locked_by = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
lock_expires_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
run_after = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
started_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
completed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
last_error = table.Column<string>(type: "character varying(4000)", maxLength: 4000, nullable: true),
output_asset_id = table.Column<Guid>(type: "uuid", nullable: true),
result = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
},
constraints: table =>
{
table.PrimaryKey("pk_background_jobs", x => x.id);
table.UniqueConstraint("ak_background_jobs_tenant_id_id", x => new { x.tenant_id, x.id });
table.ForeignKey(
name: "fk_background_jobs_content_assets_tenant_id_output_asset_id",
columns: x => new { x.tenant_id, x.output_asset_id },
principalTable: "content_assets",
principalColumns: new[] { "tenant_id", "id" },
onDelete: ReferentialAction.SetNull);
table.ForeignKey(
name: "fk_background_jobs_tenants_tenant_id",
column: x => x.tenant_id,
principalTable: "tenants",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "commission_settlement_proofs",
columns: table => new
@@ -6121,6 +6419,48 @@ namespace Tiku.Infrastructure.Persistence.Migrations
table: "auth_sessions",
column: "user_id");
migrationBuilder.CreateIndex(
name: "ix_backend_menus_area_parent_code_sort_order",
table: "backend_menus",
columns: new[] { "area", "parent_code", "sort_order" });
migrationBuilder.CreateIndex(
name: "ix_backend_menus_code",
table: "backend_menus",
column: "code",
unique: true);
migrationBuilder.CreateIndex(
name: "ix_backend_menus_permission_code",
table: "backend_menus",
column: "permission_code");
migrationBuilder.CreateIndex(
name: "ix_backend_permissions_area_module_sort_order",
table: "backend_permissions",
columns: new[] { "area", "module", "sort_order" });
migrationBuilder.CreateIndex(
name: "ix_backend_permissions_code",
table: "backend_permissions",
column: "code",
unique: true);
migrationBuilder.CreateIndex(
name: "ix_background_jobs_tenant_id_job_type_status_created_at",
table: "background_jobs",
columns: new[] { "tenant_id", "job_type", "status", "created_at" });
migrationBuilder.CreateIndex(
name: "ix_background_jobs_tenant_id_output_asset_id",
table: "background_jobs",
columns: new[] { "tenant_id", "output_asset_id" });
migrationBuilder.CreateIndex(
name: "ix_background_jobs_tenant_id_status_run_after_created_at",
table: "background_jobs",
columns: new[] { "tenant_id", "status", "run_after", "created_at" });
migrationBuilder.CreateIndex(
name: "ix_badges_tenant_id_category_is_active_sort_order",
table: "badges",
@@ -7129,6 +7469,50 @@ namespace Tiku.Infrastructure.Persistence.Migrations
table: "platform_audit_alerts",
columns: new[] { "tenant_id", "status", "created_at" });
migrationBuilder.CreateIndex(
name: "ix_platform_backend_role_menus_menu_code",
table: "platform_backend_role_menus",
column: "menu_code");
migrationBuilder.CreateIndex(
name: "ix_platform_backend_role_menus_role_id_menu_code",
table: "platform_backend_role_menus",
columns: new[] { "role_id", "menu_code" },
unique: true);
migrationBuilder.CreateIndex(
name: "ix_platform_backend_role_permissions_permission_code",
table: "platform_backend_role_permissions",
column: "permission_code");
migrationBuilder.CreateIndex(
name: "ix_platform_backend_role_permissions_role_id_permission_code",
table: "platform_backend_role_permissions",
columns: new[] { "role_id", "permission_code" },
unique: true);
migrationBuilder.CreateIndex(
name: "ix_platform_backend_roles_code",
table: "platform_backend_roles",
column: "code",
unique: true);
migrationBuilder.CreateIndex(
name: "ix_platform_backend_roles_status_code",
table: "platform_backend_roles",
columns: new[] { "status", "code" });
migrationBuilder.CreateIndex(
name: "ix_platform_backend_user_roles_role_id",
table: "platform_backend_user_roles",
column: "role_id");
migrationBuilder.CreateIndex(
name: "ix_platform_backend_user_roles_user_id_role_id",
table: "platform_backend_user_roles",
columns: new[] { "user_id", "role_id" },
unique: true);
migrationBuilder.CreateIndex(
name: "ix_platform_dunning_notification_channels_channel_code",
table: "platform_dunning_notification_channels",
@@ -7973,6 +8357,55 @@ namespace Tiku.Infrastructure.Persistence.Migrations
columns: new[] { "tenant_id", "code" },
unique: true);
migrationBuilder.CreateIndex(
name: "ix_tenant_backend_role_menus_menu_code",
table: "tenant_backend_role_menus",
column: "menu_code");
migrationBuilder.CreateIndex(
name: "ix_tenant_backend_role_menus_tenant_id_role_id_menu_code",
table: "tenant_backend_role_menus",
columns: new[] { "tenant_id", "role_id", "menu_code" },
unique: true);
migrationBuilder.CreateIndex(
name: "ix_tenant_backend_role_permissions_permission_code",
table: "tenant_backend_role_permissions",
column: "permission_code");
migrationBuilder.CreateIndex(
name: "ix_tenant_backend_role_permissions_tenant_id_role_id_permissio~",
table: "tenant_backend_role_permissions",
columns: new[] { "tenant_id", "role_id", "permission_code" },
unique: true);
migrationBuilder.CreateIndex(
name: "ix_tenant_backend_roles_tenant_id_code",
table: "tenant_backend_roles",
columns: new[] { "tenant_id", "code" },
unique: true);
migrationBuilder.CreateIndex(
name: "ix_tenant_backend_roles_tenant_id_status_code",
table: "tenant_backend_roles",
columns: new[] { "tenant_id", "status", "code" });
migrationBuilder.CreateIndex(
name: "ix_tenant_backend_user_roles_tenant_id_role_id",
table: "tenant_backend_user_roles",
columns: new[] { "tenant_id", "role_id" });
migrationBuilder.CreateIndex(
name: "ix_tenant_backend_user_roles_tenant_id_user_id_role_id",
table: "tenant_backend_user_roles",
columns: new[] { "tenant_id", "user_id", "role_id" },
unique: true);
migrationBuilder.CreateIndex(
name: "ix_tenant_backend_user_roles_user_id",
table: "tenant_backend_user_roles",
column: "user_id");
migrationBuilder.CreateIndex(
name: "ix_tenant_class_members_tenant_id_class_id_status_member_type",
table: "tenant_class_members",
@@ -8686,64 +9119,14 @@ namespace Tiku.Infrastructure.Persistence.Migrations
principalColumns: new[] { "tenant_id", "id" },
onDelete: ReferentialAction.SetNull);
migrationBuilder.Sql("""
create or replace function validate_tenant_question_reference()
returns trigger language plpgsql as $$
declare owner_mode text;
begin
select mode into owner_mode from tenants where id = new.question_owner_tenant_id;
if new.question_owner_tenant_id = new.tenant_id then
if new.source <> 'tenant' then raise exception 'A tenant-owned question reference must use tenant source'; end if;
elsif owner_mode = 'platform_owned' then
if new.source <> 'platform' then raise exception 'A platform-owned question reference must use platform source'; end if;
else
raise exception 'A tenant cannot reference another tenant private question';
end if;
return new;
end $$;
create trigger trg_validate_tenant_question_reference before insert or update on tenant_question_references
for each row execute function validate_tenant_question_reference();
create or replace function validate_taxonomy_owner_boundary()
returns trigger language plpgsql as $$
declare parent_mode text;
begin
if new.parent_owner_tenant_id is null or new.parent_owner_tenant_id = new.tenant_id then return new; end if;
select mode into parent_mode from tenants where id = new.parent_owner_tenant_id;
if parent_mode <> 'platform_owned' then
raise exception 'A taxonomy node can only extend platform or current tenant taxonomy';
end if;
return new;
end $$;
create trigger trg_validate_taxonomy_owner_boundary before insert or update on taxonomy_nodes
for each row execute function validate_taxonomy_owner_boundary();
create or replace function validate_question_bank_preference()
returns trigger language plpgsql as $$
declare owner_mode text;
begin
select mode into owner_mode from tenants where id = new.question_bank_owner_tenant_id;
if owner_mode <> 'platform_owned' then
raise exception 'Question bank preferences can only target platform-owned banks';
end if;
return new;
end $$;
create trigger trg_validate_question_bank_preference before insert or update on tenant_question_bank_preferences
for each row execute function validate_question_bank_preference();
""");
migrationBuilder.Sql(PostgreSqlTenantConstraintSql.CreateTenantQuestionReferenceGuard);
migrationBuilder.Sql(PostgreSqlTenantConstraintSql.CreateTaxonomyParentGuard);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("""
drop trigger if exists trg_validate_question_bank_preference on tenant_question_bank_preferences;
drop function if exists validate_question_bank_preference();
drop trigger if exists trg_validate_taxonomy_owner_boundary on taxonomy_nodes;
drop function if exists validate_taxonomy_owner_boundary();
drop trigger if exists trg_validate_tenant_question_reference on tenant_question_references;
drop function if exists validate_tenant_question_reference();
""");
migrationBuilder.Sql(PostgreSqlTenantConstraintSql.DropTenantGuards);
migrationBuilder.DropForeignKey(
name: "fk_content_entries_regions_tenant_id_region_id",
@@ -8970,6 +9353,9 @@ namespace Tiku.Infrastructure.Persistence.Migrations
migrationBuilder.DropTable(
name: "auth_sessions");
migrationBuilder.DropTable(
name: "background_jobs");
migrationBuilder.DropTable(
name: "banners");
@@ -9042,6 +9428,15 @@ namespace Tiku.Infrastructure.Persistence.Migrations
migrationBuilder.DropTable(
name: "platform_audit_alerts");
migrationBuilder.DropTable(
name: "platform_backend_role_menus");
migrationBuilder.DropTable(
name: "platform_backend_role_permissions");
migrationBuilder.DropTable(
name: "platform_backend_user_roles");
migrationBuilder.DropTable(
name: "platform_dunning_notification_events");
@@ -9114,6 +9509,15 @@ namespace Tiku.Infrastructure.Persistence.Migrations
migrationBuilder.DropTable(
name: "subject_shares");
migrationBuilder.DropTable(
name: "tenant_backend_role_menus");
migrationBuilder.DropTable(
name: "tenant_backend_role_permissions");
migrationBuilder.DropTable(
name: "tenant_backend_user_roles");
migrationBuilder.DropTable(
name: "tenant_billing_profiles");
@@ -9225,6 +9629,9 @@ namespace Tiku.Infrastructure.Persistence.Migrations
migrationBuilder.DropTable(
name: "platform_audit_alert_rules");
migrationBuilder.DropTable(
name: "platform_backend_roles");
migrationBuilder.DropTable(
name: "platform_dunning_notification_channels");
@@ -9249,6 +9656,12 @@ namespace Tiku.Infrastructure.Persistence.Migrations
migrationBuilder.DropTable(
name: "reports");
migrationBuilder.DropTable(
name: "backend_menus");
migrationBuilder.DropTable(
name: "tenant_backend_roles");
migrationBuilder.DropTable(
name: "tenant_role_templates");
@@ -9285,6 +9698,9 @@ namespace Tiku.Infrastructure.Persistence.Migrations
migrationBuilder.DropTable(
name: "practice_sessions");
migrationBuilder.DropTable(
name: "backend_permissions");
migrationBuilder.DropTable(
name: "vocabulary_units");

View File

@@ -9876,6 +9876,268 @@ namespace Tiku.Infrastructure.Persistence.Migrations
b.ToTable("audit_logs", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.BackendMenu", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<string>("Area")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("area");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("code");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("Icon")
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("icon");
b.Property<bool>("IsActive")
.HasColumnType("boolean")
.HasColumnName("is_active");
b.Property<string>("ParentCode")
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("parent_code");
b.Property<string>("Path")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)")
.HasColumnName("path");
b.Property<string>("PermissionCode")
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("permission_code");
b.Property<int>("SortOrder")
.HasColumnType("integer")
.HasColumnName("sort_order");
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("title");
b.Property<DateTimeOffset>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_backend_menus");
b.HasAlternateKey("Code")
.HasName("ak_backend_menus_code");
b.HasIndex("Code")
.IsUnique()
.HasDatabaseName("ix_backend_menus_code");
b.HasIndex("PermissionCode")
.HasDatabaseName("ix_backend_menus_permission_code");
b.HasIndex("Area", "ParentCode", "SortOrder")
.HasDatabaseName("ix_backend_menus_area_parent_code_sort_order");
b.ToTable("backend_menus", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.BackendPermission", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<string>("Area")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("area");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("code");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("character varying(1000)")
.HasColumnName("description");
b.Property<bool>("IsSystem")
.HasColumnType("boolean")
.HasColumnName("is_system");
b.Property<string>("Module")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("module");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("name");
b.Property<int>("SortOrder")
.HasColumnType("integer")
.HasColumnName("sort_order");
b.Property<DateTimeOffset>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_backend_permissions");
b.HasAlternateKey("Code")
.HasName("ak_backend_permissions_code");
b.HasIndex("Code")
.IsUnique()
.HasDatabaseName("ix_backend_permissions_code");
b.HasIndex("Area", "Module", "SortOrder")
.HasDatabaseName("ix_backend_permissions_area_module_sort_order");
b.ToTable("backend_permissions", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.BackgroundJob", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset?>("CompletedAt")
.HasColumnType("timestamp with time zone")
.HasColumnName("completed_at");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("JobType")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("job_type");
b.Property<string>("LastError")
.HasMaxLength(4000)
.HasColumnType("character varying(4000)")
.HasColumnName("last_error");
b.Property<DateTimeOffset?>("LockExpiresAt")
.HasColumnType("timestamp with time zone")
.HasColumnName("lock_expires_at");
b.Property<string>("LockedBy")
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("locked_by");
b.Property<int>("MaxRetries")
.HasColumnType("integer")
.HasColumnName("max_retries");
b.Property<Guid?>("OutputAssetId")
.HasColumnType("uuid")
.HasColumnName("output_asset_id");
b.Property<JsonElement>("Payload")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("payload")
.HasDefaultValueSql("'{}'::jsonb");
b.Property<JsonElement>("Result")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("result")
.HasDefaultValueSql("'{}'::jsonb");
b.Property<int>("RetryCount")
.HasColumnType("integer")
.HasColumnName("retry_count");
b.Property<DateTimeOffset?>("RunAfter")
.HasColumnType("timestamp with time zone")
.HasColumnName("run_after");
b.Property<DateTimeOffset?>("StartedAt")
.HasColumnType("timestamp with time zone")
.HasColumnName("started_at");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("status");
b.Property<Guid>("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property<DateTimeOffset>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_background_jobs");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_background_jobs_tenant_id_id");
b.HasIndex("TenantId", "OutputAssetId")
.HasDatabaseName("ix_background_jobs_tenant_id_output_asset_id");
b.HasIndex("TenantId", "JobType", "Status", "CreatedAt")
.HasDatabaseName("ix_background_jobs_tenant_id_job_type_status_created_at");
b.HasIndex("TenantId", "Status", "RunAfter", "CreatedAt")
.HasDatabaseName("ix_background_jobs_tenant_id_status_run_after_created_at");
b.ToTable("background_jobs", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.Badge", b =>
{
b.Property<Guid>("Id")
@@ -10135,6 +10397,381 @@ namespace Tiku.Infrastructure.Persistence.Migrations
b.ToTable("faqs", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("code");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("character varying(1000)")
.HasColumnName("description");
b.Property<bool>("IsSystem")
.HasColumnType("boolean")
.HasColumnName("is_system");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("name");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("status");
b.Property<DateTimeOffset>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_platform_backend_roles");
b.HasIndex("Code")
.IsUnique()
.HasDatabaseName("ix_platform_backend_roles_code");
b.HasIndex("Status", "Code")
.HasDatabaseName("ix_platform_backend_roles_status_code");
b.ToTable("platform_backend_roles", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendRoleMenu", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("MenuCode")
.IsRequired()
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("menu_code");
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id");
b.HasKey("Id")
.HasName("pk_platform_backend_role_menus");
b.HasIndex("MenuCode")
.HasDatabaseName("ix_platform_backend_role_menus_menu_code");
b.HasIndex("RoleId", "MenuCode")
.IsUnique()
.HasDatabaseName("ix_platform_backend_role_menus_role_id_menu_code");
b.ToTable("platform_backend_role_menus", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendRolePermission", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("PermissionCode")
.IsRequired()
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("permission_code");
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id");
b.HasKey("Id")
.HasName("pk_platform_backend_role_permissions");
b.HasIndex("PermissionCode")
.HasDatabaseName("ix_platform_backend_role_permissions_permission_code");
b.HasIndex("RoleId", "PermissionCode")
.IsUnique()
.HasDatabaseName("ix_platform_backend_role_permissions_role_id_permission_code");
b.ToTable("platform_backend_role_permissions", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendUserRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id");
b.Property<Guid>("UserId")
.HasColumnType("uuid")
.HasColumnName("user_id");
b.HasKey("Id")
.HasName("pk_platform_backend_user_roles");
b.HasIndex("RoleId")
.HasDatabaseName("ix_platform_backend_user_roles_role_id");
b.HasIndex("UserId", "RoleId")
.IsUnique()
.HasDatabaseName("ix_platform_backend_user_roles_user_id_role_id");
b.ToTable("platform_backend_user_roles", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("code");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<JsonElement>("DataScope")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("data_scope")
.HasDefaultValueSql("'{}'::jsonb");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("character varying(1000)")
.HasColumnName("description");
b.Property<bool>("IsSystem")
.HasColumnType("boolean")
.HasColumnName("is_system");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("name");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("status");
b.Property<Guid>("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property<DateTimeOffset>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_tenant_backend_roles");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_tenant_backend_roles_tenant_id_id");
b.HasIndex("TenantId", "Code")
.IsUnique()
.HasDatabaseName("ix_tenant_backend_roles_tenant_id_code");
b.HasIndex("TenantId", "Status", "Code")
.HasDatabaseName("ix_tenant_backend_roles_tenant_id_status_code");
b.ToTable("tenant_backend_roles", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendRoleMenu", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("MenuCode")
.IsRequired()
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("menu_code");
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id");
b.Property<Guid>("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.HasKey("Id")
.HasName("pk_tenant_backend_role_menus");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_tenant_backend_role_menus_tenant_id_id");
b.HasIndex("MenuCode")
.HasDatabaseName("ix_tenant_backend_role_menus_menu_code");
b.HasIndex("TenantId", "RoleId", "MenuCode")
.IsUnique()
.HasDatabaseName("ix_tenant_backend_role_menus_tenant_id_role_id_menu_code");
b.ToTable("tenant_backend_role_menus", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendRolePermission", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<string>("PermissionCode")
.IsRequired()
.HasMaxLength(160)
.HasColumnType("character varying(160)")
.HasColumnName("permission_code");
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id");
b.Property<Guid>("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.HasKey("Id")
.HasName("pk_tenant_backend_role_permissions");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_tenant_backend_role_permissions_tenant_id_id");
b.HasIndex("PermissionCode")
.HasDatabaseName("ix_tenant_backend_role_permissions_permission_code");
b.HasIndex("TenantId", "RoleId", "PermissionCode")
.IsUnique()
.HasDatabaseName("ix_tenant_backend_role_permissions_tenant_id_role_id_permissio~");
b.ToTable("tenant_backend_role_permissions", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendUserRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property<DateTimeOffset>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id");
b.Property<Guid>("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property<Guid>("UserId")
.HasColumnType("uuid")
.HasColumnName("user_id");
b.HasKey("Id")
.HasName("pk_tenant_backend_user_roles");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_tenant_backend_user_roles_tenant_id_id");
b.HasIndex("UserId")
.HasDatabaseName("ix_tenant_backend_user_roles_user_id");
b.HasIndex("TenantId", "RoleId")
.HasDatabaseName("ix_tenant_backend_user_roles_tenant_id_role_id");
b.HasIndex("TenantId", "UserId", "RoleId")
.IsUnique()
.HasDatabaseName("ix_tenant_backend_user_roles_tenant_id_user_id_role_id");
b.ToTable("tenant_backend_user_roles", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantContentNotification", b =>
{
b.Property<Guid>("Id")
@@ -15991,6 +16628,33 @@ namespace Tiku.Infrastructure.Persistence.Migrations
.HasConstraintName("fk_audit_logs_tenants_tenant_id");
});
modelBuilder.Entity("Tiku.Domain.Operations.BackendMenu", b =>
{
b.HasOne("Tiku.Domain.Operations.BackendPermission", null)
.WithMany()
.HasForeignKey("PermissionCode")
.HasPrincipalKey("Code")
.OnDelete(DeleteBehavior.SetNull)
.HasConstraintName("fk_backend_menus_backend_permissions_permission_code");
});
modelBuilder.Entity("Tiku.Domain.Operations.BackgroundJob", b =>
{
b.HasOne("Tiku.Domain.Tenancy.Tenant", null)
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_background_jobs_tenants_tenant_id");
b.HasOne("Tiku.Domain.Content.ContentAsset", null)
.WithMany()
.HasForeignKey("TenantId", "OutputAssetId")
.HasPrincipalKey("TenantId", "Id")
.OnDelete(DeleteBehavior.SetNull)
.HasConstraintName("fk_background_jobs_content_assets_tenant_id_output_asset_id");
});
modelBuilder.Entity("Tiku.Domain.Operations.Badge", b =>
{
b.HasOne("Tiku.Domain.Tenancy.Tenant", null)
@@ -16035,6 +16699,125 @@ namespace Tiku.Infrastructure.Persistence.Migrations
.HasConstraintName("fk_faqs_regions_tenant_id_region_id");
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendRoleMenu", b =>
{
b.HasOne("Tiku.Domain.Operations.BackendMenu", null)
.WithMany()
.HasForeignKey("MenuCode")
.HasPrincipalKey("Code")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("fk_platform_backend_role_menus_backend_menus_menu_code");
b.HasOne("Tiku.Domain.Operations.PlatformBackendRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_platform_backend_role_menus_platform_backend_roles_role_id");
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendRolePermission", b =>
{
b.HasOne("Tiku.Domain.Operations.BackendPermission", null)
.WithMany()
.HasForeignKey("PermissionCode")
.HasPrincipalKey("Code")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("fk_platform_backend_role_permissions_backend_permissions_permi~");
b.HasOne("Tiku.Domain.Operations.PlatformBackendRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_platform_backend_role_permissions_platform_backend_roles_ro~");
});
modelBuilder.Entity("Tiku.Domain.Operations.PlatformBackendUserRole", b =>
{
b.HasOne("Tiku.Domain.Operations.PlatformBackendRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_platform_backend_user_roles_platform_backend_roles_role_id");
b.HasOne("Tiku.Domain.Identity.User", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_platform_backend_user_roles_users_user_id");
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendRole", b =>
{
b.HasOne("Tiku.Domain.Tenancy.Tenant", null)
.WithMany()
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_tenant_backend_roles_tenants_tenant_id");
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendRoleMenu", b =>
{
b.HasOne("Tiku.Domain.Operations.BackendMenu", null)
.WithMany()
.HasForeignKey("MenuCode")
.HasPrincipalKey("Code")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("fk_tenant_backend_role_menus_backend_menus_menu_code");
b.HasOne("Tiku.Domain.Operations.TenantBackendRole", null)
.WithMany()
.HasForeignKey("TenantId", "RoleId")
.HasPrincipalKey("TenantId", "Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_tenant_backend_role_menus_tenant_backend_roles_tenant_id_ro~");
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendRolePermission", b =>
{
b.HasOne("Tiku.Domain.Operations.BackendPermission", null)
.WithMany()
.HasForeignKey("PermissionCode")
.HasPrincipalKey("Code")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("fk_tenant_backend_role_permissions_backend_permissions_permiss~");
b.HasOne("Tiku.Domain.Operations.TenantBackendRole", null)
.WithMany()
.HasForeignKey("TenantId", "RoleId")
.HasPrincipalKey("TenantId", "Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_tenant_backend_role_permissions_tenant_backend_roles_tenant~");
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantBackendUserRole", b =>
{
b.HasOne("Tiku.Domain.Identity.User", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_tenant_backend_user_roles_users_user_id");
b.HasOne("Tiku.Domain.Operations.TenantBackendRole", null)
.WithMany()
.HasForeignKey("TenantId", "RoleId")
.HasPrincipalKey("TenantId", "Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_tenant_backend_user_roles_tenant_backend_roles_tenant_id_ro~");
});
modelBuilder.Entity("Tiku.Domain.Operations.TenantContentNotification", b =>
{
b.HasOne("Tiku.Domain.Identity.User", null)