//
using System;
using System.Text.Json;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Tiku.Infrastructure.Persistence;
#nullable disable
namespace Tiku.Infrastructure.Persistence.Migrations
{
[DbContext(typeof(TikuDbContext))]
[Migration("20260725212832_AddAuthAndTenantOperationsPersistence")]
partial class AddAuthAndTenantOperationsPersistence
{
///
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "citext");
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "ltree");
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Tiku.Domain.Catalog.Category", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("CategoryType")
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("category_type");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("IsActive")
.HasColumnType("boolean")
.HasColumnName("is_active");
b.Property("LegacyId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_id");
b.Property("Name")
.IsRequired()
.HasMaxLength(300)
.HasColumnType("character varying(300)")
.HasColumnName("name");
b.Property("NodeId")
.HasColumnType("uuid")
.HasColumnName("node_id");
b.Property("SortOrder")
.HasColumnType("integer")
.HasColumnName("sort_order");
b.Property("SubjectId")
.HasColumnType("uuid")
.HasColumnName("subject_id");
b.Property("SvipQuestionLimit")
.HasColumnType("integer")
.HasColumnName("svip_question_limit");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_categories");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_categories_tenant_id_id");
b.HasIndex("TenantId", "LegacyId")
.IsUnique()
.HasDatabaseName("ix_categories_tenant_id_legacy_id");
b.HasIndex("TenantId", "NodeId")
.HasDatabaseName("ix_categories_tenant_id_node_id");
b.HasIndex("TenantId", "SubjectId")
.HasDatabaseName("ix_categories_tenant_id_subject_id");
b.ToTable("categories", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Catalog.Major", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("Description")
.HasColumnType("text")
.HasColumnName("description");
b.Property("IsActive")
.HasColumnType("boolean")
.HasColumnName("is_active");
b.Property("LegacyId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_id");
b.Property("Name")
.IsRequired()
.HasMaxLength(300)
.HasColumnType("character varying(300)")
.HasColumnName("name");
b.Property("RegionId")
.HasColumnType("uuid")
.HasColumnName("region_id");
b.Property("SchoolId")
.HasColumnType("uuid")
.HasColumnName("school_id");
b.Property("SortOrder")
.HasColumnType("integer")
.HasColumnName("sort_order");
b.Property("StudyTips")
.HasColumnType("text")
.HasColumnName("study_tips");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_majors");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_majors_tenant_id_id");
b.HasIndex("TenantId", "LegacyId")
.IsUnique()
.HasDatabaseName("ix_majors_tenant_id_legacy_id");
b.HasIndex("TenantId", "RegionId")
.HasDatabaseName("ix_majors_tenant_id_region_id");
b.HasIndex("TenantId", "SchoolId")
.HasDatabaseName("ix_majors_tenant_id_school_id");
b.ToTable("majors", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Catalog.ModuleNode", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("IsActive")
.HasColumnType("boolean")
.HasColumnName("is_active");
b.Property("LegacyId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_id");
b.Property("LegacyModuleId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_module_id");
b.Property("LegacyParentId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_parent_id");
b.Property("Metadata")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("metadata")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("ModuleId")
.HasColumnType("uuid")
.HasColumnName("module_id");
b.Property("Name")
.IsRequired()
.HasMaxLength(300)
.HasColumnType("character varying(300)")
.HasColumnName("name");
b.Property("ParentId")
.HasColumnType("uuid")
.HasColumnName("parent_id");
b.Property("Path")
.HasMaxLength(1000)
.HasColumnType("character varying(1000)")
.HasColumnName("path");
b.Property("RegionId")
.HasColumnType("uuid")
.HasColumnName("region_id");
b.Property("SortOrder")
.HasColumnType("integer")
.HasColumnName("sort_order");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("Type")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("type");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_module_nodes");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_module_nodes_tenant_id_id");
b.HasIndex("TenantId", "LegacyId")
.IsUnique()
.HasDatabaseName("ix_module_nodes_tenant_id_legacy_id");
b.HasIndex("TenantId", "ModuleId")
.HasDatabaseName("ix_module_nodes_tenant_id_module_id");
b.HasIndex("TenantId", "ParentId")
.HasDatabaseName("ix_module_nodes_tenant_id_parent_id");
b.HasIndex("TenantId", "RegionId")
.HasDatabaseName("ix_module_nodes_tenant_id_region_id");
b.ToTable("module_nodes", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Catalog.Region", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("Code")
.HasMaxLength(50)
.HasColumnType("character varying(50)")
.HasColumnName("code");
b.Property("Config")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("config")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("FullName")
.HasMaxLength(300)
.HasColumnType("character varying(300)")
.HasColumnName("full_name");
b.Property("Icon")
.HasMaxLength(2048)
.HasColumnType("character varying(2048)")
.HasColumnName("icon");
b.Property("IsActive")
.HasColumnType("boolean")
.HasColumnName("is_active");
b.Property("IsHot")
.HasColumnType("boolean")
.HasColumnName("is_hot");
b.Property("LegacyId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_id");
b.Property("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("name");
b.Property("Pinyin")
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("pinyin");
b.Property("ShortName")
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("short_name");
b.Property("SortOrder")
.HasColumnType("integer")
.HasColumnName("sort_order");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_regions");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_regions_tenant_id_id");
b.HasIndex("TenantId", "LegacyId")
.IsUnique()
.HasDatabaseName("ix_regions_tenant_id_legacy_id");
b.ToTable("regions", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Catalog.RegionModule", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("Color")
.HasMaxLength(50)
.HasColumnType("character varying(50)")
.HasColumnName("color");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("Description")
.HasColumnType("text")
.HasColumnName("description");
b.Property("Icon")
.HasMaxLength(2048)
.HasColumnType("character varying(2048)")
.HasColumnName("icon");
b.Property("IsActive")
.HasColumnType("boolean")
.HasColumnName("is_active");
b.Property("IsPrimarySchoolModule")
.HasColumnType("boolean")
.HasColumnName("is_primary_school_module");
b.Property("LegacyId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_id");
b.Property("Name")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("name");
b.Property("RegionId")
.HasColumnType("uuid")
.HasColumnName("region_id");
b.Property("Route")
.HasMaxLength(500)
.HasColumnType("character varying(500)")
.HasColumnName("route");
b.Property("SortOrder")
.HasColumnType("integer")
.HasColumnName("sort_order");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("TextColor")
.HasMaxLength(50)
.HasColumnType("character varying(50)")
.HasColumnName("text_color");
b.Property("Type")
.HasMaxLength(50)
.HasColumnType("character varying(50)")
.HasColumnName("type");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_region_modules");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_region_modules_tenant_id_id");
b.HasIndex("TenantId", "LegacyId")
.IsUnique()
.HasDatabaseName("ix_region_modules_tenant_id_legacy_id");
b.HasIndex("TenantId", "RegionId")
.HasDatabaseName("ix_region_modules_tenant_id_region_id");
b.ToTable("region_modules", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Catalog.School", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("LegacyId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_id");
b.Property("Metadata")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("metadata")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("ModuleId")
.HasColumnType("uuid")
.HasColumnName("module_id");
b.Property("Name")
.IsRequired()
.HasMaxLength(300)
.HasColumnType("character varying(300)")
.HasColumnName("name");
b.Property("ProfessionalExamDate")
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("professional_exam_date");
b.Property("RegionId")
.HasColumnType("uuid")
.HasColumnName("region_id");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_schools");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_schools_tenant_id_id");
b.HasIndex("TenantId", "LegacyId")
.IsUnique()
.HasDatabaseName("ix_schools_tenant_id_legacy_id");
b.HasIndex("TenantId", "ModuleId")
.HasDatabaseName("ix_schools_tenant_id_module_id");
b.HasIndex("TenantId", "RegionId")
.HasDatabaseName("ix_schools_tenant_id_region_id");
b.ToTable("schools", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Catalog.Subject", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("Description")
.HasColumnType("text")
.HasColumnName("description");
b.Property("Icon")
.HasMaxLength(2048)
.HasColumnType("character varying(2048)")
.HasColumnName("icon");
b.Property("IsActive")
.HasColumnType("boolean")
.HasColumnName("is_active");
b.Property("LegacyId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_id");
b.Property("MajorId")
.HasColumnType("uuid")
.HasColumnName("major_id");
b.Property("MajorLegacyIds")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("major_legacy_ids")
.HasDefaultValueSql("'[]'::jsonb");
b.Property("ModuleId")
.HasColumnType("uuid")
.HasColumnName("module_id");
b.Property("Name")
.IsRequired()
.HasMaxLength(300)
.HasColumnType("character varying(300)")
.HasColumnName("name");
b.Property("NodeId")
.HasColumnType("uuid")
.HasColumnName("node_id");
b.Property("RegionId")
.HasColumnType("uuid")
.HasColumnName("region_id");
b.Property("SchoolId")
.HasColumnType("uuid")
.HasColumnName("school_id");
b.Property("SortOrder")
.HasColumnType("integer")
.HasColumnName("sort_order");
b.Property("Stats")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("stats")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("Type")
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("type");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_subjects");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_subjects_tenant_id_id");
b.HasIndex("TenantId", "LegacyId")
.IsUnique()
.HasDatabaseName("ix_subjects_tenant_id_legacy_id");
b.HasIndex("TenantId", "MajorId")
.HasDatabaseName("ix_subjects_tenant_id_major_id");
b.HasIndex("TenantId", "ModuleId")
.HasDatabaseName("ix_subjects_tenant_id_module_id");
b.HasIndex("TenantId", "NodeId")
.HasDatabaseName("ix_subjects_tenant_id_node_id");
b.HasIndex("TenantId", "RegionId")
.HasDatabaseName("ix_subjects_tenant_id_region_id");
b.HasIndex("TenantId", "SchoolId")
.HasDatabaseName("ix_subjects_tenant_id_school_id");
b.ToTable("subjects", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Content.AppAsset", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("AssetKey")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("asset_key");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("Description")
.HasMaxLength(1000)
.HasColumnType("character varying(1000)")
.HasColumnName("description");
b.Property("FileName")
.HasMaxLength(500)
.HasColumnType("character varying(500)")
.HasColumnName("file_name");
b.Property("LegacyId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_id");
b.Property("Metadata")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("metadata")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_app_assets");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_app_assets_tenant_id_id");
b.HasIndex("TenantId", "AssetKey")
.IsUnique()
.HasDatabaseName("ix_app_assets_tenant_id_asset_key");
b.HasIndex("TenantId", "LegacyId")
.IsUnique()
.HasDatabaseName("ix_app_assets_tenant_id_legacy_id");
b.ToTable("app_assets", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Content.ContentAsset", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("AccessRules")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("access_rules")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("AssetKey")
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("asset_key");
b.Property("AssetType")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("asset_type");
b.Property("Bucket")
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("bucket");
b.Property("Category")
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("category");
b.Property("CategoryId")
.HasColumnType("uuid")
.HasColumnName("category_id");
b.Property("CdnUrl")
.HasMaxLength(2048)
.HasColumnType("character varying(2048)")
.HasColumnName("cdn_url");
b.Property("ChecksumSha256")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("checksum_sha256");
b.Property("ContentNodeId")
.HasColumnType("uuid")
.HasColumnName("content_node_id");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("CreatedBy")
.HasColumnType("uuid")
.HasColumnName("created_by");
b.Property("Description")
.HasColumnType("text")
.HasColumnName("description");
b.Property("DownloadCount")
.HasColumnType("integer")
.HasColumnName("download_count");
b.Property("FileName")
.HasMaxLength(500)
.HasColumnType("character varying(500)")
.HasColumnName("file_name");
b.Property("FileSizeBytes")
.HasColumnType("bigint")
.HasColumnName("file_size_bytes");
b.Property("IsPublic")
.HasColumnType("boolean")
.HasColumnName("is_public");
b.Property("LegacyId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_id");
b.Property("Metadata")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("metadata")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("MimeType")
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("mime_type");
b.Property("ObjectKey")
.HasMaxLength(1000)
.HasColumnType("character varying(1000)")
.HasColumnName("object_key");
b.Property("PreviewObjectKey")
.HasMaxLength(1000)
.HasColumnType("character varying(1000)")
.HasColumnName("preview_object_key");
b.Property("PreviewStatus")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("preview_status");
b.Property("PreviewUrl")
.HasMaxLength(2048)
.HasColumnType("character varying(2048)")
.HasColumnName("preview_url");
b.Property("RegionId")
.HasColumnType("uuid")
.HasColumnName("region_id");
b.Property("SecurityFlags")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("security_flags")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("SortOrder")
.HasColumnType("integer")
.HasColumnName("sort_order");
b.Property("Source")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)")
.HasColumnName("source");
b.Property("Status")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("status");
b.Property("StorageProvider")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("storage_provider");
b.Property("SubjectId")
.HasColumnType("uuid")
.HasColumnName("subject_id");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("Title")
.HasMaxLength(300)
.HasColumnType("character varying(300)")
.HasColumnName("title");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.Property("UpdatedBy")
.HasColumnType("uuid")
.HasColumnName("updated_by");
b.Property("UploadStatus")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("upload_status");
b.Property("VerificationDetails")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("verification_details")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("VerifiedAt")
.HasColumnType("timestamp with time zone")
.HasColumnName("verified_at");
b.Property("VerifiedBy")
.HasColumnType("uuid")
.HasColumnName("verified_by");
b.Property("VerifiedChecksumSha256")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("verified_checksum_sha256");
b.Property("VerifiedSizeBytes")
.HasColumnType("bigint")
.HasColumnName("verified_size_bytes");
b.Property("Visibility")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("visibility");
b.HasKey("Id")
.HasName("pk_content_assets");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_content_assets_tenant_id_id");
b.HasIndex("CreatedBy")
.HasDatabaseName("ix_content_assets_created_by");
b.HasIndex("UpdatedBy")
.HasDatabaseName("ix_content_assets_updated_by");
b.HasIndex("VerifiedBy")
.HasDatabaseName("ix_content_assets_verified_by");
b.HasIndex("TenantId", "CategoryId")
.HasDatabaseName("ix_content_assets_tenant_id_category_id");
b.HasIndex("TenantId", "ChecksumSha256")
.HasDatabaseName("ix_content_assets_tenant_id_checksum_sha256")
.HasFilter("checksum_sha256 is not null");
b.HasIndex("TenantId", "ContentNodeId")
.HasDatabaseName("ix_content_assets_tenant_id_content_node_id");
b.HasIndex("TenantId", "LegacyId")
.IsUnique()
.HasDatabaseName("ix_content_assets_tenant_id_legacy_id");
b.HasIndex("TenantId", "PreviewStatus")
.HasDatabaseName("ix_content_assets_tenant_id_preview_status")
.HasFilter("preview_status <> 'none'");
b.HasIndex("TenantId", "RegionId")
.HasDatabaseName("ix_content_assets_tenant_id_region_id");
b.HasIndex("TenantId", "SubjectId")
.HasDatabaseName("ix_content_assets_tenant_id_subject_id");
b.HasIndex("TenantId", "StorageProvider", "Bucket", "ObjectKey")
.HasDatabaseName("ix_content_assets_tenant_id_storage_provider_bucket_object_key");
b.HasIndex("TenantId", "UploadStatus", "Status", "UpdatedAt")
.HasDatabaseName("ix_content_assets_tenant_id_upload_status_status_updated_at");
b.HasIndex("TenantId", "Status", "Visibility", "AssetType", "RegionId", "SubjectId", "CategoryId", "SortOrder")
.HasDatabaseName("ix_content_assets_tenant_id_status_visibility_asset_type_regio~");
b.ToTable("content_assets", null, t =>
{
t.HasCheckConstraint("ck_content_assets_download_count", "download_count >= 0");
t.HasCheckConstraint("ck_content_assets_file_size", "file_size_bytes is null or file_size_bytes >= 0");
t.HasCheckConstraint("ck_content_assets_verified_checksum", "verified_checksum_sha256 is null or verified_checksum_sha256 ~ '^[a-f0-9]{64}$'");
t.HasCheckConstraint("ck_content_assets_verified_size", "verified_size_bytes is null or verified_size_bytes >= 0");
});
});
modelBuilder.Entity("Tiku.Domain.Content.ContentEntry", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("AccessRules")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("access_rules")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("CreatedBy")
.HasColumnType("uuid")
.HasColumnName("created_by");
b.Property("Description")
.HasMaxLength(2000)
.HasColumnType("character varying(2000)")
.HasColumnName("description");
b.Property("EntryKey")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("entry_key");
b.Property("EntryType")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("entry_type");
b.Property("Icon")
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("icon");
b.Property("IsActive")
.HasColumnType("boolean")
.HasColumnName("is_active");
b.Property("LayoutConfig")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("layout_config")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("LegacyId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_id");
b.Property("Name")
.IsRequired()
.HasMaxLength(300)
.HasColumnType("character varying(300)")
.HasColumnName("name");
b.Property("RegionId")
.HasColumnType("uuid")
.HasColumnName("region_id");
b.Property("Route")
.HasMaxLength(500)
.HasColumnType("character varying(500)")
.HasColumnName("route");
b.Property("SortOrder")
.HasColumnType("integer")
.HasColumnName("sort_order");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.Property("UpdatedBy")
.HasColumnType("uuid")
.HasColumnName("updated_by");
b.Property("Visibility")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("visibility");
b.HasKey("Id")
.HasName("pk_content_entries");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_content_entries_tenant_id_id");
b.HasIndex("CreatedBy")
.HasDatabaseName("ix_content_entries_created_by");
b.HasIndex("UpdatedBy")
.HasDatabaseName("ix_content_entries_updated_by");
b.HasIndex("TenantId", "EntryKey")
.IsUnique()
.HasDatabaseName("ix_content_entries_tenant_id_entry_key");
b.HasIndex("TenantId", "LegacyId")
.IsUnique()
.HasDatabaseName("ix_content_entries_tenant_id_legacy_id");
b.HasIndex("TenantId", "RegionId", "EntryType", "IsActive", "SortOrder")
.HasDatabaseName("ix_content_entries_tenant_id_region_id_entry_type_is_active_so~");
b.ToTable("content_entries", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Content.ContentImportIssue", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("Code")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("code");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("Details")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("details")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("FieldPath")
.HasMaxLength(500)
.HasColumnType("character varying(500)")
.HasColumnName("field_path");
b.Property("ItemId")
.HasColumnType("uuid")
.HasColumnName("item_id");
b.Property("JobId")
.HasColumnType("uuid")
.HasColumnName("job_id");
b.Property("Message")
.IsRequired()
.HasMaxLength(2000)
.HasColumnType("character varying(2000)")
.HasColumnName("message");
b.Property("RowNo")
.HasColumnType("integer")
.HasColumnName("row_no");
b.Property("Severity")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("severity");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_content_import_issues");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_content_import_issues_tenant_id_id");
b.HasIndex("TenantId", "ItemId")
.HasDatabaseName("ix_content_import_issues_tenant_id_item_id");
b.HasIndex("TenantId", "JobId", "Severity", "RowNo")
.HasDatabaseName("ix_content_import_issues_tenant_id_job_id_severity_row_no");
b.ToTable("content_import_issues", (string)null);
});
modelBuilder.Entity("Tiku.Domain.Content.ContentImportItem", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("ContentHash")
.HasMaxLength(128)
.HasColumnType("character varying(128)")
.HasColumnName("content_hash");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("ExternalId")
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("external_id");
b.Property("IssuesCount")
.HasColumnType("integer")
.HasColumnName("issues_count");
b.Property("JobId")
.HasColumnType("uuid")
.HasColumnName("job_id");
b.Property("NormalizedPayload")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("normalized_payload")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("RowNo")
.HasColumnType("integer")
.HasColumnName("row_no");
b.Property("SourcePayload")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("source_payload")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("Status")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("status");
b.Property("TargetId")
.HasColumnType("uuid")
.HasColumnName("target_id");
b.Property("TargetType")
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("target_type");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.HasKey("Id")
.HasName("pk_content_import_items");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_content_import_items_tenant_id_id");
b.HasIndex("JobId", "RowNo")
.IsUnique()
.HasDatabaseName("ix_content_import_items_job_id_row_no");
b.HasIndex("TenantId", "JobId", "Status", "RowNo")
.HasDatabaseName("ix_content_import_items_tenant_id_job_id_status_row_no");
b.ToTable("content_import_items", null, t =>
{
t.HasCheckConstraint("ck_content_import_items_issues_count", "issues_count >= 0");
t.HasCheckConstraint("ck_content_import_items_row_no", "row_no >= 0");
});
});
modelBuilder.Entity("Tiku.Domain.Content.ContentImportJob", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("CreatedBy")
.HasColumnType("uuid")
.HasColumnName("created_by");
b.Property("DryRun")
.HasColumnType("boolean")
.HasColumnName("dry_run");
b.Property("ErrorCount")
.HasColumnType("integer")
.HasColumnName("error_count");
b.Property("ErrorMessage")
.HasColumnType("text")
.HasColumnName("error_message");
b.Property("FinishedAt")
.HasColumnType("timestamp with time zone")
.HasColumnName("finished_at");
b.Property("ImportType")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("import_type");
b.Property("InsertedCount")
.HasColumnType("integer")
.HasColumnName("inserted_count");
b.Property("NormalizedPayload")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("normalized_payload")
.HasDefaultValueSql("'[]'::jsonb");
b.Property("RawPayload")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("raw_payload")
.HasDefaultValueSql("'[]'::jsonb");
b.Property("SkippedCount")
.HasColumnType("integer")
.HasColumnName("skipped_count");
b.Property("SourceFormat")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("source_format");
b.Property("SourceHash")
.HasMaxLength(128)
.HasColumnType("character varying(128)")
.HasColumnName("source_hash");
b.Property("SourceName")
.HasMaxLength(500)
.HasColumnType("character varying(500)")
.HasColumnName("source_name");
b.Property("StartedAt")
.HasColumnType("timestamp with time zone")
.HasColumnName("started_at");
b.Property("Status")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("status");
b.Property("Summary")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("summary")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("TargetCategoryId")
.HasColumnType("uuid")
.HasColumnName("target_category_id");
b.Property("TargetContentNodeId")
.HasColumnType("uuid")
.HasColumnName("target_content_node_id");
b.Property("TargetQuestionBankId")
.HasColumnType("uuid")
.HasColumnName("target_question_bank_id");
b.Property("TargetRegionId")
.HasColumnType("uuid")
.HasColumnName("target_region_id");
b.Property("TargetSubjectId")
.HasColumnType("uuid")
.HasColumnName("target_subject_id");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("TotalCount")
.HasColumnType("integer")
.HasColumnName("total_count");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.Property("UpdatedCount")
.HasColumnType("integer")
.HasColumnName("updated_count");
b.Property("ValidCount")
.HasColumnType("integer")
.HasColumnName("valid_count");
b.Property("WarningCount")
.HasColumnType("integer")
.HasColumnName("warning_count");
b.HasKey("Id")
.HasName("pk_content_import_jobs");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_content_import_jobs_tenant_id_id");
b.HasIndex("CreatedBy")
.HasDatabaseName("ix_content_import_jobs_created_by");
b.HasIndex("TenantId", "TargetCategoryId")
.HasDatabaseName("ix_content_import_jobs_tenant_id_target_category_id");
b.HasIndex("TenantId", "TargetContentNodeId")
.HasDatabaseName("ix_content_import_jobs_tenant_id_target_content_node_id");
b.HasIndex("TenantId", "TargetQuestionBankId")
.HasDatabaseName("ix_content_import_jobs_tenant_id_target_question_bank_id");
b.HasIndex("TenantId", "TargetRegionId")
.HasDatabaseName("ix_content_import_jobs_tenant_id_target_region_id");
b.HasIndex("TenantId", "TargetSubjectId")
.HasDatabaseName("ix_content_import_jobs_tenant_id_target_subject_id");
b.HasIndex("TenantId", "ImportType", "Status", "CreatedAt")
.HasDatabaseName("ix_content_import_jobs_tenant_id_import_type_status_created_at");
b.ToTable("content_import_jobs", null, t =>
{
t.HasCheckConstraint("ck_content_import_jobs_counts", "total_count >= 0 and valid_count >= 0 and error_count >= 0 and warning_count >= 0 and inserted_count >= 0 and updated_count >= 0 and skipped_count >= 0");
});
});
modelBuilder.Entity("Tiku.Domain.Content.ContentNode", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("AccessRules")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("access_rules")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("CreatedBy")
.HasColumnType("uuid")
.HasColumnName("created_by");
b.Property("Depth")
.HasColumnType("integer")
.HasColumnName("depth");
b.Property("EntryId")
.HasColumnType("uuid")
.HasColumnName("entry_id");
b.Property("IsActive")
.HasColumnType("boolean")
.HasColumnName("is_active");
b.Property("IsLeaf")
.HasColumnType("boolean")
.HasColumnName("is_leaf");
b.Property("IsSelectable")
.HasColumnType("boolean")
.HasColumnName("is_selectable");
b.Property("LegacyId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_id");
b.Property("MarkerConfig")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("marker_config")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("MarkerType")
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("marker_type");
b.Property("Metadata")
.ValueGeneratedOnAdd()
.HasColumnType("jsonb")
.HasColumnName("metadata")
.HasDefaultValueSql("'{}'::jsonb");
b.Property("Name")
.IsRequired()
.HasMaxLength(300)
.HasColumnType("character varying(300)")
.HasColumnName("name");
b.Property("NodeKey")
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("node_key");
b.Property("NodeType")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("node_type");
b.Property("ParentId")
.HasColumnType("uuid")
.HasColumnName("parent_id");
b.Property("Path")
.HasColumnType("ltree")
.HasColumnName("path");
b.Property("RegionId")
.HasColumnType("uuid")
.HasColumnName("region_id");
b.Property("SortOrder")
.HasColumnType("integer")
.HasColumnName("sort_order");
b.Property("TenantId")
.HasColumnType("uuid")
.HasColumnName("tenant_id");
b.Property("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at")
.HasDefaultValueSql("now()");
b.Property("UpdatedBy")
.HasColumnType("uuid")
.HasColumnName("updated_by");
b.HasKey("Id")
.HasName("pk_content_nodes");
b.HasAlternateKey("TenantId", "Id")
.HasName("ak_content_nodes_tenant_id_id");
b.HasIndex("CreatedBy")
.HasDatabaseName("ix_content_nodes_created_by");
b.HasIndex("Path")
.HasDatabaseName("ix_content_nodes_path");
NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("Path"), "gist");
b.HasIndex("UpdatedBy")
.HasDatabaseName("ix_content_nodes_updated_by");
b.HasIndex("TenantId", "LegacyId")
.IsUnique()
.HasDatabaseName("ix_content_nodes_tenant_id_legacy_id");
b.HasIndex("TenantId", "MarkerType")
.HasDatabaseName("ix_content_nodes_tenant_id_marker_type")
.HasFilter("marker_type is not null");
b.HasIndex("TenantId", "ParentId")
.HasDatabaseName("ix_content_nodes_tenant_id_parent_id");
b.HasIndex("TenantId", "RegionId")
.HasDatabaseName("ix_content_nodes_tenant_id_region_id");
b.HasIndex("TenantId", "EntryId", "NodeKey")
.IsUnique()
.HasDatabaseName("ix_content_nodes_tenant_id_entry_id_node_key");
b.HasIndex("TenantId", "EntryId", "ParentId", "SortOrder")
.HasDatabaseName("ix_content_nodes_tenant_id_entry_id_parent_id_sort_order");
b.ToTable("content_nodes", null, t =>
{
t.HasCheckConstraint("ck_content_nodes_depth", "depth >= 0");
});
});
modelBuilder.Entity("Tiku.Domain.Content.HandbookChapter", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasColumnName("id")
.HasDefaultValueSql("gen_random_uuid()");
b.Property("ContentNodeId")
.HasColumnType("uuid")
.HasColumnName("content_node_id");
b.Property("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at")
.HasDefaultValueSql("now()");
b.Property("Description")
.HasColumnType("text")
.HasColumnName("description");
b.Property("EntryId")
.HasColumnType("uuid")
.HasColumnName("entry_id");
b.Property("IsActive")
.HasColumnType("boolean")
.HasColumnName("is_active");
b.Property("LegacyId")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("legacy_id");
b.Property