diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725205004_InitialCore.Designer.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725205004_InitialCore.Designer.cs deleted file mode 100644 index 3083ab8..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725205004_InitialCore.Designer.cs +++ /dev/null @@ -1,2176 +0,0 @@ -// -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("20260725205004_InitialCore")] - partial class InitialCore - { - /// - 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.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.Identity.StudentProfile", 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("LastCheckInDate") - .HasColumnType("date") - .HasColumnName("last_check_in_date"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("MasteredWordsCount") - .HasColumnType("integer") - .HasColumnName("mastered_words_count"); - - b.Property("ModuleSelections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_selections") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Progress") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("progress") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionsAnsweredToday") - .HasColumnType("integer") - .HasColumnName("questions_answered_today"); - - b.Property("RecentActivities") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("recent_activities") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SelectedMajorId") - .HasColumnType("uuid") - .HasColumnName("selected_major_id"); - - b.Property("SelectedSchoolId") - .HasColumnType("uuid") - .HasColumnName("selected_school_id"); - - b.Property("Stats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("stats") - .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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_student_profiles"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_student_profiles_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_student_profiles_user_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_student_profiles_tenant_id_region_id"); - - b.HasIndex("TenantId", "SelectedMajorId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_major_id"); - - b.HasIndex("TenantId", "SelectedSchoolId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_school_id"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_student_profiles_tenant_id_user_id"); - - b.ToTable("student_profiles", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AvatarUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("avatar_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("LastSeenAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_seen_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPasswordHash") - .HasMaxLength(512) - .HasColumnType("character varying(512)") - .HasColumnName("legacy_password_hash"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PasswordMigrationRequired") - .HasColumnType("boolean") - .HasColumnName("password_migration_required"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("PrimaryRole") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("primary_role"); - - b.Property("RawProfile") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_profile") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Score") - .HasColumnType("integer") - .HasColumnName("score"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Username") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("username"); - - b.HasKey("Id") - .HasName("pk_users"); - - b.HasIndex("Email") - .IsUnique() - .HasDatabaseName("ix_users_email"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_users_legacy_id"); - - b.HasIndex("Phone") - .IsUnique() - .HasDatabaseName("ix_users_phone"); - - b.HasIndex("Username") - .IsUnique() - .HasDatabaseName("ix_users_username"); - - b.ToTable("users", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", 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("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("OpenId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("open_id"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderSubject") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("provider_subject"); - - b.Property("SecretPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("secret_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UnionId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("union_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_identities"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_identities_user_id"); - - b.HasIndex("Provider", "ProviderSubject") - .IsUnique() - .HasDatabaseName("ix_user_identities_provider_provider_subject"); - - b.ToTable("user_identities", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("AnsweredAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("answered_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IsCorrect") - .HasColumnType("boolean") - .HasColumnName("is_correct"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("QuestionVersionId") - .HasColumnType("uuid") - .HasColumnName("question_version_id"); - - b.Property("SelectedOptions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("selected_options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_answer_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_answer_records_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_answer_records_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_answer_records_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id"); - - b.HasIndex("TenantId", "QuestionId", "QuestionVersionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id_question_version_id"); - - b.HasIndex("TenantId", "UserId", "PracticeSessionId") - .HasDatabaseName("ix_answer_records_tenant_id_user_id_practice_session_id"); - - b.ToTable("answer_records", null, t => - { - t.HasCheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_favorite_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_favorite_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_favorite_questions_tenant_id_question_id"); - - b.ToTable("favorite_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("FinishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("finished_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("StartedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at") - .HasDefaultValueSql("now()"); - - b.Property("TargetId") - .HasColumnType("uuid") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_sessions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "UserId", "Id") - .HasName("ak_practice_sessions_tenant_id_user_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_sessions_user_id"); - - b.HasIndex("TenantId", "UserId", "StartedAt") - .HasDatabaseName("ix_practice_sessions_tenant_id_user_id_started_at"); - - b.ToTable("practice_sessions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", 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("LastAccessAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_access_at"); - - b.Property("LastPracticeAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_practice_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("practice_type"); - - b.Property("Progress") - .HasColumnType("integer") - .HasColumnName("progress"); - - b.Property("TargetLegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("target_legacy_id"); - - b.Property("TargetName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("target_name"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_recent_practices"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_recent_practices_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_recent_practices_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_recent_practices_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "LastAccessAt") - .HasDatabaseName("ix_recent_practices_tenant_id_user_id_last_access_at"); - - b.ToTable("recent_practices", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("LastWrongAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("last_wrong_at") - .HasDefaultValueSql("now()"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("WrongCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(1) - .HasColumnName("wrong_count"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_wrong_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_wrong_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_wrong_questions_tenant_id_question_id"); - - b.ToTable("wrong_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CurrentVersionId") - .HasColumnType("uuid") - .HasColumnName("current_version_id"); - - b.Property("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("HasVideoExplanation") - .HasColumnType("boolean") - .HasColumnName("has_video_explanation"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyNodeId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_node_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("MediaUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("media_url"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Type") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("type"); - - b.Property("TypeLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("type_label"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_questions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_questions_tenant_id_id"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_questions_tenant_id_category_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_questions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "NodeId") - .HasDatabaseName("ix_questions_tenant_id_node_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_questions_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_questions_tenant_id_subject_id"); - - b.HasIndex("TenantId", "Id", "CurrentVersionId") - .HasDatabaseName("ix_questions_tenant_id_id_current_version_id"); - - b.ToTable("questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SourceScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_scope"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_banks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_banks_tenant_id_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_banks_tenant_id_region_id"); - - b.ToTable("question_banks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("CodeLang") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("code_lang"); - - b.Property("CodeTemplate") - .HasColumnType("text") - .HasColumnName("code_template"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CorrectOptionIndex") - .HasColumnType("integer") - .HasColumnName("correct_option_index"); - - b.Property("CorrectOptionIndices") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("correct_option_indices") - .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("Explanation") - .HasColumnType("text") - .HasColumnName("explanation"); - - b.Property("Options") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubQuestions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sub_questions") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("VersionNo") - .HasColumnType("integer") - .HasColumnName("version_no"); - - b.HasKey("Id") - .HasName("pk_question_versions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_versions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "QuestionId", "Id") - .HasName("ak_question_versions_tenant_id_question_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_versions_created_by"); - - b.HasIndex("QuestionId", "VersionNo") - .IsUnique() - .HasDatabaseName("ix_question_versions_question_id_version_no"); - - b.ToTable("question_versions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BillingStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("billing_status"); - - 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("LegalName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("legal_name"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OwnerUserId") - .HasColumnType("uuid") - .HasColumnName("owner_user_id"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("slug"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenants"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenants_legacy_id"); - - b.HasIndex("OwnerUserId") - .HasDatabaseName("ix_tenants_owner_user_id"); - - b.HasIndex("Slug") - .IsUnique() - .HasDatabaseName("ix_tenants_slug"); - - b.ToTable("tenants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", 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("LegacyRole") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("legacy_role"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Role") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("role"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_memberships"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_memberships_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_memberships_user_id"); - - b.HasIndex("TenantId", "UserId", "Role") - .IsUnique() - .HasDatabaseName("ix_tenant_memberships_tenant_id_user_id_role"); - - b.ToTable("tenant_memberships", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Category", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_categories_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Major", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_majors_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.ModuleNode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_module_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_module_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Region", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_regions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.RegionModule", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_region_modules_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_region_modules_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.School", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_schools_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Subject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedMajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_majors_tenant_id_selected_major_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedSchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_schools_tenant_id_selected_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_identities_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId", "QuestionVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_question_versions_tenant_id_question_id_ques~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "UserId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "UserId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_practice_sessions_tenant_id_user_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_recent_practices_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_recent_practices_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_banks_tenant_id_question_bank_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_subjects_tenant_id_subject_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "Id", "CurrentVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_versions_tenant_id_id_current_version_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_banks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_banks_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_versions_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_versions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("OwnerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenants_users_owner_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_users_user_id"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725205004_InitialCore.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725205004_InitialCore.cs deleted file mode 100644 index 8e02f8f..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725205004_InitialCore.cs +++ /dev/null @@ -1,1229 +0,0 @@ -using System; -using System.Text.Json; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Tiku.Infrastructure.Persistence.Migrations -{ - /// - public partial class InitialCore : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterDatabase() - .Annotation("Npgsql:PostgresExtension:citext", ",,"); - - migrationBuilder.CreateTable( - name: "users", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - username = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - email = table.Column(type: "citext", maxLength: 320, nullable: true), - phone = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - avatar_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - primary_role = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - score = table.Column(type: "integer", nullable: false), - last_seen_at = table.Column(type: "timestamp with time zone", nullable: true), - legacy_password_hash = table.Column(type: "character varying(512)", maxLength: 512, nullable: true), - password_migration_required = table.Column(type: "boolean", nullable: false), - raw_profile = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_users", x => x.id); - }); - - migrationBuilder.CreateTable( - name: "tenants", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - slug = table.Column(type: "citext", maxLength: 100, nullable: false), - name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - legal_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - billing_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - owner_user_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenants", x => x.id); - table.ForeignKey( - name: "fk_tenants_users_owner_user_id", - column: x => x.owner_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "user_identities", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: false), - provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - provider_subject = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), - union_id = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), - open_id = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), - phone = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - email = table.Column(type: "citext", maxLength: 320, nullable: true), - secret_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_user_identities", x => x.id); - table.ForeignKey( - name: "fk_user_identities_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "practice_sessions", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: false), - mode = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - target_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - target_id = table.Column(type: "uuid", nullable: true), - started_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - finished_at = table.Column(type: "timestamp with time zone", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("pk_practice_sessions", x => x.id); - table.UniqueConstraint("ak_practice_sessions_tenant_id_id", x => new { x.tenant_id, x.id }); - table.UniqueConstraint("ak_practice_sessions_tenant_id_user_id_id", x => new { x.tenant_id, x.user_id, x.id }); - table.ForeignKey( - name: "fk_practice_sessions_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_practice_sessions_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "recent_practices", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - practice_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - target_legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - target_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - progress = table.Column(type: "integer", nullable: false), - color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - last_access_at = table.Column(type: "timestamp with time zone", nullable: true), - last_practice_at = table.Column(type: "timestamp with time zone", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_recent_practices", x => x.id); - table.UniqueConstraint("ak_recent_practices_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_recent_practices_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_recent_practices_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "regions", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - code = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - short_name = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - full_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - icon = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - pinyin = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), - sort_order = table.Column(type: "integer", nullable: false), - is_hot = table.Column(type: "boolean", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - config = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_regions", x => x.id); - table.UniqueConstraint("ak_regions_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_regions_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_memberships", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: false), - role = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - permissions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - legacy_role = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_memberships", x => x.id); - table.UniqueConstraint("ak_tenant_memberships_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_tenant_memberships_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_memberships_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "question_banks", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - source_scope = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_question_banks", x => x.id); - table.UniqueConstraint("ak_question_banks_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_question_banks_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_question_banks_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "region_modules", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - icon = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - text_color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - description = table.Column(type: "text", nullable: true), - route = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - sort_order = table.Column(type: "integer", nullable: false), - is_primary_school_module = table.Column(type: "boolean", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_region_modules", x => x.id); - table.UniqueConstraint("ak_region_modules_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_region_modules_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_region_modules_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "module_nodes", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - module_id = table.Column(type: "uuid", nullable: true), - parent_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_parent_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_module_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - path = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_module_nodes", x => x.id); - table.UniqueConstraint("ak_module_nodes_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_module_nodes_module_nodes_tenant_id_parent_id", - columns: x => new { x.tenant_id, x.parent_id }, - principalTable: "module_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_module_nodes_region_modules_tenant_id_module_id", - columns: x => new { x.tenant_id, x.module_id }, - principalTable: "region_modules", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_module_nodes_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_module_nodes_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "schools", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - module_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - professional_exam_date = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_schools", x => x.id); - table.UniqueConstraint("ak_schools_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_schools_region_modules_tenant_id_module_id", - columns: x => new { x.tenant_id, x.module_id }, - principalTable: "region_modules", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_schools_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_schools_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "majors", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - school_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - description = table.Column(type: "text", nullable: true), - study_tips = table.Column(type: "text", nullable: true), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_majors", x => x.id); - table.UniqueConstraint("ak_majors_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_majors_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_majors_schools_tenant_id_school_id", - columns: x => new { x.tenant_id, x.school_id }, - principalTable: "schools", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_majors_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "student_profiles", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: false), - legacy_user_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - region_id = table.Column(type: "uuid", nullable: true), - selected_school_id = table.Column(type: "uuid", nullable: true), - selected_major_id = table.Column(type: "uuid", nullable: true), - questions_answered_today = table.Column(type: "integer", nullable: false), - mastered_words_count = table.Column(type: "integer", nullable: false), - last_check_in_date = table.Column(type: "date", nullable: true), - stats = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - progress = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - module_selections = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - recent_activities = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_student_profiles", x => x.id); - table.UniqueConstraint("ak_student_profiles_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_student_profiles_majors_tenant_id_selected_major_id", - columns: x => new { x.tenant_id, x.selected_major_id }, - principalTable: "majors", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_student_profiles_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_student_profiles_schools_tenant_id_selected_school_id", - columns: x => new { x.tenant_id, x.selected_school_id }, - principalTable: "schools", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_student_profiles_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_student_profiles_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "subjects", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - module_id = table.Column(type: "uuid", nullable: true), - school_id = table.Column(type: "uuid", nullable: true), - major_id = table.Column(type: "uuid", nullable: true), - node_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - major_legacy_ids = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - icon = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - description = table.Column(type: "text", nullable: true), - stats = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_subjects", x => x.id); - table.UniqueConstraint("ak_subjects_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_subjects_majors_tenant_id_major_id", - columns: x => new { x.tenant_id, x.major_id }, - principalTable: "majors", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_subjects_module_nodes_tenant_id_node_id", - columns: x => new { x.tenant_id, x.node_id }, - principalTable: "module_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_subjects_region_modules_tenant_id_module_id", - columns: x => new { x.tenant_id, x.module_id }, - principalTable: "region_modules", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_subjects_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_subjects_schools_tenant_id_school_id", - columns: x => new { x.tenant_id, x.school_id }, - principalTable: "schools", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_subjects_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "categories", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - subject_id = table.Column(type: "uuid", nullable: true), - node_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - category_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - sort_order = table.Column(type: "integer", nullable: false), - svip_question_limit = table.Column(type: "integer", nullable: true), - is_active = table.Column(type: "boolean", nullable: false), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_categories", x => x.id); - table.UniqueConstraint("ak_categories_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_categories_module_nodes_tenant_id_node_id", - columns: x => new { x.tenant_id, x.node_id }, - principalTable: "module_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_categories_subjects_tenant_id_subject_id", - columns: x => new { x.tenant_id, x.subject_id }, - principalTable: "subjects", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_categories_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "answer_records", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: false), - question_id = table.Column(type: "uuid", nullable: true), - question_version_id = table.Column(type: "uuid", nullable: true), - practice_session_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_question_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_category_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - selected_options = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - answer_text = table.Column(type: "text", nullable: true), - is_correct = table.Column(type: "boolean", nullable: true), - answered_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - tenant_id = table.Column(type: "uuid", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("pk_answer_records", x => x.id); - table.UniqueConstraint("ak_answer_records_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); - table.ForeignKey( - name: "fk_answer_records_practice_sessions_tenant_id_user_id_practice~", - columns: x => new { x.tenant_id, x.user_id, x.practice_session_id }, - principalTable: "practice_sessions", - principalColumns: new[] { "tenant_id", "user_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_answer_records_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_answer_records_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "favorite_questions", - columns: table => new - { - tenant_id = table.Column(type: "uuid", nullable: false), - user_id = table.Column(type: "uuid", nullable: false), - question_id = table.Column(type: "uuid", nullable: false), - source = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_favorite_questions", x => new { x.tenant_id, x.user_id, x.question_id }); - table.ForeignKey( - name: "fk_favorite_questions_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_favorite_questions_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "question_versions", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - question_id = table.Column(type: "uuid", nullable: false), - version_no = table.Column(type: "integer", nullable: false), - content = table.Column(type: "text", nullable: true), - options = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - correct_option_index = table.Column(type: "integer", nullable: true), - correct_option_indices = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - answer_text = table.Column(type: "text", nullable: true), - explanation = table.Column(type: "text", nullable: true), - sub_questions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - code_lang = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - code_template = table.Column(type: "text", nullable: true), - source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), - created_by = table.Column(type: "uuid", nullable: true), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_question_versions", x => x.id); - table.UniqueConstraint("ak_question_versions_tenant_id_id", x => new { x.tenant_id, x.id }); - table.UniqueConstraint("ak_question_versions_tenant_id_question_id_id", x => new { x.tenant_id, x.question_id, x.id }); - table.ForeignKey( - name: "fk_question_versions_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "questions", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - question_bank_id = table.Column(type: "uuid", nullable: true), - subject_id = table.Column(type: "uuid", nullable: true), - category_id = table.Column(type: "uuid", nullable: true), - node_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_subject_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_category_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_node_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - type = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - type_label = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - difficulty = table.Column(type: "integer", nullable: true), - tags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - media_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - has_video_explanation = table.Column(type: "boolean", nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - current_version_id = table.Column(type: "uuid", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_questions", x => x.id); - table.UniqueConstraint("ak_questions_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_questions_categories_tenant_id_category_id", - columns: x => new { x.tenant_id, x.category_id }, - principalTable: "categories", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_questions_module_nodes_tenant_id_node_id", - columns: x => new { x.tenant_id, x.node_id }, - principalTable: "module_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_questions_question_banks_tenant_id_question_bank_id", - columns: x => new { x.tenant_id, x.question_bank_id }, - principalTable: "question_banks", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_questions_question_versions_tenant_id_id_current_version_id", - columns: x => new { x.tenant_id, x.id, x.current_version_id }, - principalTable: "question_versions", - principalColumns: new[] { "tenant_id", "question_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_questions_subjects_tenant_id_subject_id", - columns: x => new { x.tenant_id, x.subject_id }, - principalTable: "subjects", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_questions_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "wrong_questions", - columns: table => new - { - tenant_id = table.Column(type: "uuid", nullable: false), - user_id = table.Column(type: "uuid", nullable: false), - question_id = table.Column(type: "uuid", nullable: false), - wrong_count = table.Column(type: "integer", nullable: false, defaultValue: 1), - last_wrong_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - resolved_at = table.Column(type: "timestamp with time zone", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("pk_wrong_questions", x => new { x.tenant_id, x.user_id, x.question_id }); - table.ForeignKey( - name: "fk_wrong_questions_questions_tenant_id_question_id", - columns: x => new { x.tenant_id, x.question_id }, - principalTable: "questions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_wrong_questions_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_wrong_questions_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "ix_answer_records_tenant_id_legacy_id", - table: "answer_records", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_answer_records_tenant_id_question_id", - table: "answer_records", - columns: new[] { "tenant_id", "question_id" }); - - migrationBuilder.CreateIndex( - name: "ix_answer_records_tenant_id_question_id_question_version_id", - table: "answer_records", - columns: new[] { "tenant_id", "question_id", "question_version_id" }); - - migrationBuilder.CreateIndex( - name: "ix_answer_records_tenant_id_user_id_practice_session_id", - table: "answer_records", - columns: new[] { "tenant_id", "user_id", "practice_session_id" }); - - migrationBuilder.CreateIndex( - name: "ix_answer_records_user_id", - table: "answer_records", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_categories_tenant_id_legacy_id", - table: "categories", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_categories_tenant_id_node_id", - table: "categories", - columns: new[] { "tenant_id", "node_id" }); - - migrationBuilder.CreateIndex( - name: "ix_categories_tenant_id_subject_id", - table: "categories", - columns: new[] { "tenant_id", "subject_id" }); - - migrationBuilder.CreateIndex( - name: "ix_favorite_questions_tenant_id_question_id", - table: "favorite_questions", - columns: new[] { "tenant_id", "question_id" }); - - migrationBuilder.CreateIndex( - name: "ix_favorite_questions_user_id", - table: "favorite_questions", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_majors_tenant_id_legacy_id", - table: "majors", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_majors_tenant_id_region_id", - table: "majors", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_majors_tenant_id_school_id", - table: "majors", - columns: new[] { "tenant_id", "school_id" }); - - migrationBuilder.CreateIndex( - name: "ix_module_nodes_tenant_id_legacy_id", - table: "module_nodes", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_module_nodes_tenant_id_module_id", - table: "module_nodes", - columns: new[] { "tenant_id", "module_id" }); - - migrationBuilder.CreateIndex( - name: "ix_module_nodes_tenant_id_parent_id", - table: "module_nodes", - columns: new[] { "tenant_id", "parent_id" }); - - migrationBuilder.CreateIndex( - name: "ix_module_nodes_tenant_id_region_id", - table: "module_nodes", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_sessions_tenant_id_user_id_started_at", - table: "practice_sessions", - columns: new[] { "tenant_id", "user_id", "started_at" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_sessions_user_id", - table: "practice_sessions", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_question_banks_tenant_id_region_id", - table: "question_banks", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_question_versions_created_by", - table: "question_versions", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_question_versions_question_id_version_no", - table: "question_versions", - columns: new[] { "question_id", "version_no" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_questions_tenant_id_category_id", - table: "questions", - columns: new[] { "tenant_id", "category_id" }); - - migrationBuilder.CreateIndex( - name: "ix_questions_tenant_id_id_current_version_id", - table: "questions", - columns: new[] { "tenant_id", "id", "current_version_id" }); - - migrationBuilder.CreateIndex( - name: "ix_questions_tenant_id_legacy_id", - table: "questions", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_questions_tenant_id_node_id", - table: "questions", - columns: new[] { "tenant_id", "node_id" }); - - migrationBuilder.CreateIndex( - name: "ix_questions_tenant_id_question_bank_id", - table: "questions", - columns: new[] { "tenant_id", "question_bank_id" }); - - migrationBuilder.CreateIndex( - name: "ix_questions_tenant_id_subject_id", - table: "questions", - columns: new[] { "tenant_id", "subject_id" }); - - migrationBuilder.CreateIndex( - name: "ix_recent_practices_tenant_id_legacy_id", - table: "recent_practices", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_recent_practices_tenant_id_user_id_last_access_at", - table: "recent_practices", - columns: new[] { "tenant_id", "user_id", "last_access_at" }); - - migrationBuilder.CreateIndex( - name: "ix_recent_practices_user_id", - table: "recent_practices", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_region_modules_tenant_id_legacy_id", - table: "region_modules", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_region_modules_tenant_id_region_id", - table: "region_modules", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_regions_tenant_id_legacy_id", - table: "regions", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_schools_tenant_id_legacy_id", - table: "schools", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_schools_tenant_id_module_id", - table: "schools", - columns: new[] { "tenant_id", "module_id" }); - - migrationBuilder.CreateIndex( - name: "ix_schools_tenant_id_region_id", - table: "schools", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_student_profiles_tenant_id_region_id", - table: "student_profiles", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_student_profiles_tenant_id_selected_major_id", - table: "student_profiles", - columns: new[] { "tenant_id", "selected_major_id" }); - - migrationBuilder.CreateIndex( - name: "ix_student_profiles_tenant_id_selected_school_id", - table: "student_profiles", - columns: new[] { "tenant_id", "selected_school_id" }); - - migrationBuilder.CreateIndex( - name: "ix_student_profiles_tenant_id_user_id", - table: "student_profiles", - columns: new[] { "tenant_id", "user_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_student_profiles_user_id", - table: "student_profiles", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_subjects_tenant_id_legacy_id", - table: "subjects", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_subjects_tenant_id_major_id", - table: "subjects", - columns: new[] { "tenant_id", "major_id" }); - - migrationBuilder.CreateIndex( - name: "ix_subjects_tenant_id_module_id", - table: "subjects", - columns: new[] { "tenant_id", "module_id" }); - - migrationBuilder.CreateIndex( - name: "ix_subjects_tenant_id_node_id", - table: "subjects", - columns: new[] { "tenant_id", "node_id" }); - - migrationBuilder.CreateIndex( - name: "ix_subjects_tenant_id_region_id", - table: "subjects", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_subjects_tenant_id_school_id", - table: "subjects", - columns: new[] { "tenant_id", "school_id" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_memberships_tenant_id_user_id_role", - table: "tenant_memberships", - columns: new[] { "tenant_id", "user_id", "role" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_memberships_user_id", - table: "tenant_memberships", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_tenants_legacy_id", - table: "tenants", - column: "legacy_id", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenants_owner_user_id", - table: "tenants", - column: "owner_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_tenants_slug", - table: "tenants", - column: "slug", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_user_identities_provider_provider_subject", - table: "user_identities", - columns: new[] { "provider", "provider_subject" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_user_identities_user_id", - table: "user_identities", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_users_email", - table: "users", - column: "email", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_users_legacy_id", - table: "users", - column: "legacy_id", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_users_phone", - table: "users", - column: "phone", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_users_username", - table: "users", - column: "username", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_wrong_questions_tenant_id_question_id", - table: "wrong_questions", - columns: new[] { "tenant_id", "question_id" }); - - migrationBuilder.CreateIndex( - name: "ix_wrong_questions_user_id", - table: "wrong_questions", - column: "user_id"); - - migrationBuilder.AddForeignKey( - name: "fk_answer_records_question_versions_tenant_id_question_id_ques~", - table: "answer_records", - columns: new[] { "tenant_id", "question_id", "question_version_id" }, - principalTable: "question_versions", - principalColumns: new[] { "tenant_id", "question_id", "id" }, - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "fk_answer_records_questions_tenant_id_question_id", - table: "answer_records", - columns: new[] { "tenant_id", "question_id" }, - principalTable: "questions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "fk_favorite_questions_questions_tenant_id_question_id", - table: "favorite_questions", - columns: new[] { "tenant_id", "question_id" }, - principalTable: "questions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - - migrationBuilder.AddForeignKey( - name: "fk_question_versions_questions_tenant_id_question_id", - table: "question_versions", - columns: new[] { "tenant_id", "question_id" }, - principalTable: "questions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "fk_questions_question_versions_tenant_id_id_current_version_id", - table: "questions"); - - migrationBuilder.DropTable( - name: "answer_records"); - - migrationBuilder.DropTable( - name: "favorite_questions"); - - migrationBuilder.DropTable( - name: "recent_practices"); - - migrationBuilder.DropTable( - name: "student_profiles"); - - migrationBuilder.DropTable( - name: "tenant_memberships"); - - migrationBuilder.DropTable( - name: "user_identities"); - - migrationBuilder.DropTable( - name: "wrong_questions"); - - migrationBuilder.DropTable( - name: "practice_sessions"); - - migrationBuilder.DropTable( - name: "question_versions"); - - migrationBuilder.DropTable( - name: "questions"); - - migrationBuilder.DropTable( - name: "categories"); - - migrationBuilder.DropTable( - name: "question_banks"); - - migrationBuilder.DropTable( - name: "subjects"); - - migrationBuilder.DropTable( - name: "majors"); - - migrationBuilder.DropTable( - name: "module_nodes"); - - migrationBuilder.DropTable( - name: "schools"); - - migrationBuilder.DropTable( - name: "region_modules"); - - migrationBuilder.DropTable( - name: "regions"); - - migrationBuilder.DropTable( - name: "tenants"); - - migrationBuilder.DropTable( - name: "users"); - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725205731_AddContentNavigationAndTenantConfiguration.Designer.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725205731_AddContentNavigationAndTenantConfiguration.Designer.cs deleted file mode 100644 index 729c98d..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725205731_AddContentNavigationAndTenantConfiguration.Designer.cs +++ /dev/null @@ -1,3394 +0,0 @@ -// -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("20260725205731_AddContentNavigationAndTenantConfiguration")] - partial class AddContentNavigationAndTenantConfiguration - { - /// - 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.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.ContentNode", 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("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.PracticeBlueprint", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssemblyType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assembly_type"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_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("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PassScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("pass_score"); - - b.Property("QuestionLimit") - .HasColumnType("integer") - .HasColumnName("question_limit"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Rules") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("rules") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Sections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sections") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_practice_blueprints"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_blueprints_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_practice_blueprints_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_practice_blueprints_updated_by"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_collection_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_practice_blueprints_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_region_id"); - - b.HasIndex("TenantId", "NodeId", "CollectionId", "Mode", "Status", "SortOrder") - .HasDatabaseName("ix_practice_blueprints_tenant_id_node_id_collection_id_mode_st~"); - - b.ToTable("practice_blueprints", null, t => - { - t.HasCheckConstraint("ck_practice_blueprints_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_practice_blueprints_question_limit", "question_limit is null or question_limit > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - b.Property("CollectionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("collection_type"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Filters") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("filters") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_question_collections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collections_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_collections_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_question_collections_updated_by"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_question_collections_tenant_id_category_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_question_collections_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_collections_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_question_collections_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_collections_tenant_id_region_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_question_collections_tenant_id_subject_id"); - - b.HasIndex("TenantId", "NodeId", "Status", "SortOrder") - .HasDatabaseName("ix_question_collections_tenant_id_node_id_status_sort_order"); - - b.ToTable("question_collections", null, t => - { - t.HasCheckConstraint("ck_question_collections_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_question_collections_question_count", "question_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Required") - .HasColumnType("boolean") - .HasColumnName("required"); - - b.Property("Score") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - 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_question_collection_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collection_items_tenant_id_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_question_collection_items_tenant_id_question_id"); - - b.HasIndex("TenantId", "CollectionId", "QuestionId") - .IsUnique() - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_question_~"); - - b.HasIndex("TenantId", "CollectionId", "SectionKey", "SortOrder") - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_section_k~"); - - b.ToTable("question_collection_items", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", 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("LastCheckInDate") - .HasColumnType("date") - .HasColumnName("last_check_in_date"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("MasteredWordsCount") - .HasColumnType("integer") - .HasColumnName("mastered_words_count"); - - b.Property("ModuleSelections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_selections") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Progress") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("progress") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionsAnsweredToday") - .HasColumnType("integer") - .HasColumnName("questions_answered_today"); - - b.Property("RecentActivities") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("recent_activities") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SelectedMajorId") - .HasColumnType("uuid") - .HasColumnName("selected_major_id"); - - b.Property("SelectedSchoolId") - .HasColumnType("uuid") - .HasColumnName("selected_school_id"); - - b.Property("Stats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("stats") - .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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_student_profiles"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_student_profiles_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_student_profiles_user_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_student_profiles_tenant_id_region_id"); - - b.HasIndex("TenantId", "SelectedMajorId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_major_id"); - - b.HasIndex("TenantId", "SelectedSchoolId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_school_id"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_student_profiles_tenant_id_user_id"); - - b.ToTable("student_profiles", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AvatarUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("avatar_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("LastSeenAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_seen_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPasswordHash") - .HasMaxLength(512) - .HasColumnType("character varying(512)") - .HasColumnName("legacy_password_hash"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PasswordMigrationRequired") - .HasColumnType("boolean") - .HasColumnName("password_migration_required"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("PrimaryRole") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("primary_role"); - - b.Property("RawProfile") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_profile") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Score") - .HasColumnType("integer") - .HasColumnName("score"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Username") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("username"); - - b.HasKey("Id") - .HasName("pk_users"); - - b.HasIndex("Email") - .IsUnique() - .HasDatabaseName("ix_users_email"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_users_legacy_id"); - - b.HasIndex("Phone") - .IsUnique() - .HasDatabaseName("ix_users_phone"); - - b.HasIndex("Username") - .IsUnique() - .HasDatabaseName("ix_users_username"); - - b.ToTable("users", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", 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("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("OpenId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("open_id"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderSubject") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("provider_subject"); - - b.Property("SecretPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("secret_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UnionId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("union_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_identities"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_identities_user_id"); - - b.HasIndex("Provider", "ProviderSubject") - .IsUnique() - .HasDatabaseName("ix_user_identities_provider_provider_subject"); - - b.ToTable("user_identities", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("AnsweredAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("answered_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IsCorrect") - .HasColumnType("boolean") - .HasColumnName("is_correct"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("QuestionVersionId") - .HasColumnType("uuid") - .HasColumnName("question_version_id"); - - b.Property("SelectedOptions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("selected_options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_answer_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_answer_records_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_answer_records_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_answer_records_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id"); - - b.HasIndex("TenantId", "QuestionId", "QuestionVersionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id_question_version_id"); - - b.HasIndex("TenantId", "UserId", "PracticeSessionId") - .HasDatabaseName("ix_answer_records_tenant_id_user_id_practice_session_id"); - - b.ToTable("answer_records", null, t => - { - t.HasCheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_favorite_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_favorite_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_favorite_questions_tenant_id_question_id"); - - b.ToTable("favorite_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("ContentNodeId") - .HasColumnType("uuid") - .HasColumnName("content_node_id"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("FinishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("finished_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at") - .HasDefaultValueSql("now()"); - - b.Property("TargetId") - .HasColumnType("uuid") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_sessions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "UserId", "Id") - .HasName("ak_practice_sessions_tenant_id_user_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_sessions_user_id"); - - b.HasIndex("TenantId", "BlueprintId") - .HasDatabaseName("ix_practice_sessions_tenant_id_blueprint_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_sessions_tenant_id_collection_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_practice_sessions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_sessions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "UserId", "StartedAt") - .HasDatabaseName("ix_practice_sessions_tenant_id_user_id_started_at"); - - b.ToTable("practice_sessions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", 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("LastAccessAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_access_at"); - - b.Property("LastPracticeAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_practice_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("practice_type"); - - b.Property("Progress") - .HasColumnType("integer") - .HasColumnName("progress"); - - b.Property("TargetLegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("target_legacy_id"); - - b.Property("TargetName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("target_name"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_recent_practices"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_recent_practices_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_recent_practices_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_recent_practices_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "LastAccessAt") - .HasDatabaseName("ix_recent_practices_tenant_id_user_id_last_access_at"); - - b.ToTable("recent_practices", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("LastWrongAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("last_wrong_at") - .HasDefaultValueSql("now()"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("WrongCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(1) - .HasColumnName("wrong_count"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_wrong_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_wrong_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_wrong_questions_tenant_id_question_id"); - - b.ToTable("wrong_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - 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("CurrentVersionId") - .HasColumnType("uuid") - .HasColumnName("current_version_id"); - - b.Property("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExamMarkers") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("exam_markers") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("HasVideoExplanation") - .HasColumnType("boolean") - .HasColumnName("has_video_explanation"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyNodeId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_node_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("MediaUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("media_url"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PrimaryCollectionId") - .HasColumnType("uuid") - .HasColumnName("primary_collection_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Type") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("type"); - - b.Property("TypeLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("type_label"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_questions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_questions_tenant_id_id"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_questions_tenant_id_category_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_questions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_questions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_questions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "NodeId") - .HasDatabaseName("ix_questions_tenant_id_node_id"); - - b.HasIndex("TenantId", "PrimaryCollectionId") - .HasDatabaseName("ix_questions_tenant_id_primary_collection_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_questions_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_questions_tenant_id_subject_id"); - - b.HasIndex("TenantId", "Id", "CurrentVersionId") - .HasDatabaseName("ix_questions_tenant_id_id_current_version_id"); - - b.ToTable("questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SourceScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_scope"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_banks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_banks_tenant_id_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_banks_tenant_id_region_id"); - - b.ToTable("question_banks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("CodeLang") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("code_lang"); - - b.Property("CodeTemplate") - .HasColumnType("text") - .HasColumnName("code_template"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CorrectOptionIndex") - .HasColumnType("integer") - .HasColumnName("correct_option_index"); - - b.Property("CorrectOptionIndices") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("correct_option_indices") - .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("Explanation") - .HasColumnType("text") - .HasColumnName("explanation"); - - b.Property("Options") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubQuestions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sub_questions") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("VersionNo") - .HasColumnType("integer") - .HasColumnName("version_no"); - - b.HasKey("Id") - .HasName("pk_question_versions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_versions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "QuestionId", "Id") - .HasName("ak_question_versions_tenant_id_question_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_versions_created_by"); - - b.HasIndex("QuestionId", "VersionNo") - .IsUnique() - .HasDatabaseName("ix_question_versions_question_id_version_no"); - - b.ToTable("question_versions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BillingStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("billing_status"); - - 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("LegalName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("legal_name"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OwnerUserId") - .HasColumnType("uuid") - .HasColumnName("owner_user_id"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("slug"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenants"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenants_legacy_id"); - - b.HasIndex("OwnerUserId") - .HasDatabaseName("ix_tenants_owner_user_id"); - - b.HasIndex("Slug") - .IsUnique() - .HasDatabaseName("ix_tenants_slug"); - - b.ToTable("tenants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("BrandName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("brand_name"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FaviconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("favicon_url"); - - b.Property("LogoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("logo_url"); - - b.Property("OrganizationName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("organization_name"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ServiceAccountName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("service_account_name"); - - b.Property("ServiceWechat") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("service_wechat"); - - b.Property("ShortName") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("short_name"); - - b.Property("Slogan") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("slogan"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_branding"); - - b.ToTable("tenant_branding", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", 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("DomainType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("domain_type"); - - b.Property("Host") - .IsRequired() - .HasMaxLength(253) - .HasColumnType("citext") - .HasColumnName("host"); - - b.Property("IsPrimary") - .HasColumnType("boolean") - .HasColumnName("is_primary"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VerificationToken") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("verification_token"); - - b.Property("VerifiedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("verified_at"); - - b.HasKey("Id") - .HasName("pk_tenant_domains"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_domains_tenant_id_id"); - - b.HasIndex("Host") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_host"); - - b.HasIndex("TenantId", "IsPrimary") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_tenant_id_is_primary") - .HasFilter("is_primary"); - - b.ToTable("tenant_domains", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", 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("LegacyRole") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("legacy_role"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Role") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("role"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_memberships"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_memberships_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_memberships_user_id"); - - b.HasIndex("TenantId", "UserId", "Role") - .IsUnique() - .HasDatabaseName("ix_tenant_memberships_tenant_id_user_id_role"); - - b.ToTable("tenant_memberships", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("AdminFeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("admin_feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PublicConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_settings"); - - b.ToTable("tenant_settings", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Category", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_categories_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Major", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_majors_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.ModuleNode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_module_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_module_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Region", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_regions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.RegionModule", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_region_modules_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_region_modules_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.School", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_schools_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Subject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentEntry", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_entries_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentNode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_nodes_content_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_blueprints_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_question_collections_tenant_id_collecti~"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_question_banks_tenant_id_question_bank~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_question_collections_tenant_id_co~"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedMajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_majors_tenant_id_selected_major_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedSchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_schools_tenant_id_selected_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_identities_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId", "QuestionVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_question_versions_tenant_id_question_id_ques~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "UserId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "UserId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_practice_sessions_tenant_id_user_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_question_collections_tenant_id_collection~"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_recent_practices_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_recent_practices_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "PrimaryCollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_collections_tenant_id_primary_collection~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_banks_tenant_id_question_bank_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_subjects_tenant_id_subject_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "Id", "CurrentVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_versions_tenant_id_id_current_version_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_banks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_banks_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_versions_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_versions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("OwnerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenants_users_owner_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantBranding", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_branding_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_domains_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantSettings", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_settings_tenants_tenant_id"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725205731_AddContentNavigationAndTenantConfiguration.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725205731_AddContentNavigationAndTenantConfiguration.cs deleted file mode 100644 index d44de3e..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725205731_AddContentNavigationAndTenantConfiguration.cs +++ /dev/null @@ -1,932 +0,0 @@ -using System; -using System.Text.Json; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Tiku.Infrastructure.Persistence.Migrations -{ - /// - public partial class AddContentNavigationAndTenantConfiguration : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterDatabase() - .Annotation("Npgsql:PostgresExtension:citext", ",,") - .Annotation("Npgsql:PostgresExtension:ltree", ",,") - .OldAnnotation("Npgsql:PostgresExtension:citext", ",,"); - - migrationBuilder.AddColumn( - name: "content_node_id", - table: "questions", - type: "uuid", - nullable: true); - - migrationBuilder.AddColumn( - name: "entry_id", - table: "questions", - type: "uuid", - nullable: true); - - migrationBuilder.AddColumn( - name: "exam_markers", - table: "questions", - type: "jsonb", - nullable: false, - defaultValueSql: "'{}'::jsonb"); - - migrationBuilder.AddColumn( - name: "primary_collection_id", - table: "questions", - type: "uuid", - nullable: true); - - migrationBuilder.AddColumn( - name: "blueprint_id", - table: "practice_sessions", - type: "uuid", - nullable: true); - - migrationBuilder.AddColumn( - name: "collection_id", - table: "practice_sessions", - type: "uuid", - nullable: true); - - migrationBuilder.AddColumn( - name: "content_node_id", - table: "practice_sessions", - type: "uuid", - nullable: true); - - migrationBuilder.AddColumn( - name: "duration_minutes", - table: "practice_sessions", - type: "integer", - nullable: true); - - migrationBuilder.AddColumn( - name: "entry_id", - table: "practice_sessions", - type: "uuid", - nullable: true); - - migrationBuilder.AddColumn( - name: "expires_at", - table: "practice_sessions", - type: "timestamp with time zone", - nullable: true); - - migrationBuilder.AddColumn( - name: "question_count", - table: "practice_sessions", - type: "integer", - nullable: false, - defaultValue: 0); - - migrationBuilder.AddColumn( - name: "question_ids", - table: "practice_sessions", - type: "jsonb", - nullable: false, - defaultValueSql: "'[]'::jsonb"); - - migrationBuilder.AddColumn( - name: "total_score", - table: "practice_sessions", - type: "numeric(8,2)", - precision: 8, - scale: 2, - nullable: true); - - migrationBuilder.CreateTable( - name: "content_entries", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - entry_key = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - entry_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - icon = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - route = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - description = table.Column(type: "character varying(2000)", maxLength: 2000, nullable: true), - visibility = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - access_rules = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - layout_config = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - created_by = table.Column(type: "uuid", nullable: true), - updated_by = table.Column(type: "uuid", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_content_entries", x => x.id); - table.UniqueConstraint("ak_content_entries_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_content_entries_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_content_entries_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_content_entries_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_content_entries_users_updated_by", - column: x => x.updated_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "tenant_branding", - columns: table => new - { - tenant_id = table.Column(type: "uuid", nullable: false), - brand_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - short_name = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - slogan = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - organization_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - logo_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - favicon_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - service_wechat = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - service_account_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - theme = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - public_assets = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_branding", x => x.tenant_id); - table.ForeignKey( - name: "fk_tenant_branding_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_domains", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - host = table.Column(type: "citext", maxLength: 253, nullable: false), - domain_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - is_primary = table.Column(type: "boolean", nullable: false), - verification_token = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), - verified_at = table.Column(type: "timestamp with time zone", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_domains", x => x.id); - table.UniqueConstraint("ak_tenant_domains_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_tenant_domains_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_settings", - columns: table => new - { - tenant_id = table.Column(type: "uuid", nullable: false), - feature_flags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - admin_feature_flags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - public_config = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_settings", x => x.tenant_id); - table.ForeignKey( - name: "fk_tenant_settings_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "content_nodes", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - entry_id = table.Column(type: "uuid", nullable: false), - region_id = table.Column(type: "uuid", nullable: true), - parent_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - node_key = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - node_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - marker_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - marker_config = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - path = table.Column(type: "ltree", nullable: true), - depth = table.Column(type: "integer", nullable: false), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - is_selectable = table.Column(type: "boolean", nullable: false), - is_leaf = table.Column(type: "boolean", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_by = table.Column(type: "uuid", nullable: true), - updated_by = table.Column(type: "uuid", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_content_nodes", x => x.id); - table.UniqueConstraint("ak_content_nodes_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_content_nodes_depth", "depth >= 0"); - table.ForeignKey( - name: "fk_content_nodes_content_entries_tenant_id_entry_id", - columns: x => new { x.tenant_id, x.entry_id }, - principalTable: "content_entries", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_content_nodes_content_nodes_tenant_id_parent_id", - columns: x => new { x.tenant_id, x.parent_id }, - principalTable: "content_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_content_nodes_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_content_nodes_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_content_nodes_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_content_nodes_users_updated_by", - column: x => x.updated_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "question_collections", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - entry_id = table.Column(type: "uuid", nullable: true), - node_id = table.Column(type: "uuid", nullable: true), - subject_id = table.Column(type: "uuid", nullable: true), - category_id = table.Column(type: "uuid", nullable: true), - question_bank_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - collection_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - source_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - filters = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - question_count = table.Column(type: "integer", nullable: false), - total_score = table.Column(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true), - duration_minutes = table.Column(type: "integer", nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - sort_order = table.Column(type: "integer", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_by = table.Column(type: "uuid", nullable: true), - updated_by = table.Column(type: "uuid", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_question_collections", x => x.id); - table.UniqueConstraint("ak_question_collections_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_question_collections_duration", "duration_minutes is null or duration_minutes > 0"); - table.CheckConstraint("ck_question_collections_question_count", "question_count >= 0"); - table.ForeignKey( - name: "fk_question_collections_categories_tenant_id_category_id", - columns: x => new { x.tenant_id, x.category_id }, - principalTable: "categories", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_question_collections_content_entries_tenant_id_entry_id", - columns: x => new { x.tenant_id, x.entry_id }, - principalTable: "content_entries", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_question_collections_content_nodes_tenant_id_node_id", - columns: x => new { x.tenant_id, x.node_id }, - principalTable: "content_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_question_collections_question_banks_tenant_id_question_bank~", - columns: x => new { x.tenant_id, x.question_bank_id }, - principalTable: "question_banks", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_question_collections_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_question_collections_subjects_tenant_id_subject_id", - columns: x => new { x.tenant_id, x.subject_id }, - principalTable: "subjects", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_question_collections_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_question_collections_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_question_collections_users_updated_by", - column: x => x.updated_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "practice_blueprints", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - entry_id = table.Column(type: "uuid", nullable: true), - node_id = table.Column(type: "uuid", nullable: true), - collection_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - assembly_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - question_limit = table.Column(type: "integer", nullable: true), - duration_minutes = table.Column(type: "integer", nullable: true), - total_score = table.Column(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true), - pass_score = table.Column(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true), - sections = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - rules = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - sort_order = table.Column(type: "integer", nullable: false), - created_by = table.Column(type: "uuid", nullable: true), - updated_by = table.Column(type: "uuid", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_practice_blueprints", x => x.id); - table.UniqueConstraint("ak_practice_blueprints_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_practice_blueprints_duration", "duration_minutes is null or duration_minutes > 0"); - table.CheckConstraint("ck_practice_blueprints_question_limit", "question_limit is null or question_limit > 0"); - table.ForeignKey( - name: "fk_practice_blueprints_content_entries_tenant_id_entry_id", - columns: x => new { x.tenant_id, x.entry_id }, - principalTable: "content_entries", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_practice_blueprints_content_nodes_tenant_id_node_id", - columns: x => new { x.tenant_id, x.node_id }, - principalTable: "content_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_practice_blueprints_question_collections_tenant_id_collecti~", - columns: x => new { x.tenant_id, x.collection_id }, - principalTable: "question_collections", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_practice_blueprints_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_practice_blueprints_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_practice_blueprints_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_practice_blueprints_users_updated_by", - column: x => x.updated_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "question_collection_items", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - collection_id = table.Column(type: "uuid", nullable: false), - question_id = table.Column(type: "uuid", nullable: false), - section_key = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - sort_order = table.Column(type: "integer", nullable: false), - score = table.Column(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true), - required = table.Column(type: "boolean", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_question_collection_items", x => x.id); - table.UniqueConstraint("ak_question_collection_items_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_question_collection_items_question_collections_tenant_id_co~", - columns: x => new { x.tenant_id, x.collection_id }, - principalTable: "question_collections", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_question_collection_items_questions_tenant_id_question_id", - columns: x => new { x.tenant_id, x.question_id }, - principalTable: "questions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_question_collection_items_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "ix_questions_tenant_id_content_node_id", - table: "questions", - columns: new[] { "tenant_id", "content_node_id" }); - - migrationBuilder.CreateIndex( - name: "ix_questions_tenant_id_entry_id", - table: "questions", - columns: new[] { "tenant_id", "entry_id" }); - - migrationBuilder.CreateIndex( - name: "ix_questions_tenant_id_primary_collection_id", - table: "questions", - columns: new[] { "tenant_id", "primary_collection_id" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_sessions_tenant_id_blueprint_id", - table: "practice_sessions", - columns: new[] { "tenant_id", "blueprint_id" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_sessions_tenant_id_collection_id", - table: "practice_sessions", - columns: new[] { "tenant_id", "collection_id" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_sessions_tenant_id_content_node_id", - table: "practice_sessions", - columns: new[] { "tenant_id", "content_node_id" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_sessions_tenant_id_entry_id", - table: "practice_sessions", - columns: new[] { "tenant_id", "entry_id" }); - - migrationBuilder.CreateIndex( - name: "ix_content_entries_created_by", - table: "content_entries", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_content_entries_tenant_id_entry_key", - table: "content_entries", - columns: new[] { "tenant_id", "entry_key" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_content_entries_tenant_id_legacy_id", - table: "content_entries", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_content_entries_tenant_id_region_id_entry_type_is_active_so~", - table: "content_entries", - columns: new[] { "tenant_id", "region_id", "entry_type", "is_active", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_content_entries_updated_by", - table: "content_entries", - column: "updated_by"); - - migrationBuilder.CreateIndex( - name: "ix_content_nodes_created_by", - table: "content_nodes", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_content_nodes_path", - table: "content_nodes", - column: "path") - .Annotation("Npgsql:IndexMethod", "gist"); - - migrationBuilder.CreateIndex( - name: "ix_content_nodes_tenant_id_entry_id_node_key", - table: "content_nodes", - columns: new[] { "tenant_id", "entry_id", "node_key" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_content_nodes_tenant_id_entry_id_parent_id_sort_order", - table: "content_nodes", - columns: new[] { "tenant_id", "entry_id", "parent_id", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_content_nodes_tenant_id_legacy_id", - table: "content_nodes", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_content_nodes_tenant_id_marker_type", - table: "content_nodes", - columns: new[] { "tenant_id", "marker_type" }, - filter: "marker_type is not null"); - - migrationBuilder.CreateIndex( - name: "ix_content_nodes_tenant_id_parent_id", - table: "content_nodes", - columns: new[] { "tenant_id", "parent_id" }); - - migrationBuilder.CreateIndex( - name: "ix_content_nodes_tenant_id_region_id", - table: "content_nodes", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_content_nodes_updated_by", - table: "content_nodes", - column: "updated_by"); - - migrationBuilder.CreateIndex( - name: "ix_practice_blueprints_created_by", - table: "practice_blueprints", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_practice_blueprints_tenant_id_collection_id", - table: "practice_blueprints", - columns: new[] { "tenant_id", "collection_id" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_blueprints_tenant_id_entry_id", - table: "practice_blueprints", - columns: new[] { "tenant_id", "entry_id" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_blueprints_tenant_id_legacy_id", - table: "practice_blueprints", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_practice_blueprints_tenant_id_node_id_collection_id_mode_st~", - table: "practice_blueprints", - columns: new[] { "tenant_id", "node_id", "collection_id", "mode", "status", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_blueprints_tenant_id_region_id", - table: "practice_blueprints", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_blueprints_updated_by", - table: "practice_blueprints", - column: "updated_by"); - - migrationBuilder.CreateIndex( - name: "ix_question_collection_items_tenant_id_collection_id_question_~", - table: "question_collection_items", - columns: new[] { "tenant_id", "collection_id", "question_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_question_collection_items_tenant_id_collection_id_section_k~", - table: "question_collection_items", - columns: new[] { "tenant_id", "collection_id", "section_key", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_question_collection_items_tenant_id_question_id", - table: "question_collection_items", - columns: new[] { "tenant_id", "question_id" }); - - migrationBuilder.CreateIndex( - name: "ix_question_collections_created_by", - table: "question_collections", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_question_collections_tenant_id_category_id", - table: "question_collections", - columns: new[] { "tenant_id", "category_id" }); - - migrationBuilder.CreateIndex( - name: "ix_question_collections_tenant_id_entry_id", - table: "question_collections", - columns: new[] { "tenant_id", "entry_id" }); - - migrationBuilder.CreateIndex( - name: "ix_question_collections_tenant_id_legacy_id", - table: "question_collections", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_question_collections_tenant_id_node_id_status_sort_order", - table: "question_collections", - columns: new[] { "tenant_id", "node_id", "status", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_question_collections_tenant_id_question_bank_id", - table: "question_collections", - columns: new[] { "tenant_id", "question_bank_id" }); - - migrationBuilder.CreateIndex( - name: "ix_question_collections_tenant_id_region_id", - table: "question_collections", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_question_collections_tenant_id_subject_id", - table: "question_collections", - columns: new[] { "tenant_id", "subject_id" }); - - migrationBuilder.CreateIndex( - name: "ix_question_collections_updated_by", - table: "question_collections", - column: "updated_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_domains_host", - table: "tenant_domains", - column: "host", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_domains_tenant_id_is_primary", - table: "tenant_domains", - columns: new[] { "tenant_id", "is_primary" }, - unique: true, - filter: "is_primary"); - - migrationBuilder.AddForeignKey( - name: "fk_practice_sessions_content_entries_tenant_id_entry_id", - table: "practice_sessions", - columns: new[] { "tenant_id", "entry_id" }, - principalTable: "content_entries", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "fk_practice_sessions_content_nodes_tenant_id_content_node_id", - table: "practice_sessions", - columns: new[] { "tenant_id", "content_node_id" }, - principalTable: "content_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id", - table: "practice_sessions", - columns: new[] { "tenant_id", "blueprint_id" }, - principalTable: "practice_blueprints", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "fk_practice_sessions_question_collections_tenant_id_collection~", - table: "practice_sessions", - columns: new[] { "tenant_id", "collection_id" }, - principalTable: "question_collections", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "fk_questions_content_entries_tenant_id_entry_id", - table: "questions", - columns: new[] { "tenant_id", "entry_id" }, - principalTable: "content_entries", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "fk_questions_content_nodes_tenant_id_content_node_id", - table: "questions", - columns: new[] { "tenant_id", "content_node_id" }, - principalTable: "content_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "fk_questions_question_collections_tenant_id_primary_collection~", - table: "questions", - columns: new[] { "tenant_id", "primary_collection_id" }, - principalTable: "question_collections", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "fk_practice_sessions_content_entries_tenant_id_entry_id", - table: "practice_sessions"); - - migrationBuilder.DropForeignKey( - name: "fk_practice_sessions_content_nodes_tenant_id_content_node_id", - table: "practice_sessions"); - - migrationBuilder.DropForeignKey( - name: "fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id", - table: "practice_sessions"); - - migrationBuilder.DropForeignKey( - name: "fk_practice_sessions_question_collections_tenant_id_collection~", - table: "practice_sessions"); - - migrationBuilder.DropForeignKey( - name: "fk_questions_content_entries_tenant_id_entry_id", - table: "questions"); - - migrationBuilder.DropForeignKey( - name: "fk_questions_content_nodes_tenant_id_content_node_id", - table: "questions"); - - migrationBuilder.DropForeignKey( - name: "fk_questions_question_collections_tenant_id_primary_collection~", - table: "questions"); - - migrationBuilder.DropTable( - name: "practice_blueprints"); - - migrationBuilder.DropTable( - name: "question_collection_items"); - - migrationBuilder.DropTable( - name: "tenant_branding"); - - migrationBuilder.DropTable( - name: "tenant_domains"); - - migrationBuilder.DropTable( - name: "tenant_settings"); - - migrationBuilder.DropTable( - name: "question_collections"); - - migrationBuilder.DropTable( - name: "content_nodes"); - - migrationBuilder.DropTable( - name: "content_entries"); - - migrationBuilder.DropIndex( - name: "ix_questions_tenant_id_content_node_id", - table: "questions"); - - migrationBuilder.DropIndex( - name: "ix_questions_tenant_id_entry_id", - table: "questions"); - - migrationBuilder.DropIndex( - name: "ix_questions_tenant_id_primary_collection_id", - table: "questions"); - - migrationBuilder.DropIndex( - name: "ix_practice_sessions_tenant_id_blueprint_id", - table: "practice_sessions"); - - migrationBuilder.DropIndex( - name: "ix_practice_sessions_tenant_id_collection_id", - table: "practice_sessions"); - - migrationBuilder.DropIndex( - name: "ix_practice_sessions_tenant_id_content_node_id", - table: "practice_sessions"); - - migrationBuilder.DropIndex( - name: "ix_practice_sessions_tenant_id_entry_id", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "content_node_id", - table: "questions"); - - migrationBuilder.DropColumn( - name: "entry_id", - table: "questions"); - - migrationBuilder.DropColumn( - name: "exam_markers", - table: "questions"); - - migrationBuilder.DropColumn( - name: "primary_collection_id", - table: "questions"); - - migrationBuilder.DropColumn( - name: "blueprint_id", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "collection_id", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "content_node_id", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "duration_minutes", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "entry_id", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "expires_at", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "question_count", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "question_ids", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "total_score", - table: "practice_sessions"); - - migrationBuilder.AlterDatabase() - .Annotation("Npgsql:PostgresExtension:citext", ",,") - .OldAnnotation("Npgsql:PostgresExtension:citext", ",,") - .OldAnnotation("Npgsql:PostgresExtension:ltree", ",,"); - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725210815_AddVocabularyAndHandbookPersistence.Designer.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725210815_AddVocabularyAndHandbookPersistence.Designer.cs deleted file mode 100644 index 00f3c8c..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725210815_AddVocabularyAndHandbookPersistence.Designer.cs +++ /dev/null @@ -1,4505 +0,0 @@ -// -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("20260725210815_AddVocabularyAndHandbookPersistence")] - partial class AddVocabularyAndHandbookPersistence - { - /// - 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.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.ContentNode", 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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_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_handbook_chapters"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_chapters_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_chapters_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_subject_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_chapters_tenant_id_entry_id_content_node_id_subjec~"); - - b.ToTable("handbook_chapters", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ChapterId") - .HasColumnType("uuid") - .HasColumnName("chapter_id"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Summary") - .HasColumnType("text") - .HasColumnName("summary"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_handbook_entries"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_entries_tenant_id_id"); - - b.HasIndex("TenantId", "ChapterId") - .HasDatabaseName("ix_handbook_entries_tenant_id_chapter_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_entries_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_entries_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "ChapterId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_entries_tenant_id_entry_id_content_node_id_chapter~"); - - b.ToTable("handbook_entries", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", 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("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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - 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_handbook_subjects"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_subjects_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_subjects_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "MajorId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_major_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_school_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_subjects_tenant_id_entry_id_content_node_id_region~"); - - b.ToTable("handbook_subjects", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssemblyType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assembly_type"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_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("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PassScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("pass_score"); - - b.Property("QuestionLimit") - .HasColumnType("integer") - .HasColumnName("question_limit"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Rules") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("rules") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Sections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sections") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_practice_blueprints"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_blueprints_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_practice_blueprints_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_practice_blueprints_updated_by"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_collection_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_practice_blueprints_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_region_id"); - - b.HasIndex("TenantId", "NodeId", "CollectionId", "Mode", "Status", "SortOrder") - .HasDatabaseName("ix_practice_blueprints_tenant_id_node_id_collection_id_mode_st~"); - - b.ToTable("practice_blueprints", null, t => - { - t.HasCheckConstraint("ck_practice_blueprints_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_practice_blueprints_question_limit", "question_limit is null or question_limit > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - b.Property("CollectionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("collection_type"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Filters") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("filters") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_question_collections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collections_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_collections_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_question_collections_updated_by"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_question_collections_tenant_id_category_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_question_collections_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_collections_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_question_collections_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_collections_tenant_id_region_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_question_collections_tenant_id_subject_id"); - - b.HasIndex("TenantId", "NodeId", "Status", "SortOrder") - .HasDatabaseName("ix_question_collections_tenant_id_node_id_status_sort_order"); - - b.ToTable("question_collections", null, t => - { - t.HasCheckConstraint("ck_question_collections_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_question_collections_question_count", "question_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Required") - .HasColumnType("boolean") - .HasColumnName("required"); - - b.Property("Score") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - 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_question_collection_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collection_items_tenant_id_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_question_collection_items_tenant_id_question_id"); - - b.HasIndex("TenantId", "CollectionId", "QuestionId") - .IsUnique() - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_question_~"); - - b.HasIndex("TenantId", "CollectionId", "SectionKey", "SortOrder") - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_section_k~"); - - b.ToTable("question_collection_items", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", 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("DisplayName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Types") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("types") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_question_type_groups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_type_groups_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_type_groups_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_question_type_groups_tenant_id_subject_id_is_active_sort_or~"); - - b.ToTable("question_type_groups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("SourceSubjectId") - .HasColumnType("uuid") - .HasColumnName("source_subject_id"); - - b.Property("TargetSubjectId") - .HasColumnType("uuid") - .HasColumnName("target_subject_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Id") - .HasColumnType("uuid") - .HasColumnName("id"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacySourceSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_source_subject_id"); - - b.Property("LegacyTargetSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_target_subject_id"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at"); - - b.HasKey("TenantId", "SourceSubjectId", "TargetSubjectId") - .HasName("pk_subject_shares"); - - b.HasIndex("TenantId", "TargetSubjectId") - .HasDatabaseName("ix_subject_shares_tenant_id_target_subject_id"); - - b.ToTable("subject_shares", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", 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("FavoritedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("favorited_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Note") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.HasKey("Id") - .HasName("pk_user_word_favorites"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_favorites_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_favorites_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_favorites_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_favorites_tenant_id_user_id_word_id"); - - b.ToTable("user_word_favorites", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CorrectStreak") - .HasColumnType("integer") - .HasColumnName("correct_streak"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DueLevel") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("due_level"); - - b.Property("EaseFactor") - .ValueGeneratedOnAdd() - .HasPrecision(4, 2) - .HasColumnType("numeric(4,2)") - .HasDefaultValue(2.50m) - .HasColumnName("ease_factor"); - - b.Property("LastResult") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("last_result"); - - b.Property("LastReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_review_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NextReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_review_at"); - - b.Property("ReviewCount") - .HasColumnType("integer") - .HasColumnName("review_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_user_word_progress"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_progress_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_progress_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_progress_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_word_id"); - - b.HasIndex("TenantId", "UserId", "NextReviewAt", "Status", "DueLevel") - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_next_review_at_status_~"); - - b.ToTable("user_word_progress", null, t => - { - t.HasCheckConstraint("ck_user_word_progress_correct_streak", "correct_streak >= 0"); - - t.HasCheckConstraint("ck_user_word_progress_ease_factor", "ease_factor >= 1.30 and ease_factor <= 3.00"); - - t.HasCheckConstraint("ck_user_word_progress_review_count", "review_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WordCount") - .HasColumnType("integer") - .HasColumnName("word_count"); - - b.HasKey("Id") - .HasName("pk_vocabulary_units"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_units_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_units_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_region_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_units_tenant_id_entry_id_content_node_id_region_~"); - - b.ToTable("vocabulary_units", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Example") - .HasColumnType("text") - .HasColumnName("example"); - - b.Property("ExampleTranslation") - .HasColumnType("text") - .HasColumnName("example_translation"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Meaning") - .HasColumnType("text") - .HasColumnName("meaning"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phonetic") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("phonetic"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitId") - .HasColumnType("uuid") - .HasColumnName("unit_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Word") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("word"); - - b.HasKey("Id") - .HasName("pk_vocabulary_words"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_words_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_words_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_words_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UnitId", "IsActive", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_vocabulary_words_tenant_id_unit_id_is_active_sort_order_cre~"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "UnitId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_words_tenant_id_entry_id_content_node_id_unit_id~"); - - b.ToTable("vocabulary_words", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", 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("LastCheckInDate") - .HasColumnType("date") - .HasColumnName("last_check_in_date"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("MasteredWordsCount") - .HasColumnType("integer") - .HasColumnName("mastered_words_count"); - - b.Property("ModuleSelections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_selections") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Progress") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("progress") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionsAnsweredToday") - .HasColumnType("integer") - .HasColumnName("questions_answered_today"); - - b.Property("RecentActivities") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("recent_activities") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SelectedMajorId") - .HasColumnType("uuid") - .HasColumnName("selected_major_id"); - - b.Property("SelectedSchoolId") - .HasColumnType("uuid") - .HasColumnName("selected_school_id"); - - b.Property("Stats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("stats") - .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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_student_profiles"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_student_profiles_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_student_profiles_user_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_student_profiles_tenant_id_region_id"); - - b.HasIndex("TenantId", "SelectedMajorId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_major_id"); - - b.HasIndex("TenantId", "SelectedSchoolId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_school_id"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_student_profiles_tenant_id_user_id"); - - b.ToTable("student_profiles", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AvatarUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("avatar_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("LastSeenAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_seen_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPasswordHash") - .HasMaxLength(512) - .HasColumnType("character varying(512)") - .HasColumnName("legacy_password_hash"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PasswordMigrationRequired") - .HasColumnType("boolean") - .HasColumnName("password_migration_required"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("PrimaryRole") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("primary_role"); - - b.Property("RawProfile") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_profile") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Score") - .HasColumnType("integer") - .HasColumnName("score"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Username") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("username"); - - b.HasKey("Id") - .HasName("pk_users"); - - b.HasIndex("Email") - .IsUnique() - .HasDatabaseName("ix_users_email"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_users_legacy_id"); - - b.HasIndex("Phone") - .IsUnique() - .HasDatabaseName("ix_users_phone"); - - b.HasIndex("Username") - .IsUnique() - .HasDatabaseName("ix_users_username"); - - b.ToTable("users", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", 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("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("OpenId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("open_id"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderSubject") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("provider_subject"); - - b.Property("SecretPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("secret_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UnionId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("union_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_identities"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_identities_user_id"); - - b.HasIndex("Provider", "ProviderSubject") - .IsUnique() - .HasDatabaseName("ix_user_identities_provider_provider_subject"); - - b.ToTable("user_identities", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("AnsweredAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("answered_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IsCorrect") - .HasColumnType("boolean") - .HasColumnName("is_correct"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("QuestionVersionId") - .HasColumnType("uuid") - .HasColumnName("question_version_id"); - - b.Property("SelectedOptions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("selected_options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_answer_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_answer_records_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_answer_records_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_answer_records_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id"); - - b.HasIndex("TenantId", "QuestionId", "QuestionVersionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id_question_version_id"); - - b.HasIndex("TenantId", "UserId", "PracticeSessionId") - .HasDatabaseName("ix_answer_records_tenant_id_user_id_practice_session_id"); - - b.ToTable("answer_records", null, t => - { - t.HasCheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_favorite_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_favorite_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_favorite_questions_tenant_id_question_id"); - - b.ToTable("favorite_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("ContentNodeId") - .HasColumnType("uuid") - .HasColumnName("content_node_id"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("FinishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("finished_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at") - .HasDefaultValueSql("now()"); - - b.Property("TargetId") - .HasColumnType("uuid") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_sessions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "UserId", "Id") - .HasName("ak_practice_sessions_tenant_id_user_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_sessions_user_id"); - - b.HasIndex("TenantId", "BlueprintId") - .HasDatabaseName("ix_practice_sessions_tenant_id_blueprint_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_sessions_tenant_id_collection_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_practice_sessions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_sessions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "UserId", "StartedAt") - .HasDatabaseName("ix_practice_sessions_tenant_id_user_id_started_at"); - - b.ToTable("practice_sessions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", 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("LastAccessAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_access_at"); - - b.Property("LastPracticeAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_practice_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("practice_type"); - - b.Property("Progress") - .HasColumnType("integer") - .HasColumnName("progress"); - - b.Property("TargetLegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("target_legacy_id"); - - b.Property("TargetName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("target_name"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_recent_practices"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_recent_practices_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_recent_practices_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_recent_practices_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "LastAccessAt") - .HasDatabaseName("ix_recent_practices_tenant_id_user_id_last_access_at"); - - b.ToTable("recent_practices", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("LastWrongAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("last_wrong_at") - .HasDefaultValueSql("now()"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("WrongCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(1) - .HasColumnName("wrong_count"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_wrong_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_wrong_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_wrong_questions_tenant_id_question_id"); - - b.ToTable("wrong_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - 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("CurrentVersionId") - .HasColumnType("uuid") - .HasColumnName("current_version_id"); - - b.Property("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExamMarkers") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("exam_markers") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("HasVideoExplanation") - .HasColumnType("boolean") - .HasColumnName("has_video_explanation"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyNodeId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_node_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("MediaUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("media_url"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PrimaryCollectionId") - .HasColumnType("uuid") - .HasColumnName("primary_collection_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Type") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("type"); - - b.Property("TypeLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("type_label"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_questions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_questions_tenant_id_id"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_questions_tenant_id_category_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_questions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_questions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_questions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "NodeId") - .HasDatabaseName("ix_questions_tenant_id_node_id"); - - b.HasIndex("TenantId", "PrimaryCollectionId") - .HasDatabaseName("ix_questions_tenant_id_primary_collection_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_questions_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_questions_tenant_id_subject_id"); - - b.HasIndex("TenantId", "Id", "CurrentVersionId") - .HasDatabaseName("ix_questions_tenant_id_id_current_version_id"); - - b.ToTable("questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SourceScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_scope"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_banks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_banks_tenant_id_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_banks_tenant_id_region_id"); - - b.ToTable("question_banks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("CodeLang") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("code_lang"); - - b.Property("CodeTemplate") - .HasColumnType("text") - .HasColumnName("code_template"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CorrectOptionIndex") - .HasColumnType("integer") - .HasColumnName("correct_option_index"); - - b.Property("CorrectOptionIndices") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("correct_option_indices") - .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("Explanation") - .HasColumnType("text") - .HasColumnName("explanation"); - - b.Property("Options") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubQuestions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sub_questions") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("VersionNo") - .HasColumnType("integer") - .HasColumnName("version_no"); - - b.HasKey("Id") - .HasName("pk_question_versions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_versions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "QuestionId", "Id") - .HasName("ak_question_versions_tenant_id_question_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_versions_created_by"); - - b.HasIndex("QuestionId", "VersionNo") - .IsUnique() - .HasDatabaseName("ix_question_versions_question_id_version_no"); - - b.ToTable("question_versions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BillingStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("billing_status"); - - 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("LegalName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("legal_name"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OwnerUserId") - .HasColumnType("uuid") - .HasColumnName("owner_user_id"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("slug"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenants"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenants_legacy_id"); - - b.HasIndex("OwnerUserId") - .HasDatabaseName("ix_tenants_owner_user_id"); - - b.HasIndex("Slug") - .IsUnique() - .HasDatabaseName("ix_tenants_slug"); - - b.ToTable("tenants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("BrandName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("brand_name"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FaviconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("favicon_url"); - - b.Property("LogoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("logo_url"); - - b.Property("OrganizationName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("organization_name"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ServiceAccountName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("service_account_name"); - - b.Property("ServiceWechat") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("service_wechat"); - - b.Property("ShortName") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("short_name"); - - b.Property("Slogan") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("slogan"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_branding"); - - b.ToTable("tenant_branding", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", 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("DomainType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("domain_type"); - - b.Property("Host") - .IsRequired() - .HasMaxLength(253) - .HasColumnType("citext") - .HasColumnName("host"); - - b.Property("IsPrimary") - .HasColumnType("boolean") - .HasColumnName("is_primary"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VerificationToken") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("verification_token"); - - b.Property("VerifiedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("verified_at"); - - b.HasKey("Id") - .HasName("pk_tenant_domains"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_domains_tenant_id_id"); - - b.HasIndex("Host") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_host"); - - b.HasIndex("TenantId", "IsPrimary") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_tenant_id_is_primary") - .HasFilter("is_primary"); - - b.ToTable("tenant_domains", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", 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("LegacyRole") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("legacy_role"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Role") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("role"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_memberships"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_memberships_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_memberships_user_id"); - - b.HasIndex("TenantId", "UserId", "Role") - .IsUnique() - .HasDatabaseName("ix_tenant_memberships_tenant_id_user_id_role"); - - b.ToTable("tenant_memberships", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("AdminFeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("admin_feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PublicConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_settings"); - - b.ToTable("tenant_settings", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Category", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_categories_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Major", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_majors_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.ModuleNode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_module_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_module_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Region", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_regions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.RegionModule", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_region_modules_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_region_modules_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.School", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_schools_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Subject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentEntry", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_entries_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentNode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_nodes_content_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookChapter", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_chapters_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.HandbookSubject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_chapters_handbook_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.HandbookChapter", null) - .WithMany() - .HasForeignKey("TenantId", "ChapterId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_entries_handbook_chapters_tenant_id_chapter_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_blueprints_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_question_collections_tenant_id_collecti~"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_question_banks_tenant_id_question_bank~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_question_collections_tenant_id_co~"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_type_groups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_type_groups_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SourceSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_source_subject_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_units_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_words_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyUnit", null) - .WithMany() - .HasForeignKey("TenantId", "UnitId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_vocabulary_units_tenant_id_unit_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedMajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_majors_tenant_id_selected_major_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedSchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_schools_tenant_id_selected_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_identities_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId", "QuestionVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_question_versions_tenant_id_question_id_ques~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "UserId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "UserId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_practice_sessions_tenant_id_user_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_question_collections_tenant_id_collection~"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_recent_practices_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_recent_practices_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "PrimaryCollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_collections_tenant_id_primary_collection~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_banks_tenant_id_question_bank_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_subjects_tenant_id_subject_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "Id", "CurrentVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_versions_tenant_id_id_current_version_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_banks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_banks_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_versions_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_versions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("OwnerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenants_users_owner_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantBranding", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_branding_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_domains_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantSettings", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_settings_tenants_tenant_id"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725210815_AddVocabularyAndHandbookPersistence.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725210815_AddVocabularyAndHandbookPersistence.cs deleted file mode 100644 index 550853b..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725210815_AddVocabularyAndHandbookPersistence.cs +++ /dev/null @@ -1,648 +0,0 @@ -using System; -using System.Text.Json; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Tiku.Infrastructure.Persistence.Migrations -{ - /// - public partial class AddVocabularyAndHandbookPersistence : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "handbook_subjects", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - school_id = table.Column(type: "uuid", nullable: true), - major_id = table.Column(type: "uuid", nullable: true), - entry_id = table.Column(type: "uuid", nullable: true), - content_node_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - icon = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - description = table.Column(type: "text", nullable: true), - major_legacy_ids = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_handbook_subjects", x => x.id); - table.UniqueConstraint("ak_handbook_subjects_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_handbook_subjects_content_entries_tenant_id_entry_id", - columns: x => new { x.tenant_id, x.entry_id }, - principalTable: "content_entries", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_handbook_subjects_content_nodes_tenant_id_content_node_id", - columns: x => new { x.tenant_id, x.content_node_id }, - principalTable: "content_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_handbook_subjects_majors_tenant_id_major_id", - columns: x => new { x.tenant_id, x.major_id }, - principalTable: "majors", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_handbook_subjects_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_handbook_subjects_schools_tenant_id_school_id", - columns: x => new { x.tenant_id, x.school_id }, - principalTable: "schools", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_handbook_subjects_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "question_type_groups", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - subject_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - display_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - types = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_question_type_groups", x => x.id); - table.UniqueConstraint("ak_question_type_groups_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_question_type_groups_subjects_tenant_id_subject_id", - columns: x => new { x.tenant_id, x.subject_id }, - principalTable: "subjects", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_question_type_groups_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "subject_shares", - columns: table => new - { - tenant_id = table.Column(type: "uuid", nullable: false), - source_subject_id = table.Column(type: "uuid", nullable: false), - target_subject_id = table.Column(type: "uuid", nullable: false), - legacy_id = table.Column(type: "text", nullable: true), - legacy_source_subject_id = table.Column(type: "text", nullable: true), - legacy_target_subject_id = table.Column(type: "text", nullable: true), - id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("pk_subject_shares", x => new { x.tenant_id, x.source_subject_id, x.target_subject_id }); - table.ForeignKey( - name: "fk_subject_shares_subjects_tenant_id_source_subject_id", - columns: x => new { x.tenant_id, x.source_subject_id }, - principalTable: "subjects", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_subject_shares_subjects_tenant_id_target_subject_id", - columns: x => new { x.tenant_id, x.target_subject_id }, - principalTable: "subjects", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_subject_shares_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "vocabulary_units", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - entry_id = table.Column(type: "uuid", nullable: true), - content_node_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - description = table.Column(type: "text", nullable: true), - word_count = table.Column(type: "integer", nullable: true), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_vocabulary_units", x => x.id); - table.UniqueConstraint("ak_vocabulary_units_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_vocabulary_units_content_entries_tenant_id_entry_id", - columns: x => new { x.tenant_id, x.entry_id }, - principalTable: "content_entries", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_vocabulary_units_content_nodes_tenant_id_content_node_id", - columns: x => new { x.tenant_id, x.content_node_id }, - principalTable: "content_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_vocabulary_units_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_vocabulary_units_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "handbook_chapters", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - subject_id = table.Column(type: "uuid", nullable: true), - entry_id = table.Column(type: "uuid", nullable: true), - content_node_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - description = table.Column(type: "text", nullable: true), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_handbook_chapters", x => x.id); - table.UniqueConstraint("ak_handbook_chapters_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_handbook_chapters_content_entries_tenant_id_entry_id", - columns: x => new { x.tenant_id, x.entry_id }, - principalTable: "content_entries", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_handbook_chapters_content_nodes_tenant_id_content_node_id", - columns: x => new { x.tenant_id, x.content_node_id }, - principalTable: "content_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_handbook_chapters_handbook_subjects_tenant_id_subject_id", - columns: x => new { x.tenant_id, x.subject_id }, - principalTable: "handbook_subjects", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_handbook_chapters_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "vocabulary_words", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - unit_id = table.Column(type: "uuid", nullable: true), - entry_id = table.Column(type: "uuid", nullable: true), - content_node_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - word = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - phonetic = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - meaning = table.Column(type: "text", nullable: true), - example = table.Column(type: "text", nullable: true), - example_translation = table.Column(type: "text", nullable: true), - difficulty = table.Column(type: "integer", nullable: true), - tags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_vocabulary_words", x => x.id); - table.UniqueConstraint("ak_vocabulary_words_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_vocabulary_words_content_entries_tenant_id_entry_id", - columns: x => new { x.tenant_id, x.entry_id }, - principalTable: "content_entries", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_vocabulary_words_content_nodes_tenant_id_content_node_id", - columns: x => new { x.tenant_id, x.content_node_id }, - principalTable: "content_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_vocabulary_words_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_vocabulary_words_vocabulary_units_tenant_id_unit_id", - columns: x => new { x.tenant_id, x.unit_id }, - principalTable: "vocabulary_units", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "handbook_entries", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - chapter_id = table.Column(type: "uuid", nullable: true), - entry_id = table.Column(type: "uuid", nullable: true), - content_node_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - title = table.Column(type: "character varying(500)", maxLength: 500, nullable: false), - summary = table.Column(type: "text", nullable: true), - content = table.Column(type: "text", nullable: true), - tags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_handbook_entries", x => x.id); - table.UniqueConstraint("ak_handbook_entries_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_handbook_entries_content_entries_tenant_id_entry_id", - columns: x => new { x.tenant_id, x.entry_id }, - principalTable: "content_entries", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_handbook_entries_content_nodes_tenant_id_content_node_id", - columns: x => new { x.tenant_id, x.content_node_id }, - principalTable: "content_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_handbook_entries_handbook_chapters_tenant_id_chapter_id", - columns: x => new { x.tenant_id, x.chapter_id }, - principalTable: "handbook_chapters", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_handbook_entries_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "user_word_favorites", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: false), - word_id = table.Column(type: "uuid", nullable: false), - legacy_id = table.Column(type: "text", nullable: true), - legacy_user_id = table.Column(type: "text", nullable: true), - legacy_word_id = table.Column(type: "text", nullable: true), - note = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - favorited_at = table.Column(type: "timestamp with time zone", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_user_word_favorites", x => x.id); - table.UniqueConstraint("ak_user_word_favorites_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_user_word_favorites_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_user_word_favorites_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_user_word_favorites_vocabulary_words_tenant_id_word_id", - columns: x => new { x.tenant_id, x.word_id }, - principalTable: "vocabulary_words", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "user_word_progress", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: false), - word_id = table.Column(type: "uuid", nullable: false), - legacy_id = table.Column(type: "text", nullable: true), - legacy_user_id = table.Column(type: "text", nullable: true), - legacy_word_id = table.Column(type: "text", nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - correct_count = table.Column(type: "integer", nullable: false), - wrong_count = table.Column(type: "integer", nullable: false), - last_review_at = table.Column(type: "timestamp with time zone", nullable: true), - next_review_at = table.Column(type: "timestamp with time zone", nullable: true), - review_count = table.Column(type: "integer", nullable: false), - correct_streak = table.Column(type: "integer", nullable: false), - ease_factor = table.Column(type: "numeric(4,2)", precision: 4, scale: 2, nullable: false, defaultValue: 2.50m), - last_result = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - due_level = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_user_word_progress", x => x.id); - table.UniqueConstraint("ak_user_word_progress_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_user_word_progress_correct_streak", "correct_streak >= 0"); - table.CheckConstraint("ck_user_word_progress_ease_factor", "ease_factor >= 1.30 and ease_factor <= 3.00"); - table.CheckConstraint("ck_user_word_progress_review_count", "review_count >= 0"); - table.ForeignKey( - name: "fk_user_word_progress_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_user_word_progress_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_user_word_progress_vocabulary_words_tenant_id_word_id", - columns: x => new { x.tenant_id, x.word_id }, - principalTable: "vocabulary_words", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "ix_handbook_chapters_tenant_id_content_node_id", - table: "handbook_chapters", - columns: new[] { "tenant_id", "content_node_id" }); - - migrationBuilder.CreateIndex( - name: "ix_handbook_chapters_tenant_id_entry_id_content_node_id_subjec~", - table: "handbook_chapters", - columns: new[] { "tenant_id", "entry_id", "content_node_id", "subject_id", "is_active", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_handbook_chapters_tenant_id_legacy_id", - table: "handbook_chapters", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_handbook_chapters_tenant_id_subject_id", - table: "handbook_chapters", - columns: new[] { "tenant_id", "subject_id" }); - - migrationBuilder.CreateIndex( - name: "ix_handbook_entries_tenant_id_chapter_id", - table: "handbook_entries", - columns: new[] { "tenant_id", "chapter_id" }); - - migrationBuilder.CreateIndex( - name: "ix_handbook_entries_tenant_id_content_node_id", - table: "handbook_entries", - columns: new[] { "tenant_id", "content_node_id" }); - - migrationBuilder.CreateIndex( - name: "ix_handbook_entries_tenant_id_entry_id_content_node_id_chapter~", - table: "handbook_entries", - columns: new[] { "tenant_id", "entry_id", "content_node_id", "chapter_id", "is_active", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_handbook_entries_tenant_id_legacy_id", - table: "handbook_entries", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_handbook_subjects_tenant_id_content_node_id", - table: "handbook_subjects", - columns: new[] { "tenant_id", "content_node_id" }); - - migrationBuilder.CreateIndex( - name: "ix_handbook_subjects_tenant_id_entry_id_content_node_id_region~", - table: "handbook_subjects", - columns: new[] { "tenant_id", "entry_id", "content_node_id", "region_id", "is_active", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_handbook_subjects_tenant_id_legacy_id", - table: "handbook_subjects", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_handbook_subjects_tenant_id_major_id", - table: "handbook_subjects", - columns: new[] { "tenant_id", "major_id" }); - - migrationBuilder.CreateIndex( - name: "ix_handbook_subjects_tenant_id_region_id", - table: "handbook_subjects", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_handbook_subjects_tenant_id_school_id", - table: "handbook_subjects", - columns: new[] { "tenant_id", "school_id" }); - - migrationBuilder.CreateIndex( - name: "ix_question_type_groups_tenant_id_legacy_id", - table: "question_type_groups", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_question_type_groups_tenant_id_subject_id_is_active_sort_or~", - table: "question_type_groups", - columns: new[] { "tenant_id", "subject_id", "is_active", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_subject_shares_tenant_id_target_subject_id", - table: "subject_shares", - columns: new[] { "tenant_id", "target_subject_id" }); - - migrationBuilder.CreateIndex( - name: "ix_user_word_favorites_tenant_id_user_id_word_id", - table: "user_word_favorites", - columns: new[] { "tenant_id", "user_id", "word_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_user_word_favorites_tenant_id_word_id", - table: "user_word_favorites", - columns: new[] { "tenant_id", "word_id" }); - - migrationBuilder.CreateIndex( - name: "ix_user_word_favorites_user_id", - table: "user_word_favorites", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_user_word_progress_tenant_id_user_id_next_review_at_status_~", - table: "user_word_progress", - columns: new[] { "tenant_id", "user_id", "next_review_at", "status", "due_level" }); - - migrationBuilder.CreateIndex( - name: "ix_user_word_progress_tenant_id_user_id_word_id", - table: "user_word_progress", - columns: new[] { "tenant_id", "user_id", "word_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_user_word_progress_tenant_id_word_id", - table: "user_word_progress", - columns: new[] { "tenant_id", "word_id" }); - - migrationBuilder.CreateIndex( - name: "ix_user_word_progress_user_id", - table: "user_word_progress", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_vocabulary_units_tenant_id_content_node_id", - table: "vocabulary_units", - columns: new[] { "tenant_id", "content_node_id" }); - - migrationBuilder.CreateIndex( - name: "ix_vocabulary_units_tenant_id_entry_id_content_node_id_region_~", - table: "vocabulary_units", - columns: new[] { "tenant_id", "entry_id", "content_node_id", "region_id", "is_active", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_vocabulary_units_tenant_id_legacy_id", - table: "vocabulary_units", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_vocabulary_units_tenant_id_region_id", - table: "vocabulary_units", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_vocabulary_words_tenant_id_content_node_id", - table: "vocabulary_words", - columns: new[] { "tenant_id", "content_node_id" }); - - migrationBuilder.CreateIndex( - name: "ix_vocabulary_words_tenant_id_entry_id_content_node_id_unit_id~", - table: "vocabulary_words", - columns: new[] { "tenant_id", "entry_id", "content_node_id", "unit_id", "is_active", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_vocabulary_words_tenant_id_legacy_id", - table: "vocabulary_words", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_vocabulary_words_tenant_id_unit_id_is_active_sort_order_cre~", - table: "vocabulary_words", - columns: new[] { "tenant_id", "unit_id", "is_active", "sort_order", "created_at" }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "handbook_entries"); - - migrationBuilder.DropTable( - name: "question_type_groups"); - - migrationBuilder.DropTable( - name: "subject_shares"); - - migrationBuilder.DropTable( - name: "user_word_favorites"); - - migrationBuilder.DropTable( - name: "user_word_progress"); - - migrationBuilder.DropTable( - name: "handbook_chapters"); - - migrationBuilder.DropTable( - name: "vocabulary_words"); - - migrationBuilder.DropTable( - name: "handbook_subjects"); - - migrationBuilder.DropTable( - name: "vocabulary_units"); - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725211732_AddContentAssetsAndImportPersistence.Designer.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725211732_AddContentAssetsAndImportPersistence.Designer.cs deleted file mode 100644 index fc23dc3..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725211732_AddContentAssetsAndImportPersistence.Designer.cs +++ /dev/null @@ -1,5673 +0,0 @@ -// -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("20260725211732_AddContentAssetsAndImportPersistence")] - partial class AddContentAssetsAndImportPersistence - { - /// - 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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_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_handbook_chapters"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_chapters_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_chapters_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_subject_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_chapters_tenant_id_entry_id_content_node_id_subjec~"); - - b.ToTable("handbook_chapters", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ChapterId") - .HasColumnType("uuid") - .HasColumnName("chapter_id"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Summary") - .HasColumnType("text") - .HasColumnName("summary"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_handbook_entries"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_entries_tenant_id_id"); - - b.HasIndex("TenantId", "ChapterId") - .HasDatabaseName("ix_handbook_entries_tenant_id_chapter_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_entries_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_entries_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "ChapterId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_entries_tenant_id_entry_id_content_node_id_chapter~"); - - b.ToTable("handbook_entries", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", 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("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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - 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_handbook_subjects"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_subjects_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_subjects_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "MajorId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_major_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_school_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_subjects_tenant_id_entry_id_content_node_id_region~"); - - b.ToTable("handbook_subjects", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("CdnUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cdn_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FileName") - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("file_name"); - - 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("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.HasKey("Id") - .HasName("pk_images"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_images_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_images_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "Category", "IsPublic") - .HasDatabaseName("ix_images_tenant_id_category_is_public"); - - b.ToTable("images", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssemblyType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assembly_type"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_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("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PassScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("pass_score"); - - b.Property("QuestionLimit") - .HasColumnType("integer") - .HasColumnName("question_limit"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Rules") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("rules") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Sections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sections") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_practice_blueprints"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_blueprints_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_practice_blueprints_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_practice_blueprints_updated_by"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_collection_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_practice_blueprints_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_region_id"); - - b.HasIndex("TenantId", "NodeId", "CollectionId", "Mode", "Status", "SortOrder") - .HasDatabaseName("ix_practice_blueprints_tenant_id_node_id_collection_id_mode_st~"); - - b.ToTable("practice_blueprints", null, t => - { - t.HasCheckConstraint("ck_practice_blueprints_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_practice_blueprints_question_limit", "question_limit is null or question_limit > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - b.Property("CollectionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("collection_type"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Filters") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("filters") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_question_collections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collections_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_collections_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_question_collections_updated_by"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_question_collections_tenant_id_category_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_question_collections_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_collections_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_question_collections_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_collections_tenant_id_region_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_question_collections_tenant_id_subject_id"); - - b.HasIndex("TenantId", "NodeId", "Status", "SortOrder") - .HasDatabaseName("ix_question_collections_tenant_id_node_id_status_sort_order"); - - b.ToTable("question_collections", null, t => - { - t.HasCheckConstraint("ck_question_collections_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_question_collections_question_count", "question_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Required") - .HasColumnType("boolean") - .HasColumnName("required"); - - b.Property("Score") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - 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_question_collection_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collection_items_tenant_id_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_question_collection_items_tenant_id_question_id"); - - b.HasIndex("TenantId", "CollectionId", "QuestionId") - .IsUnique() - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_question_~"); - - b.HasIndex("TenantId", "CollectionId", "SectionKey", "SortOrder") - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_section_k~"); - - b.ToTable("question_collection_items", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", 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("DisplayName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Types") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("types") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_question_type_groups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_type_groups_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_type_groups_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_question_type_groups_tenant_id_subject_id_is_active_sort_or~"); - - b.ToTable("question_type_groups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", 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("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("LegacyVideoId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_video_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_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("VideoId") - .HasColumnType("uuid") - .HasColumnName("video_id"); - - b.Property("VideoType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("video_type"); - - b.HasKey("Id") - .HasName("pk_question_videos"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_videos_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "VideoId") - .HasDatabaseName("ix_question_videos_tenant_id_video_id"); - - b.HasIndex("TenantId", "QuestionId", "VideoId", "VideoType") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_question_id_video_id_video_type"); - - b.ToTable("question_videos", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("SourceSubjectId") - .HasColumnType("uuid") - .HasColumnName("source_subject_id"); - - b.Property("TargetSubjectId") - .HasColumnType("uuid") - .HasColumnName("target_subject_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Id") - .HasColumnType("uuid") - .HasColumnName("id"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacySourceSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_source_subject_id"); - - b.Property("LegacyTargetSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_target_subject_id"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at"); - - b.HasKey("TenantId", "SourceSubjectId", "TargetSubjectId") - .HasName("pk_subject_shares"); - - b.HasIndex("TenantId", "TargetSubjectId") - .HasDatabaseName("ix_subject_shares_tenant_id_target_subject_id"); - - b.ToTable("subject_shares", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", 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("FavoritedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("favorited_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Note") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.HasKey("Id") - .HasName("pk_user_word_favorites"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_favorites_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_favorites_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_favorites_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_favorites_tenant_id_user_id_word_id"); - - b.ToTable("user_word_favorites", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CorrectStreak") - .HasColumnType("integer") - .HasColumnName("correct_streak"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DueLevel") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("due_level"); - - b.Property("EaseFactor") - .ValueGeneratedOnAdd() - .HasPrecision(4, 2) - .HasColumnType("numeric(4,2)") - .HasDefaultValue(2.50m) - .HasColumnName("ease_factor"); - - b.Property("LastResult") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("last_result"); - - b.Property("LastReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_review_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NextReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_review_at"); - - b.Property("ReviewCount") - .HasColumnType("integer") - .HasColumnName("review_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_user_word_progress"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_progress_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_progress_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_progress_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_word_id"); - - b.HasIndex("TenantId", "UserId", "NextReviewAt", "Status", "DueLevel") - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_next_review_at_status_~"); - - b.ToTable("user_word_progress", null, t => - { - t.HasCheckConstraint("ck_user_word_progress_correct_streak", "correct_streak >= 0"); - - t.HasCheckConstraint("ck_user_word_progress_ease_factor", "ease_factor >= 1.30 and ease_factor <= 3.00"); - - t.HasCheckConstraint("ck_user_word_progress_review_count", "review_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("IsGeneral") - .HasColumnType("boolean") - .HasColumnName("is_general"); - - b.Property("KnowledgeTags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("knowledge_tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ThumbnailUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("thumbnail_url"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VideoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("video_url"); - - b.HasKey("Id") - .HasName("pk_video_explanations"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_video_explanations_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_video_explanations_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SourceHash") - .HasDatabaseName("ix_video_explanations_tenant_id_source_hash") - .HasFilter("source_hash is not null"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_video_explanations_tenant_id_subject_id_is_active_sort_order"); - - b.ToTable("video_explanations", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WordCount") - .HasColumnType("integer") - .HasColumnName("word_count"); - - b.HasKey("Id") - .HasName("pk_vocabulary_units"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_units_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_units_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_region_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_units_tenant_id_entry_id_content_node_id_region_~"); - - b.ToTable("vocabulary_units", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Example") - .HasColumnType("text") - .HasColumnName("example"); - - b.Property("ExampleTranslation") - .HasColumnType("text") - .HasColumnName("example_translation"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Meaning") - .HasColumnType("text") - .HasColumnName("meaning"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phonetic") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("phonetic"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitId") - .HasColumnType("uuid") - .HasColumnName("unit_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Word") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("word"); - - b.HasKey("Id") - .HasName("pk_vocabulary_words"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_words_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_words_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_words_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UnitId", "IsActive", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_vocabulary_words_tenant_id_unit_id_is_active_sort_order_cre~"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "UnitId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_words_tenant_id_entry_id_content_node_id_unit_id~"); - - b.ToTable("vocabulary_words", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", 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("LastCheckInDate") - .HasColumnType("date") - .HasColumnName("last_check_in_date"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("MasteredWordsCount") - .HasColumnType("integer") - .HasColumnName("mastered_words_count"); - - b.Property("ModuleSelections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_selections") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Progress") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("progress") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionsAnsweredToday") - .HasColumnType("integer") - .HasColumnName("questions_answered_today"); - - b.Property("RecentActivities") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("recent_activities") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SelectedMajorId") - .HasColumnType("uuid") - .HasColumnName("selected_major_id"); - - b.Property("SelectedSchoolId") - .HasColumnType("uuid") - .HasColumnName("selected_school_id"); - - b.Property("Stats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("stats") - .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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_student_profiles"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_student_profiles_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_student_profiles_user_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_student_profiles_tenant_id_region_id"); - - b.HasIndex("TenantId", "SelectedMajorId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_major_id"); - - b.HasIndex("TenantId", "SelectedSchoolId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_school_id"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_student_profiles_tenant_id_user_id"); - - b.ToTable("student_profiles", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AvatarUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("avatar_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("LastSeenAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_seen_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPasswordHash") - .HasMaxLength(512) - .HasColumnType("character varying(512)") - .HasColumnName("legacy_password_hash"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PasswordMigrationRequired") - .HasColumnType("boolean") - .HasColumnName("password_migration_required"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("PrimaryRole") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("primary_role"); - - b.Property("RawProfile") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_profile") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Score") - .HasColumnType("integer") - .HasColumnName("score"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Username") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("username"); - - b.HasKey("Id") - .HasName("pk_users"); - - b.HasIndex("Email") - .IsUnique() - .HasDatabaseName("ix_users_email"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_users_legacy_id"); - - b.HasIndex("Phone") - .IsUnique() - .HasDatabaseName("ix_users_phone"); - - b.HasIndex("Username") - .IsUnique() - .HasDatabaseName("ix_users_username"); - - b.ToTable("users", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", 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("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("OpenId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("open_id"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderSubject") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("provider_subject"); - - b.Property("SecretPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("secret_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UnionId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("union_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_identities"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_identities_user_id"); - - b.HasIndex("Provider", "ProviderSubject") - .IsUnique() - .HasDatabaseName("ix_user_identities_provider_provider_subject"); - - b.ToTable("user_identities", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("AnsweredAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("answered_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IsCorrect") - .HasColumnType("boolean") - .HasColumnName("is_correct"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("QuestionVersionId") - .HasColumnType("uuid") - .HasColumnName("question_version_id"); - - b.Property("SelectedOptions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("selected_options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_answer_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_answer_records_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_answer_records_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_answer_records_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id"); - - b.HasIndex("TenantId", "QuestionId", "QuestionVersionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id_question_version_id"); - - b.HasIndex("TenantId", "UserId", "PracticeSessionId") - .HasDatabaseName("ix_answer_records_tenant_id_user_id_practice_session_id"); - - b.ToTable("answer_records", null, t => - { - t.HasCheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_favorite_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_favorite_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_favorite_questions_tenant_id_question_id"); - - b.ToTable("favorite_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("ContentNodeId") - .HasColumnType("uuid") - .HasColumnName("content_node_id"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("FinishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("finished_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at") - .HasDefaultValueSql("now()"); - - b.Property("TargetId") - .HasColumnType("uuid") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_sessions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "UserId", "Id") - .HasName("ak_practice_sessions_tenant_id_user_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_sessions_user_id"); - - b.HasIndex("TenantId", "BlueprintId") - .HasDatabaseName("ix_practice_sessions_tenant_id_blueprint_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_sessions_tenant_id_collection_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_practice_sessions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_sessions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "UserId", "StartedAt") - .HasDatabaseName("ix_practice_sessions_tenant_id_user_id_started_at"); - - b.ToTable("practice_sessions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", 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("LastAccessAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_access_at"); - - b.Property("LastPracticeAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_practice_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("practice_type"); - - b.Property("Progress") - .HasColumnType("integer") - .HasColumnName("progress"); - - b.Property("TargetLegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("target_legacy_id"); - - b.Property("TargetName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("target_name"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_recent_practices"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_recent_practices_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_recent_practices_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_recent_practices_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "LastAccessAt") - .HasDatabaseName("ix_recent_practices_tenant_id_user_id_last_access_at"); - - b.ToTable("recent_practices", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("LastWrongAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("last_wrong_at") - .HasDefaultValueSql("now()"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("WrongCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(1) - .HasColumnName("wrong_count"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_wrong_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_wrong_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_wrong_questions_tenant_id_question_id"); - - b.ToTable("wrong_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - 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("CurrentVersionId") - .HasColumnType("uuid") - .HasColumnName("current_version_id"); - - b.Property("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExamMarkers") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("exam_markers") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("HasVideoExplanation") - .HasColumnType("boolean") - .HasColumnName("has_video_explanation"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyNodeId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_node_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("MediaUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("media_url"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PrimaryCollectionId") - .HasColumnType("uuid") - .HasColumnName("primary_collection_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Type") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("type"); - - b.Property("TypeLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("type_label"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_questions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_questions_tenant_id_id"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_questions_tenant_id_category_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_questions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_questions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_questions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "NodeId") - .HasDatabaseName("ix_questions_tenant_id_node_id"); - - b.HasIndex("TenantId", "PrimaryCollectionId") - .HasDatabaseName("ix_questions_tenant_id_primary_collection_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_questions_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_questions_tenant_id_subject_id"); - - b.HasIndex("TenantId", "Id", "CurrentVersionId") - .HasDatabaseName("ix_questions_tenant_id_id_current_version_id"); - - b.ToTable("questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SourceScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_scope"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_banks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_banks_tenant_id_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_banks_tenant_id_region_id"); - - b.ToTable("question_banks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("CodeLang") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("code_lang"); - - b.Property("CodeTemplate") - .HasColumnType("text") - .HasColumnName("code_template"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CorrectOptionIndex") - .HasColumnType("integer") - .HasColumnName("correct_option_index"); - - b.Property("CorrectOptionIndices") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("correct_option_indices") - .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("Explanation") - .HasColumnType("text") - .HasColumnName("explanation"); - - b.Property("Options") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubQuestions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sub_questions") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("VersionNo") - .HasColumnType("integer") - .HasColumnName("version_no"); - - b.HasKey("Id") - .HasName("pk_question_versions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_versions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "QuestionId", "Id") - .HasName("ak_question_versions_tenant_id_question_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_versions_created_by"); - - b.HasIndex("QuestionId", "VersionNo") - .IsUnique() - .HasDatabaseName("ix_question_versions_question_id_version_no"); - - b.ToTable("question_versions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BillingStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("billing_status"); - - 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("LegalName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("legal_name"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OwnerUserId") - .HasColumnType("uuid") - .HasColumnName("owner_user_id"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("slug"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenants"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenants_legacy_id"); - - b.HasIndex("OwnerUserId") - .HasDatabaseName("ix_tenants_owner_user_id"); - - b.HasIndex("Slug") - .IsUnique() - .HasDatabaseName("ix_tenants_slug"); - - b.ToTable("tenants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("BrandName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("brand_name"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FaviconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("favicon_url"); - - b.Property("LogoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("logo_url"); - - b.Property("OrganizationName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("organization_name"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ServiceAccountName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("service_account_name"); - - b.Property("ServiceWechat") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("service_wechat"); - - b.Property("ShortName") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("short_name"); - - b.Property("Slogan") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("slogan"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_branding"); - - b.ToTable("tenant_branding", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", 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("DomainType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("domain_type"); - - b.Property("Host") - .IsRequired() - .HasMaxLength(253) - .HasColumnType("citext") - .HasColumnName("host"); - - b.Property("IsPrimary") - .HasColumnType("boolean") - .HasColumnName("is_primary"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VerificationToken") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("verification_token"); - - b.Property("VerifiedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("verified_at"); - - b.HasKey("Id") - .HasName("pk_tenant_domains"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_domains_tenant_id_id"); - - b.HasIndex("Host") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_host"); - - b.HasIndex("TenantId", "IsPrimary") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_tenant_id_is_primary") - .HasFilter("is_primary"); - - b.ToTable("tenant_domains", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", 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("LegacyRole") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("legacy_role"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Role") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("role"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_memberships"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_memberships_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_memberships_user_id"); - - b.HasIndex("TenantId", "UserId", "Role") - .IsUnique() - .HasDatabaseName("ix_tenant_memberships_tenant_id_user_id_role"); - - b.ToTable("tenant_memberships", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("AdminFeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("admin_feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PublicConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_settings"); - - b.ToTable("tenant_settings", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Category", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_categories_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Major", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_majors_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.ModuleNode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_module_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_module_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Region", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_regions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.RegionModule", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_region_modules_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_region_modules_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.School", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_schools_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Subject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.AppAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_app_assets_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAsset", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_assets_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_updated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("VerifiedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_verified_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentEntry", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_entries_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportIssue", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportItem", null) - .WithMany() - .HasForeignKey("TenantId", "ItemId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_import_issues_content_import_items_tenant_id_item_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportJob", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_import_jobs_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_jobs_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "TargetCategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_categories_tenant_id_target_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "TargetContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_content_nodes_tenant_id_target_content_~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "TargetQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_question_banks_tenant_id_target_questio~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "TargetRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_regions_tenant_id_target_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentNode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_nodes_content_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookChapter", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_chapters_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.HandbookSubject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_chapters_handbook_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.HandbookChapter", null) - .WithMany() - .HasForeignKey("TenantId", "ChapterId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_entries_handbook_chapters_tenant_id_chapter_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_images_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_blueprints_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_question_collections_tenant_id_collecti~"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_question_banks_tenant_id_question_bank~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_question_collections_tenant_id_co~"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_type_groups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_type_groups_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_videos_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.Content.VideoExplanation", null) - .WithMany() - .HasForeignKey("TenantId", "VideoId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_video_explanations_tenant_id_video_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SourceSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_source_subject_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_video_explanations_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_video_explanations_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_units_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_words_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyUnit", null) - .WithMany() - .HasForeignKey("TenantId", "UnitId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_vocabulary_units_tenant_id_unit_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedMajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_majors_tenant_id_selected_major_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedSchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_schools_tenant_id_selected_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_identities_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId", "QuestionVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_question_versions_tenant_id_question_id_ques~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "UserId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "UserId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_practice_sessions_tenant_id_user_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_question_collections_tenant_id_collection~"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_recent_practices_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_recent_practices_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "PrimaryCollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_collections_tenant_id_primary_collection~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_banks_tenant_id_question_bank_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_subjects_tenant_id_subject_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "Id", "CurrentVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_versions_tenant_id_id_current_version_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_banks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_banks_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_versions_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_versions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("OwnerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenants_users_owner_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantBranding", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_branding_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_domains_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantSettings", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_settings_tenants_tenant_id"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725211732_AddContentAssetsAndImportPersistence.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725211732_AddContentAssetsAndImportPersistence.cs deleted file mode 100644 index b263511..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725211732_AddContentAssetsAndImportPersistence.cs +++ /dev/null @@ -1,630 +0,0 @@ -using System; -using System.Text.Json; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Tiku.Infrastructure.Persistence.Migrations -{ - /// - public partial class AddContentAssetsAndImportPersistence : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "app_assets", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - asset_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - file_name = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_app_assets", x => x.id); - table.UniqueConstraint("ak_app_assets_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_app_assets_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "content_assets", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - subject_id = table.Column(type: "uuid", nullable: true), - category_id = table.Column(type: "uuid", nullable: true), - content_node_id = table.Column(type: "uuid", nullable: true), - created_by = table.Column(type: "uuid", nullable: true), - updated_by = table.Column(type: "uuid", nullable: true), - verified_by = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - asset_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - title = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - category = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - description = table.Column(type: "text", nullable: true), - file_name = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - cdn_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - is_public = table.Column(type: "boolean", nullable: false), - asset_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - storage_provider = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - bucket = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - object_key = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - mime_type = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - file_size_bytes = table.Column(type: "bigint", nullable: true), - checksum_sha256 = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - visibility = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - preview_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - sort_order = table.Column(type: "integer", nullable: false), - access_rules = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - source = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - download_count = table.Column(type: "integer", nullable: false), - upload_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - verified_at = table.Column(type: "timestamp with time zone", nullable: true), - verified_size_bytes = table.Column(type: "bigint", nullable: true), - verified_checksum_sha256 = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - verification_details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - preview_object_key = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - preview_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - security_flags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_content_assets", x => x.id); - table.UniqueConstraint("ak_content_assets_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_content_assets_download_count", "download_count >= 0"); - table.CheckConstraint("ck_content_assets_file_size", "file_size_bytes is null or file_size_bytes >= 0"); - table.CheckConstraint("ck_content_assets_verified_checksum", "verified_checksum_sha256 is null or verified_checksum_sha256 ~ '^[a-f0-9]{64}$'"); - table.CheckConstraint("ck_content_assets_verified_size", "verified_size_bytes is null or verified_size_bytes >= 0"); - table.ForeignKey( - name: "fk_content_assets_categories_tenant_id_category_id", - columns: x => new { x.tenant_id, x.category_id }, - principalTable: "categories", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_content_assets_content_nodes_tenant_id_content_node_id", - columns: x => new { x.tenant_id, x.content_node_id }, - principalTable: "content_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_content_assets_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_content_assets_subjects_tenant_id_subject_id", - columns: x => new { x.tenant_id, x.subject_id }, - principalTable: "subjects", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_content_assets_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_content_assets_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_content_assets_users_updated_by", - column: x => x.updated_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_content_assets_users_verified_by", - column: x => x.verified_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "content_import_jobs", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - created_by = table.Column(type: "uuid", nullable: true), - target_region_id = table.Column(type: "uuid", nullable: true), - target_subject_id = table.Column(type: "uuid", nullable: true), - target_category_id = table.Column(type: "uuid", nullable: true), - target_content_node_id = table.Column(type: "uuid", nullable: true), - target_question_bank_id = table.Column(type: "uuid", nullable: true), - import_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - source_format = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - source_name = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), - dry_run = table.Column(type: "boolean", nullable: false), - total_count = table.Column(type: "integer", nullable: false), - valid_count = table.Column(type: "integer", nullable: false), - error_count = table.Column(type: "integer", nullable: false), - warning_count = table.Column(type: "integer", nullable: false), - inserted_count = table.Column(type: "integer", nullable: false), - updated_count = table.Column(type: "integer", nullable: false), - skipped_count = table.Column(type: "integer", nullable: false), - summary = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - raw_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - normalized_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - error_message = table.Column(type: "text", nullable: true), - started_at = table.Column(type: "timestamp with time zone", nullable: true), - finished_at = table.Column(type: "timestamp with time zone", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_content_import_jobs", x => x.id); - table.UniqueConstraint("ak_content_import_jobs_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("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"); - table.ForeignKey( - name: "fk_content_import_jobs_categories_tenant_id_target_category_id", - columns: x => new { x.tenant_id, x.target_category_id }, - principalTable: "categories", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_content_import_jobs_content_nodes_tenant_id_target_content_~", - columns: x => new { x.tenant_id, x.target_content_node_id }, - principalTable: "content_nodes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_content_import_jobs_question_banks_tenant_id_target_questio~", - columns: x => new { x.tenant_id, x.target_question_bank_id }, - principalTable: "question_banks", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_content_import_jobs_regions_tenant_id_target_region_id", - columns: x => new { x.tenant_id, x.target_region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_content_import_jobs_subjects_tenant_id_target_subject_id", - columns: x => new { x.tenant_id, x.target_subject_id }, - principalTable: "subjects", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_content_import_jobs_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_content_import_jobs_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "images", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - title = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - category = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - file_name = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - is_public = table.Column(type: "boolean", nullable: false), - cdn_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_images", x => x.id); - table.UniqueConstraint("ak_images_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_images_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "video_explanations", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - subject_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_subject_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - title = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - description = table.Column(type: "text", nullable: true), - video_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - thumbnail_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - duration_seconds = table.Column(type: "integer", nullable: true), - knowledge_tags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - is_general = table.Column(type: "boolean", nullable: false), - difficulty = table.Column(type: "integer", nullable: true), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_video_explanations", x => x.id); - table.UniqueConstraint("ak_video_explanations_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_video_explanations_subjects_tenant_id_subject_id", - columns: x => new { x.tenant_id, x.subject_id }, - principalTable: "subjects", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_video_explanations_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "content_import_items", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - job_id = table.Column(type: "uuid", nullable: false), - row_no = table.Column(type: "integer", nullable: false), - external_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - target_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - target_id = table.Column(type: "uuid", nullable: true), - source_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - normalized_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - content_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), - issues_count = table.Column(type: "integer", nullable: false), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_content_import_items", x => x.id); - table.UniqueConstraint("ak_content_import_items_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_content_import_items_issues_count", "issues_count >= 0"); - table.CheckConstraint("ck_content_import_items_row_no", "row_no >= 0"); - table.ForeignKey( - name: "fk_content_import_items_content_import_jobs_tenant_id_job_id", - columns: x => new { x.tenant_id, x.job_id }, - principalTable: "content_import_jobs", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_content_import_items_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "question_videos", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - question_id = table.Column(type: "uuid", nullable: true), - video_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_question_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_video_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - video_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - sort_order = table.Column(type: "integer", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_question_videos", x => x.id); - table.UniqueConstraint("ak_question_videos_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_question_videos_questions_tenant_id_question_id", - columns: x => new { x.tenant_id, x.question_id }, - principalTable: "questions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_question_videos_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_question_videos_video_explanations_tenant_id_video_id", - columns: x => new { x.tenant_id, x.video_id }, - principalTable: "video_explanations", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "content_import_issues", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - job_id = table.Column(type: "uuid", nullable: false), - item_id = table.Column(type: "uuid", nullable: true), - row_no = table.Column(type: "integer", nullable: true), - severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - field_path = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - message = table.Column(type: "character varying(2000)", maxLength: 2000, nullable: false), - details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_content_import_issues", x => x.id); - table.UniqueConstraint("ak_content_import_issues_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_content_import_issues_content_import_items_tenant_id_item_id", - columns: x => new { x.tenant_id, x.item_id }, - principalTable: "content_import_items", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_content_import_issues_content_import_jobs_tenant_id_job_id", - columns: x => new { x.tenant_id, x.job_id }, - principalTable: "content_import_jobs", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_content_import_issues_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "ix_app_assets_tenant_id_asset_key", - table: "app_assets", - columns: new[] { "tenant_id", "asset_key" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_app_assets_tenant_id_legacy_id", - table: "app_assets", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_created_by", - table: "content_assets", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_tenant_id_category_id", - table: "content_assets", - columns: new[] { "tenant_id", "category_id" }); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_tenant_id_checksum_sha256", - table: "content_assets", - columns: new[] { "tenant_id", "checksum_sha256" }, - filter: "checksum_sha256 is not null"); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_tenant_id_content_node_id", - table: "content_assets", - columns: new[] { "tenant_id", "content_node_id" }); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_tenant_id_legacy_id", - table: "content_assets", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_tenant_id_preview_status", - table: "content_assets", - columns: new[] { "tenant_id", "preview_status" }, - filter: "preview_status <> 'none'"); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_tenant_id_region_id", - table: "content_assets", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_tenant_id_status_visibility_asset_type_regio~", - table: "content_assets", - columns: new[] { "tenant_id", "status", "visibility", "asset_type", "region_id", "subject_id", "category_id", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_tenant_id_storage_provider_bucket_object_key", - table: "content_assets", - columns: new[] { "tenant_id", "storage_provider", "bucket", "object_key" }); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_tenant_id_subject_id", - table: "content_assets", - columns: new[] { "tenant_id", "subject_id" }); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_tenant_id_upload_status_status_updated_at", - table: "content_assets", - columns: new[] { "tenant_id", "upload_status", "status", "updated_at" }); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_updated_by", - table: "content_assets", - column: "updated_by"); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_verified_by", - table: "content_assets", - column: "verified_by"); - - migrationBuilder.CreateIndex( - name: "ix_content_import_issues_tenant_id_item_id", - table: "content_import_issues", - columns: new[] { "tenant_id", "item_id" }); - - migrationBuilder.CreateIndex( - name: "ix_content_import_issues_tenant_id_job_id_severity_row_no", - table: "content_import_issues", - columns: new[] { "tenant_id", "job_id", "severity", "row_no" }); - - migrationBuilder.CreateIndex( - name: "ix_content_import_items_job_id_row_no", - table: "content_import_items", - columns: new[] { "job_id", "row_no" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_content_import_items_tenant_id_job_id_status_row_no", - table: "content_import_items", - columns: new[] { "tenant_id", "job_id", "status", "row_no" }); - - migrationBuilder.CreateIndex( - name: "ix_content_import_jobs_created_by", - table: "content_import_jobs", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_content_import_jobs_tenant_id_import_type_status_created_at", - table: "content_import_jobs", - columns: new[] { "tenant_id", "import_type", "status", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_content_import_jobs_tenant_id_target_category_id", - table: "content_import_jobs", - columns: new[] { "tenant_id", "target_category_id" }); - - migrationBuilder.CreateIndex( - name: "ix_content_import_jobs_tenant_id_target_content_node_id", - table: "content_import_jobs", - columns: new[] { "tenant_id", "target_content_node_id" }); - - migrationBuilder.CreateIndex( - name: "ix_content_import_jobs_tenant_id_target_question_bank_id", - table: "content_import_jobs", - columns: new[] { "tenant_id", "target_question_bank_id" }); - - migrationBuilder.CreateIndex( - name: "ix_content_import_jobs_tenant_id_target_region_id", - table: "content_import_jobs", - columns: new[] { "tenant_id", "target_region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_content_import_jobs_tenant_id_target_subject_id", - table: "content_import_jobs", - columns: new[] { "tenant_id", "target_subject_id" }); - - migrationBuilder.CreateIndex( - name: "ix_images_tenant_id_category_is_public", - table: "images", - columns: new[] { "tenant_id", "category", "is_public" }); - - migrationBuilder.CreateIndex( - name: "ix_images_tenant_id_legacy_id", - table: "images", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_question_videos_tenant_id_legacy_id", - table: "question_videos", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_question_videos_tenant_id_question_id_video_id_video_type", - table: "question_videos", - columns: new[] { "tenant_id", "question_id", "video_id", "video_type" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_question_videos_tenant_id_video_id", - table: "question_videos", - columns: new[] { "tenant_id", "video_id" }); - - migrationBuilder.CreateIndex( - name: "ix_video_explanations_tenant_id_legacy_id", - table: "video_explanations", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_video_explanations_tenant_id_source_hash", - table: "video_explanations", - columns: new[] { "tenant_id", "source_hash" }, - filter: "source_hash is not null"); - - migrationBuilder.CreateIndex( - name: "ix_video_explanations_tenant_id_subject_id_is_active_sort_order", - table: "video_explanations", - columns: new[] { "tenant_id", "subject_id", "is_active", "sort_order" }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "app_assets"); - - migrationBuilder.DropTable( - name: "content_assets"); - - migrationBuilder.DropTable( - name: "content_import_issues"); - - migrationBuilder.DropTable( - name: "images"); - - migrationBuilder.DropTable( - name: "question_videos"); - - migrationBuilder.DropTable( - name: "content_import_items"); - - migrationBuilder.DropTable( - name: "video_explanations"); - - migrationBuilder.DropTable( - name: "content_import_jobs"); - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725212328_AddLearningReportsAndPracticeAccessPersistence.Designer.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725212328_AddLearningReportsAndPracticeAccessPersistence.Designer.cs deleted file mode 100644 index 6afa093..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725212328_AddLearningReportsAndPracticeAccessPersistence.Designer.cs +++ /dev/null @@ -1,6939 +0,0 @@ -// -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("20260725212328_AddLearningReportsAndPracticeAccessPersistence")] - partial class AddLearningReportsAndPracticeAccessPersistence - { - /// - 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_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_handbook_chapters"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_chapters_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_chapters_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_subject_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_chapters_tenant_id_entry_id_content_node_id_subjec~"); - - b.ToTable("handbook_chapters", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ChapterId") - .HasColumnType("uuid") - .HasColumnName("chapter_id"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Summary") - .HasColumnType("text") - .HasColumnName("summary"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_handbook_entries"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_entries_tenant_id_id"); - - b.HasIndex("TenantId", "ChapterId") - .HasDatabaseName("ix_handbook_entries_tenant_id_chapter_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_entries_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_entries_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "ChapterId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_entries_tenant_id_entry_id_content_node_id_chapter~"); - - b.ToTable("handbook_entries", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", 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("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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - 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_handbook_subjects"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_subjects_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_subjects_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "MajorId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_major_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_school_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_subjects_tenant_id_entry_id_content_node_id_region~"); - - b.ToTable("handbook_subjects", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("CdnUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cdn_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FileName") - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("file_name"); - - 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("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.HasKey("Id") - .HasName("pk_images"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_images_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_images_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "Category", "IsPublic") - .HasDatabaseName("ix_images_tenant_id_category_is_public"); - - b.ToTable("images", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", 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("AssemblyType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assembly_type"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_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("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PassScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("pass_score"); - - b.Property("QuestionLimit") - .HasColumnType("integer") - .HasColumnName("question_limit"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Rules") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("rules") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Sections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sections") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_practice_blueprints"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_blueprints_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_practice_blueprints_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_practice_blueprints_updated_by"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_collection_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_practice_blueprints_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_region_id"); - - b.HasIndex("TenantId", "NodeId", "CollectionId", "Mode", "Status", "SortOrder") - .HasDatabaseName("ix_practice_blueprints_tenant_id_node_id_collection_id_mode_st~"); - - b.ToTable("practice_blueprints", null, t => - { - t.HasCheckConstraint("ck_practice_blueprints_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_practice_blueprints_question_limit", "question_limit is null or question_limit > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", 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("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - b.Property("CollectionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("collection_type"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Filters") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("filters") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_question_collections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collections_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_collections_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_question_collections_updated_by"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_question_collections_tenant_id_category_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_question_collections_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_collections_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_question_collections_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_collections_tenant_id_region_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_question_collections_tenant_id_subject_id"); - - b.HasIndex("TenantId", "NodeId", "Status", "SortOrder") - .HasDatabaseName("ix_question_collections_tenant_id_node_id_status_sort_order"); - - b.ToTable("question_collections", null, t => - { - t.HasCheckConstraint("ck_question_collections_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_question_collections_question_count", "question_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Required") - .HasColumnType("boolean") - .HasColumnName("required"); - - b.Property("Score") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - 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_question_collection_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collection_items_tenant_id_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_question_collection_items_tenant_id_question_id"); - - b.HasIndex("TenantId", "CollectionId", "QuestionId") - .IsUnique() - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_question_~"); - - b.HasIndex("TenantId", "CollectionId", "SectionKey", "SortOrder") - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_section_k~"); - - b.ToTable("question_collection_items", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", 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("DisplayName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Types") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("types") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_question_type_groups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_type_groups_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_type_groups_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_question_type_groups_tenant_id_subject_id_is_active_sort_or~"); - - b.ToTable("question_type_groups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", 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("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("LegacyVideoId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_video_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_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("VideoId") - .HasColumnType("uuid") - .HasColumnName("video_id"); - - b.Property("VideoType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("video_type"); - - b.HasKey("Id") - .HasName("pk_question_videos"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_videos_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "VideoId") - .HasDatabaseName("ix_question_videos_tenant_id_video_id"); - - b.HasIndex("TenantId", "QuestionId", "VideoId", "VideoType") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_question_id_video_id_video_type"); - - b.ToTable("question_videos", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("SourceSubjectId") - .HasColumnType("uuid") - .HasColumnName("source_subject_id"); - - b.Property("TargetSubjectId") - .HasColumnType("uuid") - .HasColumnName("target_subject_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Id") - .HasColumnType("uuid") - .HasColumnName("id"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacySourceSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_source_subject_id"); - - b.Property("LegacyTargetSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_target_subject_id"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at"); - - b.HasKey("TenantId", "SourceSubjectId", "TargetSubjectId") - .HasName("pk_subject_shares"); - - b.HasIndex("TenantId", "TargetSubjectId") - .HasDatabaseName("ix_subject_shares_tenant_id_target_subject_id"); - - b.ToTable("subject_shares", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", 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("FavoritedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("favorited_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Note") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.HasKey("Id") - .HasName("pk_user_word_favorites"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_favorites_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_favorites_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_favorites_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_favorites_tenant_id_user_id_word_id"); - - b.ToTable("user_word_favorites", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CorrectStreak") - .HasColumnType("integer") - .HasColumnName("correct_streak"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DueLevel") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("due_level"); - - b.Property("EaseFactor") - .ValueGeneratedOnAdd() - .HasPrecision(4, 2) - .HasColumnType("numeric(4,2)") - .HasDefaultValue(2.50m) - .HasColumnName("ease_factor"); - - b.Property("LastResult") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("last_result"); - - b.Property("LastReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_review_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NextReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_review_at"); - - b.Property("ReviewCount") - .HasColumnType("integer") - .HasColumnName("review_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_user_word_progress"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_progress_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_progress_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_progress_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_word_id"); - - b.HasIndex("TenantId", "UserId", "NextReviewAt", "Status", "DueLevel") - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_next_review_at_status_~"); - - b.ToTable("user_word_progress", null, t => - { - t.HasCheckConstraint("ck_user_word_progress_correct_streak", "correct_streak >= 0"); - - t.HasCheckConstraint("ck_user_word_progress_ease_factor", "ease_factor >= 1.30 and ease_factor <= 3.00"); - - t.HasCheckConstraint("ck_user_word_progress_review_count", "review_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("IsGeneral") - .HasColumnType("boolean") - .HasColumnName("is_general"); - - b.Property("KnowledgeTags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("knowledge_tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ThumbnailUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("thumbnail_url"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VideoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("video_url"); - - b.HasKey("Id") - .HasName("pk_video_explanations"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_video_explanations_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_video_explanations_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SourceHash") - .HasDatabaseName("ix_video_explanations_tenant_id_source_hash") - .HasFilter("source_hash is not null"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_video_explanations_tenant_id_subject_id_is_active_sort_order"); - - b.ToTable("video_explanations", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WordCount") - .HasColumnType("integer") - .HasColumnName("word_count"); - - b.HasKey("Id") - .HasName("pk_vocabulary_units"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_units_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_units_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_region_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_units_tenant_id_entry_id_content_node_id_region_~"); - - b.ToTable("vocabulary_units", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Example") - .HasColumnType("text") - .HasColumnName("example"); - - b.Property("ExampleTranslation") - .HasColumnType("text") - .HasColumnName("example_translation"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Meaning") - .HasColumnType("text") - .HasColumnName("meaning"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phonetic") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("phonetic"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitId") - .HasColumnType("uuid") - .HasColumnName("unit_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Word") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("word"); - - b.HasKey("Id") - .HasName("pk_vocabulary_words"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_words_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_words_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_words_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UnitId", "IsActive", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_vocabulary_words_tenant_id_unit_id_is_active_sort_order_cre~"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "UnitId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_words_tenant_id_entry_id_content_node_id_unit_id~"); - - b.ToTable("vocabulary_words", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", 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("LastCheckInDate") - .HasColumnType("date") - .HasColumnName("last_check_in_date"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("MasteredWordsCount") - .HasColumnType("integer") - .HasColumnName("mastered_words_count"); - - b.Property("ModuleSelections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_selections") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Progress") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("progress") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionsAnsweredToday") - .HasColumnType("integer") - .HasColumnName("questions_answered_today"); - - b.Property("RecentActivities") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("recent_activities") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SelectedMajorId") - .HasColumnType("uuid") - .HasColumnName("selected_major_id"); - - b.Property("SelectedSchoolId") - .HasColumnType("uuid") - .HasColumnName("selected_school_id"); - - b.Property("Stats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("stats") - .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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_student_profiles"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_student_profiles_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_student_profiles_user_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_student_profiles_tenant_id_region_id"); - - b.HasIndex("TenantId", "SelectedMajorId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_major_id"); - - b.HasIndex("TenantId", "SelectedSchoolId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_school_id"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_student_profiles_tenant_id_user_id"); - - b.ToTable("student_profiles", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AvatarUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("avatar_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("LastSeenAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_seen_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPasswordHash") - .HasMaxLength(512) - .HasColumnType("character varying(512)") - .HasColumnName("legacy_password_hash"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PasswordMigrationRequired") - .HasColumnType("boolean") - .HasColumnName("password_migration_required"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("PrimaryRole") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("primary_role"); - - b.Property("RawProfile") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_profile") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Score") - .HasColumnType("integer") - .HasColumnName("score"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Username") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("username"); - - b.HasKey("Id") - .HasName("pk_users"); - - b.HasIndex("Email") - .IsUnique() - .HasDatabaseName("ix_users_email"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_users_legacy_id"); - - b.HasIndex("Phone") - .IsUnique() - .HasDatabaseName("ix_users_phone"); - - b.HasIndex("Username") - .IsUnique() - .HasDatabaseName("ix_users_username"); - - b.ToTable("users", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", 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("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("OpenId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("open_id"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderSubject") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("provider_subject"); - - b.Property("SecretPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("secret_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UnionId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("union_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_identities"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_identities_user_id"); - - b.HasIndex("Provider", "ProviderSubject") - .IsUnique() - .HasDatabaseName("ix_user_identities_provider_provider_subject"); - - b.ToTable("user_identities", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("AnsweredAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("answered_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IsCorrect") - .HasColumnType("boolean") - .HasColumnName("is_correct"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("QuestionVersionId") - .HasColumnType("uuid") - .HasColumnName("question_version_id"); - - b.Property("SelectedOptions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("selected_options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_answer_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_answer_records_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_answer_records_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_answer_records_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id"); - - b.HasIndex("TenantId", "QuestionId", "QuestionVersionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id_question_version_id"); - - b.HasIndex("TenantId", "UserId", "PracticeSessionId") - .HasDatabaseName("ix_answer_records_tenant_id_user_id_practice_session_id"); - - b.ToTable("answer_records", null, t => - { - t.HasCheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActiveUsers") - .HasColumnType("integer") - .HasColumnName("active_users"); - - 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("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("NewOrders") - .HasColumnType("integer") - .HasColumnName("new_orders"); - - b.Property("NewQuestions") - .HasColumnType("integer") - .HasColumnName("new_questions"); - - b.Property("NewRevenueCents") - .HasColumnType("integer") - .HasColumnName("new_revenue_cents"); - - b.Property("NewUsers") - .HasColumnType("integer") - .HasColumnName("new_users"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_dashboard_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_dashboard_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_stat_date_region_id"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId"), false); - - b.ToTable("dashboard_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", 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("ExamAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("exam_at"); - - b.Property("ExamName") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("exam_name"); - - b.Property("ExamType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("exam_type"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("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_exam_dates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_exam_dates_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_exam_dates_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_exam_dates_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId", "ExamAt") - .HasDatabaseName("ix_exam_dates_tenant_id_school_id_exam_at"); - - b.ToTable("exam_dates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_favorite_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_favorite_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_favorite_questions_tenant_id_question_id"); - - b.ToTable("favorite_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("access_mode"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EntitlementId") - .HasColumnType("uuid") - .HasColumnName("entitlement_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("GrantedCount") - .HasColumnType("integer") - .HasColumnName("granted_count"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("Reason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("reason"); - - b.Property("RequestedCount") - .HasColumnType("integer") - .HasColumnName("requested_count"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_access_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_access_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_access_events_user_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_access_events_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_practice_access_events_tenant_id_user_id_created_at"); - - b.ToTable("practice_access_events", null, t => - { - t.HasCheckConstraint("ck_practice_access_events_consumed_free_quota", "consumed_free_quota >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_granted_count", "granted_count >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_requested_count", "requested_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", 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("FreeLimit") - .HasColumnType("integer") - .HasColumnName("free_limit"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsageDate") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasColumnName("usage_date") - .HasDefaultValueSql("current_date"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_daily_usage"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_daily_usage_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_daily_usage_user_id"); - - b.HasIndex("TenantId", "UserId", "UsageDate") - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date"); - - b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId") - .IsUnique() - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date_scope_typ~"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId"), false); - - b.ToTable("practice_daily_usage", null, t => - { - t.HasCheckConstraint("ck_practice_daily_usage_free_limit", "free_limit >= 0"); - - t.HasCheckConstraint("ck_practice_daily_usage_used_count", "used_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessEntitlementId") - .HasColumnType("uuid") - .HasColumnName("access_entitlement_id"); - - b.Property("AccessMode") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasDefaultValue("free") - .HasColumnName("access_mode"); - - b.Property("AccessSnapshot") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("access_snapshot") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("ContentNodeId") - .HasColumnType("uuid") - .HasColumnName("content_node_id"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("FinishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("finished_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at") - .HasDefaultValueSql("now()"); - - b.Property("TargetId") - .HasColumnType("uuid") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_sessions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "UserId", "Id") - .HasName("ak_practice_sessions_tenant_id_user_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_sessions_user_id"); - - b.HasIndex("TenantId", "BlueprintId") - .HasDatabaseName("ix_practice_sessions_tenant_id_blueprint_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_sessions_tenant_id_collection_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_practice_sessions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_sessions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "UserId", "StartedAt") - .HasDatabaseName("ix_practice_sessions_tenant_id_user_id_started_at"); - - b.ToTable("practice_sessions", null, t => - { - t.HasCheckConstraint("ck_practice_sessions_consumed_free_quota", "consumed_free_quota >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionResults") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_results") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionStats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("section_stats") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at"); - - b.Property("SubmittedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("submitted_at") - .HasDefaultValueSql("now()"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalQuestions") - .HasColumnType("integer") - .HasColumnName("total_questions"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.Property("WrongQuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("wrong_question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.HasKey("Id") - .HasName("pk_practice_session_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_reports_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_session_reports_user_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_session_reports_tenant_id_collection_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .IsUnique() - .HasDatabaseName("ix_practice_session_reports_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "BlueprintId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_blueprint_id_submitted_at") - .HasFilter("blueprint_id is not null"); - - b.HasIndex("TenantId", "UserId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_user_id_submitted_at"); - - b.ToTable("practice_session_reports", null, t => - { - t.HasCheckConstraint("ck_practice_session_reports_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_reports_counts", "total_questions >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_duration", "duration_seconds >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("question_type"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - b.Property("SectionName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("section_name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_practice_session_report_sections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_report_sections_tenant_id_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_practice_session~"); - - b.HasIndex("TenantId", "ReportId", "SectionKey") - .IsUnique() - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sectio~"); - - b.HasIndex("TenantId", "ReportId", "SortOrder") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sort_o~"); - - b.ToTable("practice_session_report_sections", null, t => - { - t.HasCheckConstraint("ck_practice_session_report_sections_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_report_sections_counts", "question_count >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_report_sections_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", 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("LastAccessAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_access_at"); - - b.Property("LastPracticeAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_practice_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("practice_type"); - - b.Property("Progress") - .HasColumnType("integer") - .HasColumnName("progress"); - - b.Property("TargetLegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("target_legacy_id"); - - b.Property("TargetName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("target_name"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_recent_practices"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_recent_practices_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_recent_practices_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_recent_practices_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "LastAccessAt") - .HasDatabaseName("ix_recent_practices_tenant_id_user_id_last_access_at"); - - b.ToTable("recent_practices", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attachments") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("attachments") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("Contact") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("contact"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("HandledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("handled_at"); - - b.Property("HandledBy") - .HasColumnType("uuid") - .HasColumnName("handled_by"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Resolution") - .HasColumnType("text") - .HasColumnName("resolution"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_reports_tenant_id_id"); - - b.HasIndex("HandledBy") - .HasDatabaseName("ix_reports_handled_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_reports_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_reports_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_question_id_created_at") - .HasFilter("question_id is not null"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_status_created_at"); - - b.ToTable("reports", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_report_status_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_report_status_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_report_status_events_actor_user_id"); - - b.HasIndex("TenantId", "ReportId", "CreatedAt") - .HasDatabaseName("ix_report_status_events_tenant_id_report_id_created_at"); - - b.ToTable("report_status_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CodeCount") - .HasColumnType("integer") - .HasColumnName("code_count"); - - b.Property("CodeEstimated") - .HasColumnType("integer") - .HasColumnName("code_estimated"); - - b.Property("CodeUsed") - .HasColumnType("integer") - .HasColumnName("code_used"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EstimatedRevenueCents") - .HasColumnType("integer") - .HasColumnName("estimated_revenue_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("OrderCount") - .HasColumnType("integer") - .HasColumnName("order_count"); - - b.Property("RealRevenueCents") - .HasColumnType("integer") - .HasColumnName("real_revenue_cents"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_revenue_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_revenue_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_stat_date_region_id_sale_type"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType"), false); - - b.ToTable("revenue_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BalanceAfter") - .HasColumnType("integer") - .HasColumnName("balance_after"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("IdempotencyKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("idempotency_key"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Points") - .HasColumnType("integer") - .HasColumnName("points"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_score_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_score_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_score_events_user_id"); - - b.HasIndex("TenantId", "IdempotencyKey") - .IsUnique() - .HasDatabaseName("ix_user_score_events_tenant_id_idempotency_key"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_user_score_events_tenant_id_user_id_created_at"); - - b.ToTable("user_score_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("LastWrongAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("last_wrong_at") - .HasDefaultValueSql("now()"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("WrongCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(1) - .HasColumnName("wrong_count"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_wrong_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_wrong_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_wrong_questions_tenant_id_question_id"); - - b.ToTable("wrong_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - 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("CurrentVersionId") - .HasColumnType("uuid") - .HasColumnName("current_version_id"); - - b.Property("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExamMarkers") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("exam_markers") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("HasVideoExplanation") - .HasColumnType("boolean") - .HasColumnName("has_video_explanation"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyNodeId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_node_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("MediaUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("media_url"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PrimaryCollectionId") - .HasColumnType("uuid") - .HasColumnName("primary_collection_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Type") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("type"); - - b.Property("TypeLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("type_label"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_questions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_questions_tenant_id_id"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_questions_tenant_id_category_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_questions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_questions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_questions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "NodeId") - .HasDatabaseName("ix_questions_tenant_id_node_id"); - - b.HasIndex("TenantId", "PrimaryCollectionId") - .HasDatabaseName("ix_questions_tenant_id_primary_collection_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_questions_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_questions_tenant_id_subject_id"); - - b.HasIndex("TenantId", "Id", "CurrentVersionId") - .HasDatabaseName("ix_questions_tenant_id_id_current_version_id"); - - b.ToTable("questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SourceScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_scope"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_banks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_banks_tenant_id_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_banks_tenant_id_region_id"); - - b.ToTable("question_banks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("CodeLang") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("code_lang"); - - b.Property("CodeTemplate") - .HasColumnType("text") - .HasColumnName("code_template"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CorrectOptionIndex") - .HasColumnType("integer") - .HasColumnName("correct_option_index"); - - b.Property("CorrectOptionIndices") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("correct_option_indices") - .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("Explanation") - .HasColumnType("text") - .HasColumnName("explanation"); - - b.Property("Options") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubQuestions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sub_questions") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("VersionNo") - .HasColumnType("integer") - .HasColumnName("version_no"); - - b.HasKey("Id") - .HasName("pk_question_versions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_versions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "QuestionId", "Id") - .HasName("ak_question_versions_tenant_id_question_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_versions_created_by"); - - b.HasIndex("QuestionId", "VersionNo") - .IsUnique() - .HasDatabaseName("ix_question_versions_question_id_version_no"); - - b.ToTable("question_versions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BillingStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("billing_status"); - - 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("LegalName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("legal_name"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OwnerUserId") - .HasColumnType("uuid") - .HasColumnName("owner_user_id"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("slug"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenants"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenants_legacy_id"); - - b.HasIndex("OwnerUserId") - .HasDatabaseName("ix_tenants_owner_user_id"); - - b.HasIndex("Slug") - .IsUnique() - .HasDatabaseName("ix_tenants_slug"); - - b.ToTable("tenants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("BrandName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("brand_name"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FaviconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("favicon_url"); - - b.Property("LogoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("logo_url"); - - b.Property("OrganizationName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("organization_name"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ServiceAccountName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("service_account_name"); - - b.Property("ServiceWechat") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("service_wechat"); - - b.Property("ShortName") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("short_name"); - - b.Property("Slogan") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("slogan"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_branding"); - - b.ToTable("tenant_branding", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", 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("DomainType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("domain_type"); - - b.Property("Host") - .IsRequired() - .HasMaxLength(253) - .HasColumnType("citext") - .HasColumnName("host"); - - b.Property("IsPrimary") - .HasColumnType("boolean") - .HasColumnName("is_primary"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VerificationToken") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("verification_token"); - - b.Property("VerifiedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("verified_at"); - - b.HasKey("Id") - .HasName("pk_tenant_domains"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_domains_tenant_id_id"); - - b.HasIndex("Host") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_host"); - - b.HasIndex("TenantId", "IsPrimary") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_tenant_id_is_primary") - .HasFilter("is_primary"); - - b.ToTable("tenant_domains", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", 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("LegacyRole") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("legacy_role"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Role") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("role"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_memberships"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_memberships_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_memberships_user_id"); - - b.HasIndex("TenantId", "UserId", "Role") - .IsUnique() - .HasDatabaseName("ix_tenant_memberships_tenant_id_user_id_role"); - - b.ToTable("tenant_memberships", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("AdminFeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("admin_feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PublicConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_settings"); - - b.ToTable("tenant_settings", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Category", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_categories_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Major", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_majors_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.ModuleNode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_module_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_module_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Region", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_regions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.RegionModule", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_region_modules_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_region_modules_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.School", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_schools_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Subject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.AppAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_app_assets_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAsset", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_assets_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_updated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("VerifiedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_verified_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentEntry", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_entries_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportIssue", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportItem", null) - .WithMany() - .HasForeignKey("TenantId", "ItemId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_import_issues_content_import_items_tenant_id_item_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportJob", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_import_jobs_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_jobs_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "TargetCategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_categories_tenant_id_target_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "TargetContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_content_nodes_tenant_id_target_content_~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "TargetQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_question_banks_tenant_id_target_questio~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "TargetRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_regions_tenant_id_target_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentNode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_nodes_content_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookChapter", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_chapters_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.HandbookSubject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_chapters_handbook_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.HandbookChapter", null) - .WithMany() - .HasForeignKey("TenantId", "ChapterId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_entries_handbook_chapters_tenant_id_chapter_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_images_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_blueprints_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_question_collections_tenant_id_collecti~"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_question_banks_tenant_id_question_bank~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_question_collections_tenant_id_co~"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_type_groups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_type_groups_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_videos_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.Content.VideoExplanation", null) - .WithMany() - .HasForeignKey("TenantId", "VideoId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_video_explanations_tenant_id_video_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SourceSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_source_subject_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_video_explanations_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_video_explanations_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_units_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_words_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyUnit", null) - .WithMany() - .HasForeignKey("TenantId", "UnitId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_vocabulary_units_tenant_id_unit_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedMajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_majors_tenant_id_selected_major_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedSchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_schools_tenant_id_selected_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_identities_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId", "QuestionVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_question_versions_tenant_id_question_id_ques~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "UserId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "UserId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_practice_sessions_tenant_id_user_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_dashboard_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_dashboard_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_exam_dates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_access_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_users_user_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_practice_sessions_tenant_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_question_collections_tenant_id_collection~"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_practice_blueprints_tenant_id_blue~"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_question_collections_tenant_id_col~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_practice_sessions_tenant_id_practi~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_sessions_tenant_i~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSessionReport", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_session_reports_t~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_recent_practices_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_recent_practices_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("HandledBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_handled_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_reports_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_report_status_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.Report", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_reports_tenant_id_report_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_revenue_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_revenue_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "PrimaryCollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_collections_tenant_id_primary_collection~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_banks_tenant_id_question_bank_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_subjects_tenant_id_subject_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "Id", "CurrentVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_versions_tenant_id_id_current_version_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_banks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_banks_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_versions_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_versions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("OwnerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenants_users_owner_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantBranding", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_branding_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_domains_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantSettings", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_settings_tenants_tenant_id"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725212328_AddLearningReportsAndPracticeAccessPersistence.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725212328_AddLearningReportsAndPracticeAccessPersistence.cs deleted file mode 100644 index b5e8b67..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725212328_AddLearningReportsAndPracticeAccessPersistence.cs +++ /dev/null @@ -1,764 +0,0 @@ -using System; -using System.Text.Json; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Tiku.Infrastructure.Persistence.Migrations -{ - /// - public partial class AddLearningReportsAndPracticeAccessPersistence : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "access_rules", - table: "question_collections", - type: "jsonb", - nullable: false, - defaultValueSql: "'{}'::jsonb"); - - migrationBuilder.AddColumn( - name: "access_entitlement_id", - table: "practice_sessions", - type: "uuid", - nullable: true); - - migrationBuilder.AddColumn( - name: "access_mode", - table: "practice_sessions", - type: "character varying(32)", - maxLength: 32, - nullable: false, - defaultValue: "free"); - - migrationBuilder.AddColumn( - name: "access_snapshot", - table: "practice_sessions", - type: "jsonb", - nullable: false, - defaultValueSql: "'{}'::jsonb"); - - migrationBuilder.AddColumn( - name: "consumed_free_quota", - table: "practice_sessions", - type: "integer", - nullable: false, - defaultValue: 0); - - migrationBuilder.AddColumn( - name: "access_rules", - table: "practice_blueprints", - type: "jsonb", - nullable: false, - defaultValueSql: "'{}'::jsonb"); - - migrationBuilder.AddColumn( - name: "access_rules", - table: "content_nodes", - type: "jsonb", - nullable: false, - defaultValueSql: "'{}'::jsonb"); - - migrationBuilder.CreateTable( - name: "dashboard_daily_stats", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_region_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - stat_date = table.Column(type: "date", nullable: false), - new_users = table.Column(type: "integer", nullable: false), - new_questions = table.Column(type: "integer", nullable: false), - new_orders = table.Column(type: "integer", nullable: false), - new_revenue_cents = table.Column(type: "integer", nullable: false), - active_users = table.Column(type: "integer", nullable: false), - rebuilt_at = table.Column(type: "timestamp with time zone", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_dashboard_daily_stats", x => x.id); - table.UniqueConstraint("ak_dashboard_daily_stats_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_dashboard_daily_stats_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_dashboard_daily_stats_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "exam_dates", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - school_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - exam_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - exam_at = table.Column(type: "timestamp with time zone", nullable: true), - exam_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - description = table.Column(type: "text", nullable: true), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_exam_dates", x => x.id); - table.UniqueConstraint("ak_exam_dates_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_exam_dates_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_exam_dates_schools_tenant_id_school_id", - columns: x => new { x.tenant_id, x.school_id }, - principalTable: "schools", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_exam_dates_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "practice_access_events", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - user_id = table.Column(type: "uuid", nullable: true), - practice_session_id = table.Column(type: "uuid", nullable: true), - event_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - access_mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - requested_count = table.Column(type: "integer", nullable: false), - granted_count = table.Column(type: "integer", nullable: false), - consumed_free_quota = table.Column(type: "integer", nullable: false), - reason = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - scope_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - scope_id = table.Column(type: "uuid", nullable: true), - entitlement_id = table.Column(type: "uuid", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_practice_access_events", x => x.id); - table.UniqueConstraint("ak_practice_access_events_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_practice_access_events_consumed_free_quota", "consumed_free_quota >= 0"); - table.CheckConstraint("ck_practice_access_events_granted_count", "granted_count >= 0"); - table.CheckConstraint("ck_practice_access_events_requested_count", "requested_count >= 0"); - table.ForeignKey( - name: "fk_practice_access_events_practice_sessions_tenant_id_practice~", - columns: x => new { x.tenant_id, x.practice_session_id }, - principalTable: "practice_sessions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_practice_access_events_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_practice_access_events_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "practice_daily_usage", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: false), - usage_date = table.Column(type: "date", nullable: false, defaultValueSql: "current_date"), - scope_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - scope_id = table.Column(type: "uuid", nullable: true), - free_limit = table.Column(type: "integer", nullable: false), - used_count = table.Column(type: "integer", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_practice_daily_usage", x => x.id); - table.UniqueConstraint("ak_practice_daily_usage_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_practice_daily_usage_free_limit", "free_limit >= 0"); - table.CheckConstraint("ck_practice_daily_usage_used_count", "used_count >= 0"); - table.ForeignKey( - name: "fk_practice_daily_usage_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_practice_daily_usage_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "practice_session_reports", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: false), - practice_session_id = table.Column(type: "uuid", nullable: false), - blueprint_id = table.Column(type: "uuid", nullable: true), - collection_id = table.Column(type: "uuid", nullable: true), - mode = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - total_questions = table.Column(type: "integer", nullable: false), - answered_count = table.Column(type: "integer", nullable: false), - correct_count = table.Column(type: "integer", nullable: false), - wrong_count = table.Column(type: "integer", nullable: false), - unanswered_count = table.Column(type: "integer", nullable: false), - score = table.Column(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false), - total_score = table.Column(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false), - accuracy = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), - duration_seconds = table.Column(type: "integer", nullable: false), - started_at = table.Column(type: "timestamp with time zone", nullable: true), - submitted_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - section_stats = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - question_results = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - wrong_question_ids = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_practice_session_reports", x => x.id); - table.UniqueConstraint("ak_practice_session_reports_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_practice_session_reports_accuracy", "accuracy >= 0 and accuracy <= 1"); - table.CheckConstraint("ck_practice_session_reports_counts", "total_questions >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - table.CheckConstraint("ck_practice_session_reports_duration", "duration_seconds >= 0"); - table.CheckConstraint("ck_practice_session_reports_scores", "score >= 0 and total_score >= 0"); - table.ForeignKey( - name: "fk_practice_session_reports_practice_blueprints_tenant_id_blue~", - columns: x => new { x.tenant_id, x.blueprint_id }, - principalTable: "practice_blueprints", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_practice_session_reports_practice_sessions_tenant_id_practi~", - columns: x => new { x.tenant_id, x.practice_session_id }, - principalTable: "practice_sessions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_practice_session_reports_question_collections_tenant_id_col~", - columns: x => new { x.tenant_id, x.collection_id }, - principalTable: "question_collections", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_practice_session_reports_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_practice_session_reports_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "reports", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - question_id = table.Column(type: "uuid", nullable: true), - user_id = table.Column(type: "uuid", nullable: true), - handled_by = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - title = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - category = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - description = table.Column(type: "text", nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - priority = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - handled_at = table.Column(type: "timestamp with time zone", nullable: true), - resolution = table.Column(type: "text", nullable: true), - contact = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - attachments = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_reports", x => x.id); - table.UniqueConstraint("ak_reports_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_reports_questions_tenant_id_question_id", - columns: x => new { x.tenant_id, x.question_id }, - principalTable: "questions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_reports_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_reports_users_handled_by", - column: x => x.handled_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_reports_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "revenue_daily_stats", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_region_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - stat_date = table.Column(type: "date", nullable: false), - sale_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - real_revenue_cents = table.Column(type: "integer", nullable: false), - order_count = table.Column(type: "integer", nullable: false), - code_count = table.Column(type: "integer", nullable: false), - code_used = table.Column(type: "integer", nullable: false), - code_estimated = table.Column(type: "integer", nullable: false), - estimated_revenue_cents = table.Column(type: "integer", nullable: false), - rebuilt_at = table.Column(type: "timestamp with time zone", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_revenue_daily_stats", x => x.id); - table.UniqueConstraint("ak_revenue_daily_stats_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_revenue_daily_stats_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_revenue_daily_stats_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "user_score_events", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - user_id = table.Column(type: "uuid", nullable: false), - event_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - points = table.Column(type: "integer", nullable: false), - balance_after = table.Column(type: "integer", nullable: false), - source_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - source_id = table.Column(type: "uuid", nullable: true), - idempotency_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_user_score_events", x => x.id); - table.UniqueConstraint("ak_user_score_events_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_user_score_events_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_user_score_events_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "practice_session_report_sections", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - report_id = table.Column(type: "uuid", nullable: false), - practice_session_id = table.Column(type: "uuid", nullable: false), - section_key = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - section_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - question_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - question_count = table.Column(type: "integer", nullable: false), - answered_count = table.Column(type: "integer", nullable: false), - correct_count = table.Column(type: "integer", nullable: false), - wrong_count = table.Column(type: "integer", nullable: false), - unanswered_count = table.Column(type: "integer", nullable: false), - score = table.Column(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false), - total_score = table.Column(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false), - accuracy = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), - sort_order = table.Column(type: "integer", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_practice_session_report_sections", x => x.id); - table.UniqueConstraint("ak_practice_session_report_sections_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_practice_session_report_sections_accuracy", "accuracy >= 0 and accuracy <= 1"); - table.CheckConstraint("ck_practice_session_report_sections_counts", "question_count >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - table.CheckConstraint("ck_practice_session_report_sections_scores", "score >= 0 and total_score >= 0"); - table.ForeignKey( - name: "fk_practice_session_report_sections_practice_session_reports_t~", - columns: x => new { x.tenant_id, x.report_id }, - principalTable: "practice_session_reports", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_practice_session_report_sections_practice_sessions_tenant_i~", - columns: x => new { x.tenant_id, x.practice_session_id }, - principalTable: "practice_sessions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_practice_session_report_sections_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "report_status_events", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - report_id = table.Column(type: "uuid", nullable: false), - from_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - to_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - note = table.Column(type: "text", nullable: true), - actor_user_id = table.Column(type: "uuid", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_report_status_events", x => x.id); - table.UniqueConstraint("ak_report_status_events_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_report_status_events_reports_tenant_id_report_id", - columns: x => new { x.tenant_id, x.report_id }, - principalTable: "reports", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_report_status_events_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_report_status_events_users_actor_user_id", - column: x => x.actor_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.AddCheckConstraint( - name: "ck_practice_sessions_consumed_free_quota", - table: "practice_sessions", - sql: "consumed_free_quota >= 0"); - - migrationBuilder.CreateIndex( - name: "ix_dashboard_daily_stats_tenant_id_legacy_id", - table: "dashboard_daily_stats", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_dashboard_daily_stats_tenant_id_region_id", - table: "dashboard_daily_stats", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_dashboard_daily_stats_tenant_id_stat_date_region_id", - table: "dashboard_daily_stats", - columns: new[] { "tenant_id", "stat_date", "region_id" }, - unique: true) - .Annotation("Npgsql:NullsDistinct", false); - - migrationBuilder.CreateIndex( - name: "ix_exam_dates_tenant_id_legacy_id", - table: "exam_dates", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_exam_dates_tenant_id_region_id", - table: "exam_dates", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_exam_dates_tenant_id_school_id_exam_at", - table: "exam_dates", - columns: new[] { "tenant_id", "school_id", "exam_at" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_access_events_tenant_id_practice_session_id", - table: "practice_access_events", - columns: new[] { "tenant_id", "practice_session_id" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_access_events_tenant_id_user_id_created_at", - table: "practice_access_events", - columns: new[] { "tenant_id", "user_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_access_events_user_id", - table: "practice_access_events", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_practice_daily_usage_tenant_id_user_id_usage_date", - table: "practice_daily_usage", - columns: new[] { "tenant_id", "user_id", "usage_date" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_daily_usage_tenant_id_user_id_usage_date_scope_typ~", - table: "practice_daily_usage", - columns: new[] { "tenant_id", "user_id", "usage_date", "scope_type", "scope_id" }, - unique: true) - .Annotation("Npgsql:NullsDistinct", false); - - migrationBuilder.CreateIndex( - name: "ix_practice_daily_usage_user_id", - table: "practice_daily_usage", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_practice_session_report_sections_tenant_id_practice_session~", - table: "practice_session_report_sections", - columns: new[] { "tenant_id", "practice_session_id" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_session_report_sections_tenant_id_report_id_sectio~", - table: "practice_session_report_sections", - columns: new[] { "tenant_id", "report_id", "section_key" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_practice_session_report_sections_tenant_id_report_id_sort_o~", - table: "practice_session_report_sections", - columns: new[] { "tenant_id", "report_id", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_session_reports_tenant_id_blueprint_id_submitted_at", - table: "practice_session_reports", - columns: new[] { "tenant_id", "blueprint_id", "submitted_at" }, - filter: "blueprint_id is not null"); - - migrationBuilder.CreateIndex( - name: "ix_practice_session_reports_tenant_id_collection_id", - table: "practice_session_reports", - columns: new[] { "tenant_id", "collection_id" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_session_reports_tenant_id_practice_session_id", - table: "practice_session_reports", - columns: new[] { "tenant_id", "practice_session_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_practice_session_reports_tenant_id_user_id_submitted_at", - table: "practice_session_reports", - columns: new[] { "tenant_id", "user_id", "submitted_at" }); - - migrationBuilder.CreateIndex( - name: "ix_practice_session_reports_user_id", - table: "practice_session_reports", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_report_status_events_actor_user_id", - table: "report_status_events", - column: "actor_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_report_status_events_tenant_id_report_id_created_at", - table: "report_status_events", - columns: new[] { "tenant_id", "report_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_reports_handled_by", - table: "reports", - column: "handled_by"); - - migrationBuilder.CreateIndex( - name: "ix_reports_tenant_id_legacy_id", - table: "reports", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_reports_tenant_id_question_id_created_at", - table: "reports", - columns: new[] { "tenant_id", "question_id", "created_at" }, - filter: "question_id is not null"); - - migrationBuilder.CreateIndex( - name: "ix_reports_tenant_id_status_created_at", - table: "reports", - columns: new[] { "tenant_id", "status", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_reports_user_id", - table: "reports", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_revenue_daily_stats_tenant_id_legacy_id", - table: "revenue_daily_stats", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_revenue_daily_stats_tenant_id_region_id", - table: "revenue_daily_stats", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_revenue_daily_stats_tenant_id_stat_date_region_id_sale_type", - table: "revenue_daily_stats", - columns: new[] { "tenant_id", "stat_date", "region_id", "sale_type" }, - unique: true) - .Annotation("Npgsql:NullsDistinct", false); - - migrationBuilder.CreateIndex( - name: "ix_user_score_events_tenant_id_idempotency_key", - table: "user_score_events", - columns: new[] { "tenant_id", "idempotency_key" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_user_score_events_tenant_id_user_id_created_at", - table: "user_score_events", - columns: new[] { "tenant_id", "user_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_user_score_events_user_id", - table: "user_score_events", - column: "user_id"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "dashboard_daily_stats"); - - migrationBuilder.DropTable( - name: "exam_dates"); - - migrationBuilder.DropTable( - name: "practice_access_events"); - - migrationBuilder.DropTable( - name: "practice_daily_usage"); - - migrationBuilder.DropTable( - name: "practice_session_report_sections"); - - migrationBuilder.DropTable( - name: "report_status_events"); - - migrationBuilder.DropTable( - name: "revenue_daily_stats"); - - migrationBuilder.DropTable( - name: "user_score_events"); - - migrationBuilder.DropTable( - name: "practice_session_reports"); - - migrationBuilder.DropTable( - name: "reports"); - - migrationBuilder.DropCheckConstraint( - name: "ck_practice_sessions_consumed_free_quota", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "access_rules", - table: "question_collections"); - - migrationBuilder.DropColumn( - name: "access_entitlement_id", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "access_mode", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "access_snapshot", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "consumed_free_quota", - table: "practice_sessions"); - - migrationBuilder.DropColumn( - name: "access_rules", - table: "practice_blueprints"); - - migrationBuilder.DropColumn( - name: "access_rules", - table: "content_nodes"); - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725212832_AddAuthAndTenantOperationsPersistence.Designer.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725212832_AddAuthAndTenantOperationsPersistence.Designer.cs deleted file mode 100644 index 860d5d4..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725212832_AddAuthAndTenantOperationsPersistence.Designer.cs +++ /dev/null @@ -1,8043 +0,0 @@ -// -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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_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_handbook_chapters"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_chapters_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_chapters_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_subject_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_chapters_tenant_id_entry_id_content_node_id_subjec~"); - - b.ToTable("handbook_chapters", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ChapterId") - .HasColumnType("uuid") - .HasColumnName("chapter_id"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Summary") - .HasColumnType("text") - .HasColumnName("summary"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_handbook_entries"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_entries_tenant_id_id"); - - b.HasIndex("TenantId", "ChapterId") - .HasDatabaseName("ix_handbook_entries_tenant_id_chapter_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_entries_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_entries_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "ChapterId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_entries_tenant_id_entry_id_content_node_id_chapter~"); - - b.ToTable("handbook_entries", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", 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("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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - 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_handbook_subjects"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_subjects_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_subjects_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "MajorId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_major_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_school_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_subjects_tenant_id_entry_id_content_node_id_region~"); - - b.ToTable("handbook_subjects", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("CdnUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cdn_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FileName") - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("file_name"); - - 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("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.HasKey("Id") - .HasName("pk_images"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_images_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_images_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "Category", "IsPublic") - .HasDatabaseName("ix_images_tenant_id_category_is_public"); - - b.ToTable("images", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", 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("AssemblyType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assembly_type"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_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("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PassScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("pass_score"); - - b.Property("QuestionLimit") - .HasColumnType("integer") - .HasColumnName("question_limit"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Rules") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("rules") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Sections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sections") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_practice_blueprints"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_blueprints_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_practice_blueprints_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_practice_blueprints_updated_by"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_collection_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_practice_blueprints_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_region_id"); - - b.HasIndex("TenantId", "NodeId", "CollectionId", "Mode", "Status", "SortOrder") - .HasDatabaseName("ix_practice_blueprints_tenant_id_node_id_collection_id_mode_st~"); - - b.ToTable("practice_blueprints", null, t => - { - t.HasCheckConstraint("ck_practice_blueprints_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_practice_blueprints_question_limit", "question_limit is null or question_limit > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", 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("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - b.Property("CollectionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("collection_type"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Filters") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("filters") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_question_collections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collections_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_collections_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_question_collections_updated_by"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_question_collections_tenant_id_category_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_question_collections_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_collections_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_question_collections_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_collections_tenant_id_region_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_question_collections_tenant_id_subject_id"); - - b.HasIndex("TenantId", "NodeId", "Status", "SortOrder") - .HasDatabaseName("ix_question_collections_tenant_id_node_id_status_sort_order"); - - b.ToTable("question_collections", null, t => - { - t.HasCheckConstraint("ck_question_collections_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_question_collections_question_count", "question_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Required") - .HasColumnType("boolean") - .HasColumnName("required"); - - b.Property("Score") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - 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_question_collection_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collection_items_tenant_id_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_question_collection_items_tenant_id_question_id"); - - b.HasIndex("TenantId", "CollectionId", "QuestionId") - .IsUnique() - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_question_~"); - - b.HasIndex("TenantId", "CollectionId", "SectionKey", "SortOrder") - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_section_k~"); - - b.ToTable("question_collection_items", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", 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("DisplayName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Types") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("types") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_question_type_groups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_type_groups_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_type_groups_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_question_type_groups_tenant_id_subject_id_is_active_sort_or~"); - - b.ToTable("question_type_groups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", 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("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("LegacyVideoId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_video_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_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("VideoId") - .HasColumnType("uuid") - .HasColumnName("video_id"); - - b.Property("VideoType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("video_type"); - - b.HasKey("Id") - .HasName("pk_question_videos"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_videos_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "VideoId") - .HasDatabaseName("ix_question_videos_tenant_id_video_id"); - - b.HasIndex("TenantId", "QuestionId", "VideoId", "VideoType") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_question_id_video_id_video_type"); - - b.ToTable("question_videos", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("SourceSubjectId") - .HasColumnType("uuid") - .HasColumnName("source_subject_id"); - - b.Property("TargetSubjectId") - .HasColumnType("uuid") - .HasColumnName("target_subject_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Id") - .HasColumnType("uuid") - .HasColumnName("id"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacySourceSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_source_subject_id"); - - b.Property("LegacyTargetSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_target_subject_id"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at"); - - b.HasKey("TenantId", "SourceSubjectId", "TargetSubjectId") - .HasName("pk_subject_shares"); - - b.HasIndex("TenantId", "TargetSubjectId") - .HasDatabaseName("ix_subject_shares_tenant_id_target_subject_id"); - - b.ToTable("subject_shares", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", 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("FavoritedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("favorited_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Note") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.HasKey("Id") - .HasName("pk_user_word_favorites"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_favorites_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_favorites_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_favorites_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_favorites_tenant_id_user_id_word_id"); - - b.ToTable("user_word_favorites", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CorrectStreak") - .HasColumnType("integer") - .HasColumnName("correct_streak"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DueLevel") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("due_level"); - - b.Property("EaseFactor") - .ValueGeneratedOnAdd() - .HasPrecision(4, 2) - .HasColumnType("numeric(4,2)") - .HasDefaultValue(2.50m) - .HasColumnName("ease_factor"); - - b.Property("LastResult") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("last_result"); - - b.Property("LastReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_review_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NextReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_review_at"); - - b.Property("ReviewCount") - .HasColumnType("integer") - .HasColumnName("review_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_user_word_progress"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_progress_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_progress_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_progress_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_word_id"); - - b.HasIndex("TenantId", "UserId", "NextReviewAt", "Status", "DueLevel") - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_next_review_at_status_~"); - - b.ToTable("user_word_progress", null, t => - { - t.HasCheckConstraint("ck_user_word_progress_correct_streak", "correct_streak >= 0"); - - t.HasCheckConstraint("ck_user_word_progress_ease_factor", "ease_factor >= 1.30 and ease_factor <= 3.00"); - - t.HasCheckConstraint("ck_user_word_progress_review_count", "review_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("IsGeneral") - .HasColumnType("boolean") - .HasColumnName("is_general"); - - b.Property("KnowledgeTags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("knowledge_tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ThumbnailUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("thumbnail_url"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VideoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("video_url"); - - b.HasKey("Id") - .HasName("pk_video_explanations"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_video_explanations_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_video_explanations_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SourceHash") - .HasDatabaseName("ix_video_explanations_tenant_id_source_hash") - .HasFilter("source_hash is not null"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_video_explanations_tenant_id_subject_id_is_active_sort_order"); - - b.ToTable("video_explanations", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WordCount") - .HasColumnType("integer") - .HasColumnName("word_count"); - - b.HasKey("Id") - .HasName("pk_vocabulary_units"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_units_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_units_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_region_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_units_tenant_id_entry_id_content_node_id_region_~"); - - b.ToTable("vocabulary_units", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Example") - .HasColumnType("text") - .HasColumnName("example"); - - b.Property("ExampleTranslation") - .HasColumnType("text") - .HasColumnName("example_translation"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Meaning") - .HasColumnType("text") - .HasColumnName("meaning"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phonetic") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("phonetic"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitId") - .HasColumnType("uuid") - .HasColumnName("unit_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Word") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("word"); - - b.HasKey("Id") - .HasName("pk_vocabulary_words"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_words_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_words_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_words_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UnitId", "IsActive", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_vocabulary_words_tenant_id_unit_id_is_active_sort_order_cre~"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "UnitId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_words_tenant_id_entry_id_content_node_id_unit_id~"); - - b.ToTable("vocabulary_words", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", 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("LastCheckInDate") - .HasColumnType("date") - .HasColumnName("last_check_in_date"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("MasteredWordsCount") - .HasColumnType("integer") - .HasColumnName("mastered_words_count"); - - b.Property("ModuleSelections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_selections") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Progress") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("progress") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionsAnsweredToday") - .HasColumnType("integer") - .HasColumnName("questions_answered_today"); - - b.Property("RecentActivities") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("recent_activities") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SelectedMajorId") - .HasColumnType("uuid") - .HasColumnName("selected_major_id"); - - b.Property("SelectedSchoolId") - .HasColumnType("uuid") - .HasColumnName("selected_school_id"); - - b.Property("Stats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("stats") - .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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_student_profiles"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_student_profiles_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_student_profiles_user_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_student_profiles_tenant_id_region_id"); - - b.HasIndex("TenantId", "SelectedMajorId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_major_id"); - - b.HasIndex("TenantId", "SelectedSchoolId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_school_id"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_student_profiles_tenant_id_user_id"); - - b.ToTable("student_profiles", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AvatarUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("avatar_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("LastSeenAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_seen_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPasswordHash") - .HasMaxLength(512) - .HasColumnType("character varying(512)") - .HasColumnName("legacy_password_hash"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PasswordMigrationRequired") - .HasColumnType("boolean") - .HasColumnName("password_migration_required"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("PrimaryRole") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("primary_role"); - - b.Property("RawProfile") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_profile") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Score") - .HasColumnType("integer") - .HasColumnName("score"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Username") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("username"); - - b.HasKey("Id") - .HasName("pk_users"); - - b.HasIndex("Email") - .IsUnique() - .HasDatabaseName("ix_users_email"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_users_legacy_id"); - - b.HasIndex("Phone") - .IsUnique() - .HasDatabaseName("ix_users_phone"); - - b.HasIndex("Username") - .IsUnique() - .HasDatabaseName("ix_users_username"); - - b.ToTable("users", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", 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("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("OpenId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("open_id"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderSubject") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("provider_subject"); - - b.Property("SecretPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("secret_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UnionId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("union_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_identities"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_identities_user_id"); - - b.HasIndex("Provider", "ProviderSubject") - .IsUnique() - .HasDatabaseName("ix_user_identities_provider_provider_subject"); - - b.ToTable("user_identities", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("AnsweredAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("answered_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IsCorrect") - .HasColumnType("boolean") - .HasColumnName("is_correct"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("QuestionVersionId") - .HasColumnType("uuid") - .HasColumnName("question_version_id"); - - b.Property("SelectedOptions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("selected_options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_answer_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_answer_records_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_answer_records_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_answer_records_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id"); - - b.HasIndex("TenantId", "QuestionId", "QuestionVersionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id_question_version_id"); - - b.HasIndex("TenantId", "UserId", "PracticeSessionId") - .HasDatabaseName("ix_answer_records_tenant_id_user_id_practice_session_id"); - - b.ToTable("answer_records", null, t => - { - t.HasCheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActiveUsers") - .HasColumnType("integer") - .HasColumnName("active_users"); - - 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("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("NewOrders") - .HasColumnType("integer") - .HasColumnName("new_orders"); - - b.Property("NewQuestions") - .HasColumnType("integer") - .HasColumnName("new_questions"); - - b.Property("NewRevenueCents") - .HasColumnType("integer") - .HasColumnName("new_revenue_cents"); - - b.Property("NewUsers") - .HasColumnType("integer") - .HasColumnName("new_users"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_dashboard_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_dashboard_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_stat_date_region_id"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId"), false); - - b.ToTable("dashboard_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", 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("ExamAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("exam_at"); - - b.Property("ExamName") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("exam_name"); - - b.Property("ExamType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("exam_type"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("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_exam_dates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_exam_dates_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_exam_dates_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_exam_dates_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId", "ExamAt") - .HasDatabaseName("ix_exam_dates_tenant_id_school_id_exam_at"); - - b.ToTable("exam_dates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_favorite_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_favorite_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_favorite_questions_tenant_id_question_id"); - - b.ToTable("favorite_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("access_mode"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EntitlementId") - .HasColumnType("uuid") - .HasColumnName("entitlement_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("GrantedCount") - .HasColumnType("integer") - .HasColumnName("granted_count"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("Reason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("reason"); - - b.Property("RequestedCount") - .HasColumnType("integer") - .HasColumnName("requested_count"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_access_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_access_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_access_events_user_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_access_events_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_practice_access_events_tenant_id_user_id_created_at"); - - b.ToTable("practice_access_events", null, t => - { - t.HasCheckConstraint("ck_practice_access_events_consumed_free_quota", "consumed_free_quota >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_granted_count", "granted_count >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_requested_count", "requested_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", 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("FreeLimit") - .HasColumnType("integer") - .HasColumnName("free_limit"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsageDate") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasColumnName("usage_date") - .HasDefaultValueSql("current_date"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_daily_usage"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_daily_usage_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_daily_usage_user_id"); - - b.HasIndex("TenantId", "UserId", "UsageDate") - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date"); - - b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId") - .IsUnique() - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date_scope_typ~"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId"), false); - - b.ToTable("practice_daily_usage", null, t => - { - t.HasCheckConstraint("ck_practice_daily_usage_free_limit", "free_limit >= 0"); - - t.HasCheckConstraint("ck_practice_daily_usage_used_count", "used_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessEntitlementId") - .HasColumnType("uuid") - .HasColumnName("access_entitlement_id"); - - b.Property("AccessMode") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasDefaultValue("free") - .HasColumnName("access_mode"); - - b.Property("AccessSnapshot") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("access_snapshot") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("ContentNodeId") - .HasColumnType("uuid") - .HasColumnName("content_node_id"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("FinishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("finished_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at") - .HasDefaultValueSql("now()"); - - b.Property("TargetId") - .HasColumnType("uuid") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_sessions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "UserId", "Id") - .HasName("ak_practice_sessions_tenant_id_user_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_sessions_user_id"); - - b.HasIndex("TenantId", "BlueprintId") - .HasDatabaseName("ix_practice_sessions_tenant_id_blueprint_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_sessions_tenant_id_collection_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_practice_sessions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_sessions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "UserId", "StartedAt") - .HasDatabaseName("ix_practice_sessions_tenant_id_user_id_started_at"); - - b.ToTable("practice_sessions", null, t => - { - t.HasCheckConstraint("ck_practice_sessions_consumed_free_quota", "consumed_free_quota >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionResults") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_results") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionStats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("section_stats") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at"); - - b.Property("SubmittedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("submitted_at") - .HasDefaultValueSql("now()"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalQuestions") - .HasColumnType("integer") - .HasColumnName("total_questions"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.Property("WrongQuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("wrong_question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.HasKey("Id") - .HasName("pk_practice_session_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_reports_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_session_reports_user_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_session_reports_tenant_id_collection_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .IsUnique() - .HasDatabaseName("ix_practice_session_reports_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "BlueprintId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_blueprint_id_submitted_at") - .HasFilter("blueprint_id is not null"); - - b.HasIndex("TenantId", "UserId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_user_id_submitted_at"); - - b.ToTable("practice_session_reports", null, t => - { - t.HasCheckConstraint("ck_practice_session_reports_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_reports_counts", "total_questions >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_duration", "duration_seconds >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("question_type"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - b.Property("SectionName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("section_name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_practice_session_report_sections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_report_sections_tenant_id_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_practice_session~"); - - b.HasIndex("TenantId", "ReportId", "SectionKey") - .IsUnique() - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sectio~"); - - b.HasIndex("TenantId", "ReportId", "SortOrder") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sort_o~"); - - b.ToTable("practice_session_report_sections", null, t => - { - t.HasCheckConstraint("ck_practice_session_report_sections_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_report_sections_counts", "question_count >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_report_sections_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", 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("LastAccessAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_access_at"); - - b.Property("LastPracticeAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_practice_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("practice_type"); - - b.Property("Progress") - .HasColumnType("integer") - .HasColumnName("progress"); - - b.Property("TargetLegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("target_legacy_id"); - - b.Property("TargetName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("target_name"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_recent_practices"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_recent_practices_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_recent_practices_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_recent_practices_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "LastAccessAt") - .HasDatabaseName("ix_recent_practices_tenant_id_user_id_last_access_at"); - - b.ToTable("recent_practices", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attachments") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("attachments") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("Contact") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("contact"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("HandledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("handled_at"); - - b.Property("HandledBy") - .HasColumnType("uuid") - .HasColumnName("handled_by"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Resolution") - .HasColumnType("text") - .HasColumnName("resolution"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_reports_tenant_id_id"); - - b.HasIndex("HandledBy") - .HasDatabaseName("ix_reports_handled_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_reports_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_reports_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_question_id_created_at") - .HasFilter("question_id is not null"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_status_created_at"); - - b.ToTable("reports", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_report_status_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_report_status_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_report_status_events_actor_user_id"); - - b.HasIndex("TenantId", "ReportId", "CreatedAt") - .HasDatabaseName("ix_report_status_events_tenant_id_report_id_created_at"); - - b.ToTable("report_status_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CodeCount") - .HasColumnType("integer") - .HasColumnName("code_count"); - - b.Property("CodeEstimated") - .HasColumnType("integer") - .HasColumnName("code_estimated"); - - b.Property("CodeUsed") - .HasColumnType("integer") - .HasColumnName("code_used"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EstimatedRevenueCents") - .HasColumnType("integer") - .HasColumnName("estimated_revenue_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("OrderCount") - .HasColumnType("integer") - .HasColumnName("order_count"); - - b.Property("RealRevenueCents") - .HasColumnType("integer") - .HasColumnName("real_revenue_cents"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_revenue_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_revenue_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_stat_date_region_id_sale_type"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType"), false); - - b.ToTable("revenue_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BalanceAfter") - .HasColumnType("integer") - .HasColumnName("balance_after"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("IdempotencyKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("idempotency_key"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Points") - .HasColumnType("integer") - .HasColumnName("points"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_score_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_score_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_score_events_user_id"); - - b.HasIndex("TenantId", "IdempotencyKey") - .IsUnique() - .HasDatabaseName("ix_user_score_events_tenant_id_idempotency_key"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_user_score_events_tenant_id_user_id_created_at"); - - b.ToTable("user_score_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("LastWrongAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("last_wrong_at") - .HasDefaultValueSql("now()"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("WrongCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(1) - .HasColumnName("wrong_count"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_wrong_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_wrong_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_wrong_questions_tenant_id_question_id"); - - b.ToTable("wrong_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - 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("CurrentVersionId") - .HasColumnType("uuid") - .HasColumnName("current_version_id"); - - b.Property("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExamMarkers") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("exam_markers") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("HasVideoExplanation") - .HasColumnType("boolean") - .HasColumnName("has_video_explanation"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyNodeId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_node_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("MediaUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("media_url"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PrimaryCollectionId") - .HasColumnType("uuid") - .HasColumnName("primary_collection_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Type") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("type"); - - b.Property("TypeLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("type_label"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_questions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_questions_tenant_id_id"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_questions_tenant_id_category_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_questions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_questions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_questions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "NodeId") - .HasDatabaseName("ix_questions_tenant_id_node_id"); - - b.HasIndex("TenantId", "PrimaryCollectionId") - .HasDatabaseName("ix_questions_tenant_id_primary_collection_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_questions_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_questions_tenant_id_subject_id"); - - b.HasIndex("TenantId", "Id", "CurrentVersionId") - .HasDatabaseName("ix_questions_tenant_id_id_current_version_id"); - - b.ToTable("questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SourceScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_scope"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_banks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_banks_tenant_id_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_banks_tenant_id_region_id"); - - b.ToTable("question_banks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("CodeLang") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("code_lang"); - - b.Property("CodeTemplate") - .HasColumnType("text") - .HasColumnName("code_template"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CorrectOptionIndex") - .HasColumnType("integer") - .HasColumnName("correct_option_index"); - - b.Property("CorrectOptionIndices") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("correct_option_indices") - .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("Explanation") - .HasColumnType("text") - .HasColumnName("explanation"); - - b.Property("Options") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubQuestions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sub_questions") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("VersionNo") - .HasColumnType("integer") - .HasColumnName("version_no"); - - b.HasKey("Id") - .HasName("pk_question_versions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_versions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "QuestionId", "Id") - .HasName("ak_question_versions_tenant_id_question_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_versions_created_by"); - - b.HasIndex("QuestionId", "VersionNo") - .IsUnique() - .HasDatabaseName("ix_question_versions_question_id_version_no"); - - b.ToTable("question_versions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", 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("FailureCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("failure_code"); - - b.Property("Identifier") - .HasMaxLength(320) - .HasColumnType("character varying(320)") - .HasColumnName("identifier"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Result") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("result"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_login_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_login_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_login_events_user_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_auth_login_events_tenant_id_user_id_created_at"); - - b.ToTable("auth_login_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", 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("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("RevokedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("revoked_at"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TokenHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("token_hash"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_sessions_tenant_id_id"); - - b.HasIndex("TokenHash") - .IsUnique() - .HasDatabaseName("ix_auth_sessions_token_hash"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_sessions_user_id"); - - b.HasIndex("TenantId", "UserId", "ExpiresAt") - .HasDatabaseName("ix_auth_sessions_tenant_id_user_id_expires_at") - .HasFilter("revoked_at is null"); - - b.ToTable("auth_sessions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Dimension") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("dimension"); - - b.Property("ScopeHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("scope_hash"); - - b.Property("BucketStart") - .HasColumnType("timestamp with time zone") - .HasColumnName("bucket_start"); - - b.Property("RequestCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0) - .HasColumnName("request_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId", "Dimension", "ScopeHash", "BucketStart") - .HasName("pk_sms_send_rate_limits"); - - b.HasIndex("UpdatedAt") - .HasDatabaseName("ix_sms_send_rate_limits_updated_at"); - - b.ToTable("sms_send_rate_limits", null, t => - { - t.HasCheckConstraint("ck_sms_send_rate_limits_request_count", "request_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempts") - .HasColumnType("integer") - .HasColumnName("attempts"); - - b.Property("CodeHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("code_hash"); - - b.Property("ConsumedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("consumed_at"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phone") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Purpose") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("purpose"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_sms_verification_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_sms_verification_codes_tenant_id_id"); - - b.HasIndex("TenantId", "Phone", "Purpose") - .IsUnique() - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "CreatedAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_created_at") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "ExpiresAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_expires_at"); - - b.ToTable("sms_verification_codes", null, t => - { - t.HasCheckConstraint("ck_sms_verification_codes_attempts", "attempts >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BillingStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("billing_status"); - - 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("LegalName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("legal_name"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OwnerUserId") - .HasColumnType("uuid") - .HasColumnName("owner_user_id"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("slug"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenants"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenants_legacy_id"); - - b.HasIndex("OwnerUserId") - .HasDatabaseName("ix_tenants_owner_user_id"); - - b.HasIndex("Slug") - .IsUnique() - .HasDatabaseName("ix_tenants_slug"); - - b.ToTable("tenants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ConfigPublic") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("config_public") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_auth_providers"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_auth_providers_tenant_id_id"); - - b.HasIndex("TenantId", "Provider") - .IsUnique() - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider"); - - b.HasIndex("TenantId", "Provider", "Status") - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider_status"); - - b.ToTable("tenant_auth_providers", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("BrandName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("brand_name"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FaviconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("favicon_url"); - - b.Property("LogoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("logo_url"); - - b.Property("OrganizationName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("organization_name"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ServiceAccountName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("service_account_name"); - - b.Property("ServiceWechat") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("service_wechat"); - - b.Property("ShortName") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("short_name"); - - b.Property("Slogan") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("slogan"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_branding"); - - b.ToTable("tenant_branding", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Code") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("code"); - - 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("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_classes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_classes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_classes_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_classes_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_code") - .HasFilter("code is not null and code <> ''"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_tenant_classes_tenant_id_region_id") - .HasFilter("region_id is not null"); - - b.HasIndex("TenantId", "Status", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_tenant_classes_tenant_id_status_sort_order_created_at"); - - b.ToTable("tenant_classes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_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("JoinedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("joined_at") - .HasDefaultValueSql("now()"); - - b.Property("LeftAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("left_at"); - - b.Property("MemberType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("member_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_class_members"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_class_members_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_class_members_user_id"); - - b.HasIndex("TenantId", "ClassId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_status_member_type"); - - b.HasIndex("TenantId", "ClassId", "UserId", "MemberType") - .IsUnique() - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_user_id_member_type"); - - b.HasIndex("TenantId", "UserId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_user_id_status_member_type"); - - b.ToTable("tenant_class_members", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", 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("DomainType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("domain_type"); - - b.Property("Host") - .IsRequired() - .HasMaxLength(253) - .HasColumnType("citext") - .HasColumnName("host"); - - b.Property("IsPrimary") - .HasColumnType("boolean") - .HasColumnName("is_primary"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VerificationToken") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("verification_token"); - - b.Property("VerifiedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("verified_at"); - - b.HasKey("Id") - .HasName("pk_tenant_domains"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_domains_tenant_id_id"); - - b.HasIndex("Host") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_host"); - - b.HasIndex("TenantId", "IsPrimary") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_tenant_id_is_primary") - .HasFilter("is_primary"); - - b.ToTable("tenant_domains", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", 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("LegacyRole") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("legacy_role"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Role") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("role"); - - b.Property("RoleTemplateId") - .HasColumnType("uuid") - .HasColumnName("role_template_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_memberships"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_memberships_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_memberships_user_id"); - - b.HasIndex("TenantId", "RoleTemplateId") - .HasDatabaseName("ix_tenant_memberships_tenant_id_role_template_id"); - - b.HasIndex("TenantId", "UserId", "Role") - .IsUnique() - .HasDatabaseName("ix_tenant_memberships_tenant_id_user_id_role"); - - b.ToTable("tenant_memberships", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BaseRole") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("base_role"); - - 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("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DataScope") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("data_scope") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("FieldPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("field_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("IsSystem") - .HasColumnType("boolean") - .HasColumnName("is_system"); - - b.Property("MenuPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("menu_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ModulePermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_role_templates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_role_templates_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_role_templates_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_role_templates_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_role_templates_tenant_id_code"); - - b.HasIndex("TenantId", "Status", "SortOrder") - .HasDatabaseName("ix_tenant_role_templates_tenant_id_status_sort_order"); - - b.ToTable("tenant_role_templates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("AdminFeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("admin_feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PublicConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_settings"); - - b.ToTable("tenant_settings", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignedToUserId") - .HasColumnType("uuid") - .HasColumnName("assigned_to_user_id"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_id"); - - b.Property("CompletedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("completed_at"); - - b.Property("CompletedBy") - .HasColumnType("uuid") - .HasColumnName("completed_by"); - - 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("DueAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("due_at"); - - b.Property("FollowupType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("followup_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .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.HasKey("Id") - .HasName("pk_tenant_student_followups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_followups_tenant_id_id"); - - b.HasIndex("AssignedToUserId") - .HasDatabaseName("ix_tenant_student_followups_assigned_to_user_id"); - - b.HasIndex("CompletedBy") - .HasDatabaseName("ix_tenant_student_followups_completed_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_followups_student_user_id"); - - b.HasIndex("TenantId", "AssignedToUserId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_assigned_to_user_id_stat~") - .HasFilter("assigned_to_user_id is not null"); - - b.HasIndex("TenantId", "ClassId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_class_id_status_due_at") - .HasFilter("class_id is not null"); - - b.HasIndex("TenantId", "StudentUserId", "Status", "DueAt", "CreatedAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_student_user_id_status_d~"); - - b.ToTable("tenant_student_followups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Content") - .IsRequired() - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("IsPinned") - .HasColumnType("boolean") - .HasColumnName("is_pinned"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NoteType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("note_type"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - 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_tenant_student_notes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_notes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_student_notes_created_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_notes_student_user_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_student_notes_updated_by"); - - b.HasIndex("TenantId", "CreatedBy", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_created_by_created_at") - .HasFilter("created_by is not null"); - - b.HasIndex("TenantId", "StudentUserId", "IsPinned", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_student_user_id_is_pinned_cr~"); - - b.ToTable("tenant_student_notes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Category", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_categories_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Major", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_majors_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.ModuleNode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_module_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_module_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Region", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_regions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.RegionModule", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_region_modules_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_region_modules_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.School", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_schools_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Subject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.AppAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_app_assets_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAsset", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_assets_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_updated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("VerifiedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_verified_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentEntry", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_entries_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportIssue", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportItem", null) - .WithMany() - .HasForeignKey("TenantId", "ItemId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_import_issues_content_import_items_tenant_id_item_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportJob", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_import_jobs_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_jobs_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "TargetCategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_categories_tenant_id_target_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "TargetContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_content_nodes_tenant_id_target_content_~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "TargetQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_question_banks_tenant_id_target_questio~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "TargetRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_regions_tenant_id_target_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentNode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_nodes_content_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookChapter", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_chapters_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.HandbookSubject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_chapters_handbook_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.HandbookChapter", null) - .WithMany() - .HasForeignKey("TenantId", "ChapterId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_entries_handbook_chapters_tenant_id_chapter_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_images_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_blueprints_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_question_collections_tenant_id_collecti~"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_question_banks_tenant_id_question_bank~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_question_collections_tenant_id_co~"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_type_groups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_type_groups_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_videos_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.Content.VideoExplanation", null) - .WithMany() - .HasForeignKey("TenantId", "VideoId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_video_explanations_tenant_id_video_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SourceSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_source_subject_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_video_explanations_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_video_explanations_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_units_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_words_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyUnit", null) - .WithMany() - .HasForeignKey("TenantId", "UnitId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_vocabulary_units_tenant_id_unit_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedMajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_majors_tenant_id_selected_major_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedSchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_schools_tenant_id_selected_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_identities_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId", "QuestionVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_question_versions_tenant_id_question_id_ques~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "UserId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "UserId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_practice_sessions_tenant_id_user_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_dashboard_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_dashboard_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_exam_dates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_access_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_users_user_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_practice_sessions_tenant_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_question_collections_tenant_id_collection~"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_practice_blueprints_tenant_id_blue~"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_question_collections_tenant_id_col~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_practice_sessions_tenant_id_practi~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_sessions_tenant_i~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSessionReport", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_session_reports_t~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_recent_practices_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_recent_practices_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("HandledBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_handled_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_reports_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_report_status_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.Report", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_reports_tenant_id_report_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_revenue_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_revenue_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "PrimaryCollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_collections_tenant_id_primary_collection~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_banks_tenant_id_question_bank_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_subjects_tenant_id_subject_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "Id", "CurrentVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_versions_tenant_id_id_current_version_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_banks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_banks_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_versions_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_versions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_login_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_auth_login_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_send_rate_limits_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_verification_codes_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("OwnerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenants_users_owner_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_auth_providers_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantBranding", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_branding_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_classes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_classes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_domains_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantRoleTemplate", null) - .WithMany() - .HasForeignKey("TenantId", "RoleTemplateId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_memberships_tenant_role_templates_tenant_id_role_tem~"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_role_templates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantSettings", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_settings_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedToUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_assigned_to_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CompletedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_completed_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_updated_by"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725212832_AddAuthAndTenantOperationsPersistence.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725212832_AddAuthAndTenantOperationsPersistence.cs deleted file mode 100644 index af4f7bd..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725212832_AddAuthAndTenantOperationsPersistence.cs +++ /dev/null @@ -1,669 +0,0 @@ -using System; -using System.Text.Json; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Tiku.Infrastructure.Persistence.Migrations -{ - /// - public partial class AddAuthAndTenantOperationsPersistence : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "role_template_id", - table: "tenant_memberships", - type: "uuid", - nullable: true); - - migrationBuilder.CreateTable( - name: "auth_login_events", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - user_id = table.Column(type: "uuid", nullable: true), - provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - identifier = table.Column(type: "character varying(320)", maxLength: 320, nullable: true), - result = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - failure_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - ip_address = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - user_agent = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_auth_login_events", x => x.id); - table.UniqueConstraint("ak_auth_login_events_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_auth_login_events_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_auth_login_events_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "auth_sessions", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: false), - token_hash = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), - provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - expires_at = table.Column(type: "timestamp with time zone", nullable: false), - revoked_at = table.Column(type: "timestamp with time zone", nullable: true), - ip_address = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - user_agent = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_auth_sessions", x => x.id); - table.UniqueConstraint("ak_auth_sessions_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_auth_sessions_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_auth_sessions_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "sms_send_rate_limits", - columns: table => new - { - tenant_id = table.Column(type: "uuid", nullable: false), - dimension = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - scope_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: false), - bucket_start = table.Column(type: "timestamp with time zone", nullable: false), - request_count = table.Column(type: "integer", nullable: false, defaultValue: 0), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_sms_send_rate_limits", x => new { x.tenant_id, x.dimension, x.scope_hash, x.bucket_start }); - table.CheckConstraint("ck_sms_send_rate_limits_request_count", "request_count >= 0"); - table.ForeignKey( - name: "fk_sms_send_rate_limits_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "sms_verification_codes", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - phone = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - purpose = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - code_hash = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), - provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - attempts = table.Column(type: "integer", nullable: false), - expires_at = table.Column(type: "timestamp with time zone", nullable: false), - consumed_at = table.Column(type: "timestamp with time zone", nullable: true), - ip_address = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - user_agent = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_sms_verification_codes", x => x.id); - table.UniqueConstraint("ak_sms_verification_codes_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_sms_verification_codes_attempts", "attempts >= 0"); - table.ForeignKey( - name: "fk_sms_verification_codes_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_auth_providers", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - display_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - config_public = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_auth_providers", x => x.id); - table.UniqueConstraint("ak_tenant_auth_providers_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_tenant_auth_providers_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_classes", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - description = table.Column(type: "text", nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - sort_order = table.Column(type: "integer", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_by = table.Column(type: "uuid", nullable: true), - updated_by = table.Column(type: "uuid", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_classes", x => x.id); - table.UniqueConstraint("ak_tenant_classes_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_tenant_classes_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_tenant_classes_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_classes_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_tenant_classes_users_updated_by", - column: x => x.updated_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "tenant_role_templates", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - description = table.Column(type: "text", nullable: true), - base_role = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - permissions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - menu_permissions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - module_permissions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - field_permissions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - data_scope = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - is_system = table.Column(type: "boolean", nullable: false), - sort_order = table.Column(type: "integer", nullable: false), - created_by = table.Column(type: "uuid", nullable: true), - updated_by = table.Column(type: "uuid", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_role_templates", x => x.id); - table.UniqueConstraint("ak_tenant_role_templates_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_tenant_role_templates_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_role_templates_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_tenant_role_templates_users_updated_by", - column: x => x.updated_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "tenant_student_notes", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - student_user_id = table.Column(type: "uuid", nullable: false), - note_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - content = table.Column(type: "text", nullable: false), - visibility = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - is_pinned = table.Column(type: "boolean", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_by = table.Column(type: "uuid", nullable: true), - updated_by = table.Column(type: "uuid", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_student_notes", x => x.id); - table.UniqueConstraint("ak_tenant_student_notes_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_tenant_student_notes_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_student_notes_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_tenant_student_notes_users_student_user_id", - column: x => x.student_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_student_notes_users_updated_by", - column: x => x.updated_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "tenant_class_members", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - class_id = table.Column(type: "uuid", nullable: false), - user_id = table.Column(type: "uuid", nullable: false), - member_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - joined_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - left_at = table.Column(type: "timestamp with time zone", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_by = table.Column(type: "uuid", nullable: true), - updated_by = table.Column(type: "uuid", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_class_members", x => x.id); - table.UniqueConstraint("ak_tenant_class_members_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_tenant_class_members_tenant_classes_tenant_id_class_id", - columns: x => new { x.tenant_id, x.class_id }, - principalTable: "tenant_classes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_class_members_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_class_members_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_student_followups", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - student_user_id = table.Column(type: "uuid", nullable: false), - assigned_to_user_id = table.Column(type: "uuid", nullable: true), - class_id = table.Column(type: "uuid", nullable: true), - title = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - description = table.Column(type: "text", nullable: true), - followup_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - priority = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - due_at = table.Column(type: "timestamp with time zone", nullable: true), - completed_at = table.Column(type: "timestamp with time zone", nullable: true), - completed_by = table.Column(type: "uuid", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_by = table.Column(type: "uuid", nullable: true), - updated_by = table.Column(type: "uuid", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_student_followups", x => x.id); - table.UniqueConstraint("ak_tenant_student_followups_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_tenant_student_followups_tenant_classes_tenant_id_class_id", - columns: x => new { x.tenant_id, x.class_id }, - principalTable: "tenant_classes", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_tenant_student_followups_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_student_followups_users_assigned_to_user_id", - column: x => x.assigned_to_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_tenant_student_followups_users_completed_by", - column: x => x.completed_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_tenant_student_followups_users_student_user_id", - column: x => x.student_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_memberships_tenant_id_role_template_id", - table: "tenant_memberships", - columns: new[] { "tenant_id", "role_template_id" }); - - migrationBuilder.CreateIndex( - name: "ix_auth_login_events_tenant_id_user_id_created_at", - table: "auth_login_events", - columns: new[] { "tenant_id", "user_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_auth_login_events_user_id", - table: "auth_login_events", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_auth_sessions_tenant_id_user_id_expires_at", - table: "auth_sessions", - columns: new[] { "tenant_id", "user_id", "expires_at" }, - filter: "revoked_at is null"); - - migrationBuilder.CreateIndex( - name: "ix_auth_sessions_token_hash", - table: "auth_sessions", - column: "token_hash", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_auth_sessions_user_id", - table: "auth_sessions", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_sms_send_rate_limits_updated_at", - table: "sms_send_rate_limits", - column: "updated_at"); - - migrationBuilder.CreateIndex( - name: "ix_sms_verification_codes_tenant_id_phone_purpose", - table: "sms_verification_codes", - columns: new[] { "tenant_id", "phone", "purpose" }, - unique: true, - filter: "consumed_at is null and status in ('pending', 'sent')"); - - migrationBuilder.CreateIndex( - name: "ix_sms_verification_codes_tenant_id_phone_purpose_created_at", - table: "sms_verification_codes", - columns: new[] { "tenant_id", "phone", "purpose", "created_at" }, - filter: "consumed_at is null and status in ('pending', 'sent')"); - - migrationBuilder.CreateIndex( - name: "ix_sms_verification_codes_tenant_id_phone_purpose_expires_at", - table: "sms_verification_codes", - columns: new[] { "tenant_id", "phone", "purpose", "expires_at" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_auth_providers_tenant_id_provider", - table: "tenant_auth_providers", - columns: new[] { "tenant_id", "provider" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_auth_providers_tenant_id_provider_status", - table: "tenant_auth_providers", - columns: new[] { "tenant_id", "provider", "status" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_class_members_tenant_id_class_id_status_member_type", - table: "tenant_class_members", - columns: new[] { "tenant_id", "class_id", "status", "member_type" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_class_members_tenant_id_class_id_user_id_member_type", - table: "tenant_class_members", - columns: new[] { "tenant_id", "class_id", "user_id", "member_type" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_class_members_tenant_id_user_id_status_member_type", - table: "tenant_class_members", - columns: new[] { "tenant_id", "user_id", "status", "member_type" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_class_members_user_id", - table: "tenant_class_members", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_classes_created_by", - table: "tenant_classes", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_classes_tenant_id_code", - table: "tenant_classes", - columns: new[] { "tenant_id", "code" }, - unique: true, - filter: "code is not null and code <> ''"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_classes_tenant_id_legacy_id", - table: "tenant_classes", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_classes_tenant_id_region_id", - table: "tenant_classes", - columns: new[] { "tenant_id", "region_id" }, - filter: "region_id is not null"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_classes_tenant_id_status_sort_order_created_at", - table: "tenant_classes", - columns: new[] { "tenant_id", "status", "sort_order", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_classes_updated_by", - table: "tenant_classes", - column: "updated_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_role_templates_created_by", - table: "tenant_role_templates", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_role_templates_tenant_id_code", - table: "tenant_role_templates", - columns: new[] { "tenant_id", "code" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_role_templates_tenant_id_status_sort_order", - table: "tenant_role_templates", - columns: new[] { "tenant_id", "status", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_role_templates_updated_by", - table: "tenant_role_templates", - column: "updated_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_student_followups_assigned_to_user_id", - table: "tenant_student_followups", - column: "assigned_to_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_student_followups_completed_by", - table: "tenant_student_followups", - column: "completed_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_student_followups_student_user_id", - table: "tenant_student_followups", - column: "student_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_student_followups_tenant_id_assigned_to_user_id_stat~", - table: "tenant_student_followups", - columns: new[] { "tenant_id", "assigned_to_user_id", "status", "due_at" }, - filter: "assigned_to_user_id is not null"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_student_followups_tenant_id_class_id_status_due_at", - table: "tenant_student_followups", - columns: new[] { "tenant_id", "class_id", "status", "due_at" }, - filter: "class_id is not null"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_student_followups_tenant_id_student_user_id_status_d~", - table: "tenant_student_followups", - columns: new[] { "tenant_id", "student_user_id", "status", "due_at", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_student_notes_created_by", - table: "tenant_student_notes", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_student_notes_student_user_id", - table: "tenant_student_notes", - column: "student_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_student_notes_tenant_id_created_by_created_at", - table: "tenant_student_notes", - columns: new[] { "tenant_id", "created_by", "created_at" }, - filter: "created_by is not null"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_student_notes_tenant_id_student_user_id_is_pinned_cr~", - table: "tenant_student_notes", - columns: new[] { "tenant_id", "student_user_id", "is_pinned", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_student_notes_updated_by", - table: "tenant_student_notes", - column: "updated_by"); - - migrationBuilder.AddForeignKey( - name: "fk_tenant_memberships_tenant_role_templates_tenant_id_role_tem~", - table: "tenant_memberships", - columns: new[] { "tenant_id", "role_template_id" }, - principalTable: "tenant_role_templates", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "fk_tenant_memberships_tenant_role_templates_tenant_id_role_tem~", - table: "tenant_memberships"); - - migrationBuilder.DropTable( - name: "auth_login_events"); - - migrationBuilder.DropTable( - name: "auth_sessions"); - - migrationBuilder.DropTable( - name: "sms_send_rate_limits"); - - migrationBuilder.DropTable( - name: "sms_verification_codes"); - - migrationBuilder.DropTable( - name: "tenant_auth_providers"); - - migrationBuilder.DropTable( - name: "tenant_class_members"); - - migrationBuilder.DropTable( - name: "tenant_role_templates"); - - migrationBuilder.DropTable( - name: "tenant_student_followups"); - - migrationBuilder.DropTable( - name: "tenant_student_notes"); - - migrationBuilder.DropTable( - name: "tenant_classes"); - - migrationBuilder.DropIndex( - name: "ix_tenant_memberships_tenant_id_role_template_id", - table: "tenant_memberships"); - - migrationBuilder.DropColumn( - name: "role_template_id", - table: "tenant_memberships"); - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725213505_AddCommercePersistence.Designer.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725213505_AddCommercePersistence.Designer.cs deleted file mode 100644 index 82a73fe..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725213505_AddCommercePersistence.Designer.cs +++ /dev/null @@ -1,9654 +0,0 @@ -// -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("20260725213505_AddCommercePersistence")] - partial class AddCommercePersistence - { - /// - 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.Commerce.ActivationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AgentUserId") - .HasColumnType("uuid") - .HasColumnName("agent_user_id"); - - b.Property("BatchId") - .HasColumnType("uuid") - .HasColumnName("batch_id"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CouponCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("coupon_code"); - - b.Property("CouponRedemptionId") - .HasColumnType("uuid") - .HasColumnName("coupon_redemption_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("IsUsed") - .HasColumnType("boolean") - .HasColumnName("is_used"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("SoldTo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("sold_to"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitPriceCents") - .HasColumnType("integer") - .HasColumnName("unit_price_cents"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("used_at"); - - b.Property("UsedBy") - .HasColumnType("uuid") - .HasColumnName("used_by"); - - b.Property("UsedRegionId") - .HasColumnType("uuid") - .HasColumnName("used_region_id"); - - b.HasKey("Id") - .HasName("pk_activation_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_activation_codes_tenant_id_id"); - - b.HasIndex("AgentUserId") - .HasDatabaseName("ix_activation_codes_agent_user_id"); - - b.HasIndex("UsedBy") - .HasDatabaseName("ix_activation_codes_used_by"); - - b.HasIndex("TenantId", "BatchId") - .HasDatabaseName("ix_activation_codes_tenant_id_batch_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_activation_codes_tenant_id_code"); - - b.HasIndex("TenantId", "CouponRedemptionId") - .HasDatabaseName("ix_activation_codes_tenant_id_coupon_redemption_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_activation_codes_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UsedRegionId") - .HasDatabaseName("ix_activation_codes_tenant_id_used_region_id"); - - b.ToTable("activation_codes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CodeBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CampaignName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("campaign_name"); - - b.Property("Channel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("channel"); - - b.Property("CommissionRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("commission_rate"); - - b.Property("CostPriceCents") - .HasColumnType("integer") - .HasColumnName("cost_price_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("DefaultUnitPriceCents") - .HasColumnType("integer") - .HasColumnName("default_unit_price_cents"); - - b.Property("IssuedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("issued_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - 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.HasKey("Id") - .HasName("pk_code_batches"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_code_batches_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_code_batches_tenant_id_legacy_id"); - - b.ToTable("code_batches", null, t => - { - t.HasCheckConstraint("ck_code_batches_amounts", "default_unit_price_cents >= 0 and cost_price_cents >= 0"); - - t.HasCheckConstraint("ck_code_batches_counts", "total_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Coupon", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DiscountType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("discount_type"); - - b.Property("DiscountValue") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("discount_value"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("MaxUses") - .HasColumnType("integer") - .HasColumnName("max_uses"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("Source") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("ValidFrom") - .HasColumnType("timestamp with time zone") - .HasColumnName("valid_from"); - - b.Property("ValidTo") - .HasColumnType("timestamp with time zone") - .HasColumnName("valid_to"); - - b.HasKey("Id") - .HasName("pk_coupons"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_coupons_tenant_id_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_coupons_tenant_id_code"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_coupons_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_coupons_tenant_id_plan_id"); - - b.ToTable("coupons", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CouponRedemption", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ClaimedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("claimed_at"); - - b.Property("CouponCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("coupon_code"); - - b.Property("CouponId") - .HasColumnType("uuid") - .HasColumnName("coupon_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DiscountAppliedCents") - .HasColumnType("integer") - .HasColumnName("discount_applied_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("Source") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("used_at"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_coupon_redemptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_coupon_redemptions_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_coupon_redemptions_user_id"); - - b.HasIndex("TenantId", "CouponId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_coupon_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_coupon_redemptions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_plan_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_region_id"); - - b.HasIndex("TenantId", "OrderId", "UserId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_order_id_user_id") - .HasFilter("order_id is not null"); - - b.HasIndex("TenantId", "UserId", "CouponId") - .IsUnique() - .HasDatabaseName("ix_coupon_redemptions_tenant_id_user_id_coupon_id") - .HasFilter("coupon_id is not null"); - - b.ToTable("coupon_redemptions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Entitlement", 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("EntitlementType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("entitlement_type"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("LegacySourceId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_source_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("StartsAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at") - .HasDefaultValueSql("now()"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_entitlements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_entitlements_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_entitlements_user_id"); - - b.HasIndex("TenantId", "UserId", "Status", "ExpiresAt") - .HasDatabaseName("ix_entitlements_tenant_id_user_id_status_expires_at"); - - b.ToTable("entitlements", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPlanId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_plan_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("OrderNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("order_no"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PayMethod") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("pay_method"); - - b.Property("PayProvider") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("pay_provider"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("ProductName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("product_name"); - - b.Property("ProductType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("product_type"); - - b.Property("RawPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("trade_no"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_orders"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_orders_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_orders_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_orders_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderNo") - .IsUnique() - .HasDatabaseName("ix_orders_tenant_id_order_no"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_orders_tenant_id_plan_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_orders_tenant_id_region_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_orders_tenant_id_user_id_created_at"); - - b.ToTable("orders", null, t => - { - t.HasCheckConstraint("ck_orders_amount", "amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.OrderItem", 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("ItemId") - .HasColumnType("uuid") - .HasColumnName("item_id"); - - b.Property("ItemType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("item_type"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("Quantity") - .HasColumnType("integer") - .HasColumnName("quantity"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalAmountCents") - .HasColumnType("integer") - .HasColumnName("total_amount_cents"); - - b.Property("UnitAmountCents") - .HasColumnType("integer") - .HasColumnName("unit_amount_cents"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_order_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_order_items_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_order_items_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderId") - .HasDatabaseName("ix_order_items_tenant_id_order_id"); - - b.ToTable("order_items", null, t => - { - t.HasCheckConstraint("ck_order_items_amounts", "unit_amount_cents >= 0 and total_amount_cents >= 0"); - - t.HasCheckConstraint("ck_order_items_quantity", "quantity > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Payment", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - 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("LegacyOrderId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_order_id"); - - b.Property("Method") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("method"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderTradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_trade_no"); - - b.Property("RawPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_payments"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_payments_tenant_id_id"); - - b.HasIndex("Provider", "ProviderTradeNo") - .IsUnique() - .HasDatabaseName("ix_payments_provider_provider_trade_no") - .HasFilter("provider_trade_no is not null"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_payments_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderId", "UpdatedAt") - .HasDatabaseName("ix_payments_tenant_id_order_id_updated_at"); - - b.ToTable("payments", null, t => - { - t.HasCheckConstraint("ck_payments_amount", "amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.PaymentEvent", 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("Error") - .HasColumnType("text") - .HasColumnName("error"); - - b.Property("EventId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("event_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("Payload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("ProcessedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("processed_at"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("SignatureValid") - .HasColumnType("boolean") - .HasColumnName("signature_valid"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_payment_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_payment_events_tenant_id_id"); - - b.HasIndex("Provider", "EventId") - .IsUnique() - .HasDatabaseName("ix_payment_events_provider_event_id"); - - b.HasIndex("TenantId", "PaymentId") - .HasDatabaseName("ix_payment_events_tenant_id_payment_id"); - - b.ToTable("payment_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Product", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Cover") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cover"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DetailImages") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("detail_images") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPriceText") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("legacy_price_text"); - - b.Property("Link") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("link"); - - b.Property("PreviewIframe") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("preview_iframe"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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_products"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_products_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_products_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "Type", "SortOrder") - .HasDatabaseName("ix_products_tenant_id_region_id_type_sort_order"); - - b.ToTable("products", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.SvipPlan", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Badge") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("badge"); - - b.Property("CouponOnly") - .HasColumnType("boolean") - .HasColumnName("coupon_only"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - 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(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OriginalPriceCents") - .HasColumnType("integer") - .HasColumnName("original_price_cents"); - - b.Property("PerDayLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("per_day_label"); - - b.Property("PriceCents") - .HasColumnType("integer") - .HasColumnName("price_cents"); - - b.Property("Recommended") - .HasColumnType("boolean") - .HasColumnName("recommended"); - - 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("VpEnabled") - .HasColumnType("boolean") - .HasColumnName("vp_enabled"); - - b.Property("VpProductId") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("vp_product_id"); - - b.HasKey("Id") - .HasName("pk_svip_plans"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_svip_plans_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_svip_plans_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_svip_plans_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("svip_plans", null, t => - { - t.HasCheckConstraint("ck_svip_plans_days", "days >= 0"); - - t.HasCheckConstraint("ck_svip_plans_price", "price_cents >= 0 and (original_price_cents is null or original_price_cents >= 0)"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantPaymentAccount", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ConfigPublic") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("config_public") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_payment_accounts"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_payment_accounts_tenant_id_id"); - - b.HasIndex("TenantId", "Provider") - .IsUnique() - .HasDatabaseName("ix_tenant_payment_accounts_tenant_id_provider"); - - b.ToTable("tenant_payment_accounts", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantSubscription", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("BillingCycle") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("billing_cycle"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PlanCode") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("plan_code"); - - b.Property("StartsAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_subscriptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_subscriptions_tenant_id_id"); - - b.HasIndex("TenantId", "Status", "ExpiresAt") - .HasDatabaseName("ix_tenant_subscriptions_tenant_id_status_expires_at"); - - b.ToTable("tenant_subscriptions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantUsageRecord", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("MetricKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("metric_key"); - - b.Property("MetricValue") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)") - .HasColumnName("metric_value"); - - b.Property("PeriodEnd") - .HasColumnType("date") - .HasColumnName("period_end"); - - b.Property("PeriodStart") - .HasColumnType("date") - .HasColumnName("period_start"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_tenant_usage_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_usage_records_tenant_id_id"); - - b.HasIndex("TenantId", "MetricKey", "PeriodStart", "PeriodEnd") - .HasDatabaseName("ix_tenant_usage_records_tenant_id_metric_key_period_start_peri~"); - - b.ToTable("tenant_usage_records", (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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_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_handbook_chapters"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_chapters_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_chapters_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_subject_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_chapters_tenant_id_entry_id_content_node_id_subjec~"); - - b.ToTable("handbook_chapters", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ChapterId") - .HasColumnType("uuid") - .HasColumnName("chapter_id"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Summary") - .HasColumnType("text") - .HasColumnName("summary"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_handbook_entries"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_entries_tenant_id_id"); - - b.HasIndex("TenantId", "ChapterId") - .HasDatabaseName("ix_handbook_entries_tenant_id_chapter_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_entries_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_entries_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "ChapterId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_entries_tenant_id_entry_id_content_node_id_chapter~"); - - b.ToTable("handbook_entries", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", 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("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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - 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_handbook_subjects"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_subjects_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_subjects_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "MajorId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_major_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_school_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_subjects_tenant_id_entry_id_content_node_id_region~"); - - b.ToTable("handbook_subjects", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("CdnUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cdn_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FileName") - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("file_name"); - - 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("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.HasKey("Id") - .HasName("pk_images"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_images_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_images_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "Category", "IsPublic") - .HasDatabaseName("ix_images_tenant_id_category_is_public"); - - b.ToTable("images", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", 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("AssemblyType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assembly_type"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_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("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PassScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("pass_score"); - - b.Property("QuestionLimit") - .HasColumnType("integer") - .HasColumnName("question_limit"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Rules") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("rules") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Sections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sections") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_practice_blueprints"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_blueprints_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_practice_blueprints_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_practice_blueprints_updated_by"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_collection_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_practice_blueprints_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_region_id"); - - b.HasIndex("TenantId", "NodeId", "CollectionId", "Mode", "Status", "SortOrder") - .HasDatabaseName("ix_practice_blueprints_tenant_id_node_id_collection_id_mode_st~"); - - b.ToTable("practice_blueprints", null, t => - { - t.HasCheckConstraint("ck_practice_blueprints_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_practice_blueprints_question_limit", "question_limit is null or question_limit > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", 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("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - b.Property("CollectionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("collection_type"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Filters") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("filters") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_question_collections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collections_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_collections_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_question_collections_updated_by"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_question_collections_tenant_id_category_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_question_collections_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_collections_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_question_collections_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_collections_tenant_id_region_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_question_collections_tenant_id_subject_id"); - - b.HasIndex("TenantId", "NodeId", "Status", "SortOrder") - .HasDatabaseName("ix_question_collections_tenant_id_node_id_status_sort_order"); - - b.ToTable("question_collections", null, t => - { - t.HasCheckConstraint("ck_question_collections_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_question_collections_question_count", "question_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Required") - .HasColumnType("boolean") - .HasColumnName("required"); - - b.Property("Score") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - 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_question_collection_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collection_items_tenant_id_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_question_collection_items_tenant_id_question_id"); - - b.HasIndex("TenantId", "CollectionId", "QuestionId") - .IsUnique() - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_question_~"); - - b.HasIndex("TenantId", "CollectionId", "SectionKey", "SortOrder") - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_section_k~"); - - b.ToTable("question_collection_items", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", 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("DisplayName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Types") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("types") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_question_type_groups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_type_groups_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_type_groups_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_question_type_groups_tenant_id_subject_id_is_active_sort_or~"); - - b.ToTable("question_type_groups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", 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("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("LegacyVideoId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_video_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_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("VideoId") - .HasColumnType("uuid") - .HasColumnName("video_id"); - - b.Property("VideoType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("video_type"); - - b.HasKey("Id") - .HasName("pk_question_videos"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_videos_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "VideoId") - .HasDatabaseName("ix_question_videos_tenant_id_video_id"); - - b.HasIndex("TenantId", "QuestionId", "VideoId", "VideoType") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_question_id_video_id_video_type"); - - b.ToTable("question_videos", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("SourceSubjectId") - .HasColumnType("uuid") - .HasColumnName("source_subject_id"); - - b.Property("TargetSubjectId") - .HasColumnType("uuid") - .HasColumnName("target_subject_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Id") - .HasColumnType("uuid") - .HasColumnName("id"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacySourceSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_source_subject_id"); - - b.Property("LegacyTargetSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_target_subject_id"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at"); - - b.HasKey("TenantId", "SourceSubjectId", "TargetSubjectId") - .HasName("pk_subject_shares"); - - b.HasIndex("TenantId", "TargetSubjectId") - .HasDatabaseName("ix_subject_shares_tenant_id_target_subject_id"); - - b.ToTable("subject_shares", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", 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("FavoritedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("favorited_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Note") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.HasKey("Id") - .HasName("pk_user_word_favorites"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_favorites_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_favorites_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_favorites_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_favorites_tenant_id_user_id_word_id"); - - b.ToTable("user_word_favorites", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CorrectStreak") - .HasColumnType("integer") - .HasColumnName("correct_streak"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DueLevel") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("due_level"); - - b.Property("EaseFactor") - .ValueGeneratedOnAdd() - .HasPrecision(4, 2) - .HasColumnType("numeric(4,2)") - .HasDefaultValue(2.50m) - .HasColumnName("ease_factor"); - - b.Property("LastResult") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("last_result"); - - b.Property("LastReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_review_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NextReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_review_at"); - - b.Property("ReviewCount") - .HasColumnType("integer") - .HasColumnName("review_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_user_word_progress"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_progress_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_progress_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_progress_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_word_id"); - - b.HasIndex("TenantId", "UserId", "NextReviewAt", "Status", "DueLevel") - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_next_review_at_status_~"); - - b.ToTable("user_word_progress", null, t => - { - t.HasCheckConstraint("ck_user_word_progress_correct_streak", "correct_streak >= 0"); - - t.HasCheckConstraint("ck_user_word_progress_ease_factor", "ease_factor >= 1.30 and ease_factor <= 3.00"); - - t.HasCheckConstraint("ck_user_word_progress_review_count", "review_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("IsGeneral") - .HasColumnType("boolean") - .HasColumnName("is_general"); - - b.Property("KnowledgeTags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("knowledge_tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ThumbnailUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("thumbnail_url"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VideoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("video_url"); - - b.HasKey("Id") - .HasName("pk_video_explanations"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_video_explanations_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_video_explanations_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SourceHash") - .HasDatabaseName("ix_video_explanations_tenant_id_source_hash") - .HasFilter("source_hash is not null"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_video_explanations_tenant_id_subject_id_is_active_sort_order"); - - b.ToTable("video_explanations", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WordCount") - .HasColumnType("integer") - .HasColumnName("word_count"); - - b.HasKey("Id") - .HasName("pk_vocabulary_units"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_units_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_units_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_region_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_units_tenant_id_entry_id_content_node_id_region_~"); - - b.ToTable("vocabulary_units", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Example") - .HasColumnType("text") - .HasColumnName("example"); - - b.Property("ExampleTranslation") - .HasColumnType("text") - .HasColumnName("example_translation"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Meaning") - .HasColumnType("text") - .HasColumnName("meaning"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phonetic") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("phonetic"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitId") - .HasColumnType("uuid") - .HasColumnName("unit_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Word") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("word"); - - b.HasKey("Id") - .HasName("pk_vocabulary_words"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_words_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_words_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_words_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UnitId", "IsActive", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_vocabulary_words_tenant_id_unit_id_is_active_sort_order_cre~"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "UnitId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_words_tenant_id_entry_id_content_node_id_unit_id~"); - - b.ToTable("vocabulary_words", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", 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("LastCheckInDate") - .HasColumnType("date") - .HasColumnName("last_check_in_date"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("MasteredWordsCount") - .HasColumnType("integer") - .HasColumnName("mastered_words_count"); - - b.Property("ModuleSelections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_selections") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Progress") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("progress") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionsAnsweredToday") - .HasColumnType("integer") - .HasColumnName("questions_answered_today"); - - b.Property("RecentActivities") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("recent_activities") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SelectedMajorId") - .HasColumnType("uuid") - .HasColumnName("selected_major_id"); - - b.Property("SelectedSchoolId") - .HasColumnType("uuid") - .HasColumnName("selected_school_id"); - - b.Property("Stats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("stats") - .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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_student_profiles"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_student_profiles_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_student_profiles_user_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_student_profiles_tenant_id_region_id"); - - b.HasIndex("TenantId", "SelectedMajorId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_major_id"); - - b.HasIndex("TenantId", "SelectedSchoolId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_school_id"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_student_profiles_tenant_id_user_id"); - - b.ToTable("student_profiles", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AvatarUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("avatar_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("LastSeenAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_seen_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPasswordHash") - .HasMaxLength(512) - .HasColumnType("character varying(512)") - .HasColumnName("legacy_password_hash"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PasswordMigrationRequired") - .HasColumnType("boolean") - .HasColumnName("password_migration_required"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("PrimaryRole") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("primary_role"); - - b.Property("RawProfile") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_profile") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Score") - .HasColumnType("integer") - .HasColumnName("score"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Username") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("username"); - - b.HasKey("Id") - .HasName("pk_users"); - - b.HasIndex("Email") - .IsUnique() - .HasDatabaseName("ix_users_email"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_users_legacy_id"); - - b.HasIndex("Phone") - .IsUnique() - .HasDatabaseName("ix_users_phone"); - - b.HasIndex("Username") - .IsUnique() - .HasDatabaseName("ix_users_username"); - - b.ToTable("users", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", 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("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("OpenId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("open_id"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderSubject") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("provider_subject"); - - b.Property("SecretPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("secret_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UnionId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("union_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_identities"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_identities_user_id"); - - b.HasIndex("Provider", "ProviderSubject") - .IsUnique() - .HasDatabaseName("ix_user_identities_provider_provider_subject"); - - b.ToTable("user_identities", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("AnsweredAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("answered_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IsCorrect") - .HasColumnType("boolean") - .HasColumnName("is_correct"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("QuestionVersionId") - .HasColumnType("uuid") - .HasColumnName("question_version_id"); - - b.Property("SelectedOptions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("selected_options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_answer_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_answer_records_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_answer_records_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_answer_records_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id"); - - b.HasIndex("TenantId", "QuestionId", "QuestionVersionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id_question_version_id"); - - b.HasIndex("TenantId", "UserId", "PracticeSessionId") - .HasDatabaseName("ix_answer_records_tenant_id_user_id_practice_session_id"); - - b.ToTable("answer_records", null, t => - { - t.HasCheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActiveUsers") - .HasColumnType("integer") - .HasColumnName("active_users"); - - 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("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("NewOrders") - .HasColumnType("integer") - .HasColumnName("new_orders"); - - b.Property("NewQuestions") - .HasColumnType("integer") - .HasColumnName("new_questions"); - - b.Property("NewRevenueCents") - .HasColumnType("integer") - .HasColumnName("new_revenue_cents"); - - b.Property("NewUsers") - .HasColumnType("integer") - .HasColumnName("new_users"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_dashboard_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_dashboard_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_stat_date_region_id"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId"), false); - - b.ToTable("dashboard_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", 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("ExamAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("exam_at"); - - b.Property("ExamName") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("exam_name"); - - b.Property("ExamType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("exam_type"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("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_exam_dates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_exam_dates_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_exam_dates_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_exam_dates_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId", "ExamAt") - .HasDatabaseName("ix_exam_dates_tenant_id_school_id_exam_at"); - - b.ToTable("exam_dates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_favorite_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_favorite_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_favorite_questions_tenant_id_question_id"); - - b.ToTable("favorite_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("access_mode"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EntitlementId") - .HasColumnType("uuid") - .HasColumnName("entitlement_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("GrantedCount") - .HasColumnType("integer") - .HasColumnName("granted_count"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("Reason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("reason"); - - b.Property("RequestedCount") - .HasColumnType("integer") - .HasColumnName("requested_count"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_access_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_access_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_access_events_user_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_access_events_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_practice_access_events_tenant_id_user_id_created_at"); - - b.ToTable("practice_access_events", null, t => - { - t.HasCheckConstraint("ck_practice_access_events_consumed_free_quota", "consumed_free_quota >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_granted_count", "granted_count >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_requested_count", "requested_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", 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("FreeLimit") - .HasColumnType("integer") - .HasColumnName("free_limit"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsageDate") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasColumnName("usage_date") - .HasDefaultValueSql("current_date"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_daily_usage"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_daily_usage_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_daily_usage_user_id"); - - b.HasIndex("TenantId", "UserId", "UsageDate") - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date"); - - b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId") - .IsUnique() - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date_scope_typ~"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId"), false); - - b.ToTable("practice_daily_usage", null, t => - { - t.HasCheckConstraint("ck_practice_daily_usage_free_limit", "free_limit >= 0"); - - t.HasCheckConstraint("ck_practice_daily_usage_used_count", "used_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessEntitlementId") - .HasColumnType("uuid") - .HasColumnName("access_entitlement_id"); - - b.Property("AccessMode") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasDefaultValue("free") - .HasColumnName("access_mode"); - - b.Property("AccessSnapshot") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("access_snapshot") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("ContentNodeId") - .HasColumnType("uuid") - .HasColumnName("content_node_id"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("FinishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("finished_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at") - .HasDefaultValueSql("now()"); - - b.Property("TargetId") - .HasColumnType("uuid") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_sessions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "UserId", "Id") - .HasName("ak_practice_sessions_tenant_id_user_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_sessions_user_id"); - - b.HasIndex("TenantId", "BlueprintId") - .HasDatabaseName("ix_practice_sessions_tenant_id_blueprint_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_sessions_tenant_id_collection_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_practice_sessions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_sessions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "UserId", "StartedAt") - .HasDatabaseName("ix_practice_sessions_tenant_id_user_id_started_at"); - - b.ToTable("practice_sessions", null, t => - { - t.HasCheckConstraint("ck_practice_sessions_consumed_free_quota", "consumed_free_quota >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionResults") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_results") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionStats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("section_stats") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at"); - - b.Property("SubmittedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("submitted_at") - .HasDefaultValueSql("now()"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalQuestions") - .HasColumnType("integer") - .HasColumnName("total_questions"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.Property("WrongQuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("wrong_question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.HasKey("Id") - .HasName("pk_practice_session_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_reports_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_session_reports_user_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_session_reports_tenant_id_collection_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .IsUnique() - .HasDatabaseName("ix_practice_session_reports_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "BlueprintId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_blueprint_id_submitted_at") - .HasFilter("blueprint_id is not null"); - - b.HasIndex("TenantId", "UserId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_user_id_submitted_at"); - - b.ToTable("practice_session_reports", null, t => - { - t.HasCheckConstraint("ck_practice_session_reports_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_reports_counts", "total_questions >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_duration", "duration_seconds >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("question_type"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - b.Property("SectionName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("section_name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_practice_session_report_sections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_report_sections_tenant_id_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_practice_session~"); - - b.HasIndex("TenantId", "ReportId", "SectionKey") - .IsUnique() - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sectio~"); - - b.HasIndex("TenantId", "ReportId", "SortOrder") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sort_o~"); - - b.ToTable("practice_session_report_sections", null, t => - { - t.HasCheckConstraint("ck_practice_session_report_sections_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_report_sections_counts", "question_count >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_report_sections_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", 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("LastAccessAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_access_at"); - - b.Property("LastPracticeAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_practice_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("practice_type"); - - b.Property("Progress") - .HasColumnType("integer") - .HasColumnName("progress"); - - b.Property("TargetLegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("target_legacy_id"); - - b.Property("TargetName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("target_name"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_recent_practices"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_recent_practices_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_recent_practices_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_recent_practices_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "LastAccessAt") - .HasDatabaseName("ix_recent_practices_tenant_id_user_id_last_access_at"); - - b.ToTable("recent_practices", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attachments") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("attachments") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("Contact") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("contact"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("HandledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("handled_at"); - - b.Property("HandledBy") - .HasColumnType("uuid") - .HasColumnName("handled_by"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Resolution") - .HasColumnType("text") - .HasColumnName("resolution"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_reports_tenant_id_id"); - - b.HasIndex("HandledBy") - .HasDatabaseName("ix_reports_handled_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_reports_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_reports_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_question_id_created_at") - .HasFilter("question_id is not null"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_status_created_at"); - - b.ToTable("reports", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_report_status_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_report_status_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_report_status_events_actor_user_id"); - - b.HasIndex("TenantId", "ReportId", "CreatedAt") - .HasDatabaseName("ix_report_status_events_tenant_id_report_id_created_at"); - - b.ToTable("report_status_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CodeCount") - .HasColumnType("integer") - .HasColumnName("code_count"); - - b.Property("CodeEstimated") - .HasColumnType("integer") - .HasColumnName("code_estimated"); - - b.Property("CodeUsed") - .HasColumnType("integer") - .HasColumnName("code_used"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EstimatedRevenueCents") - .HasColumnType("integer") - .HasColumnName("estimated_revenue_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("OrderCount") - .HasColumnType("integer") - .HasColumnName("order_count"); - - b.Property("RealRevenueCents") - .HasColumnType("integer") - .HasColumnName("real_revenue_cents"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_revenue_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_revenue_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_stat_date_region_id_sale_type"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType"), false); - - b.ToTable("revenue_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BalanceAfter") - .HasColumnType("integer") - .HasColumnName("balance_after"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("IdempotencyKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("idempotency_key"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Points") - .HasColumnType("integer") - .HasColumnName("points"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_score_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_score_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_score_events_user_id"); - - b.HasIndex("TenantId", "IdempotencyKey") - .IsUnique() - .HasDatabaseName("ix_user_score_events_tenant_id_idempotency_key"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_user_score_events_tenant_id_user_id_created_at"); - - b.ToTable("user_score_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("LastWrongAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("last_wrong_at") - .HasDefaultValueSql("now()"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("WrongCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(1) - .HasColumnName("wrong_count"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_wrong_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_wrong_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_wrong_questions_tenant_id_question_id"); - - b.ToTable("wrong_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - 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("CurrentVersionId") - .HasColumnType("uuid") - .HasColumnName("current_version_id"); - - b.Property("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExamMarkers") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("exam_markers") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("HasVideoExplanation") - .HasColumnType("boolean") - .HasColumnName("has_video_explanation"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyNodeId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_node_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("MediaUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("media_url"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PrimaryCollectionId") - .HasColumnType("uuid") - .HasColumnName("primary_collection_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Type") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("type"); - - b.Property("TypeLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("type_label"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_questions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_questions_tenant_id_id"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_questions_tenant_id_category_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_questions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_questions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_questions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "NodeId") - .HasDatabaseName("ix_questions_tenant_id_node_id"); - - b.HasIndex("TenantId", "PrimaryCollectionId") - .HasDatabaseName("ix_questions_tenant_id_primary_collection_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_questions_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_questions_tenant_id_subject_id"); - - b.HasIndex("TenantId", "Id", "CurrentVersionId") - .HasDatabaseName("ix_questions_tenant_id_id_current_version_id"); - - b.ToTable("questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SourceScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_scope"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_banks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_banks_tenant_id_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_banks_tenant_id_region_id"); - - b.ToTable("question_banks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("CodeLang") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("code_lang"); - - b.Property("CodeTemplate") - .HasColumnType("text") - .HasColumnName("code_template"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CorrectOptionIndex") - .HasColumnType("integer") - .HasColumnName("correct_option_index"); - - b.Property("CorrectOptionIndices") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("correct_option_indices") - .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("Explanation") - .HasColumnType("text") - .HasColumnName("explanation"); - - b.Property("Options") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubQuestions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sub_questions") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("VersionNo") - .HasColumnType("integer") - .HasColumnName("version_no"); - - b.HasKey("Id") - .HasName("pk_question_versions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_versions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "QuestionId", "Id") - .HasName("ak_question_versions_tenant_id_question_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_versions_created_by"); - - b.HasIndex("QuestionId", "VersionNo") - .IsUnique() - .HasDatabaseName("ix_question_versions_question_id_version_no"); - - b.ToTable("question_versions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", 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("FailureCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("failure_code"); - - b.Property("Identifier") - .HasMaxLength(320) - .HasColumnType("character varying(320)") - .HasColumnName("identifier"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Result") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("result"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_login_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_login_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_login_events_user_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_auth_login_events_tenant_id_user_id_created_at"); - - b.ToTable("auth_login_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", 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("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("RevokedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("revoked_at"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TokenHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("token_hash"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_sessions_tenant_id_id"); - - b.HasIndex("TokenHash") - .IsUnique() - .HasDatabaseName("ix_auth_sessions_token_hash"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_sessions_user_id"); - - b.HasIndex("TenantId", "UserId", "ExpiresAt") - .HasDatabaseName("ix_auth_sessions_tenant_id_user_id_expires_at") - .HasFilter("revoked_at is null"); - - b.ToTable("auth_sessions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Dimension") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("dimension"); - - b.Property("ScopeHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("scope_hash"); - - b.Property("BucketStart") - .HasColumnType("timestamp with time zone") - .HasColumnName("bucket_start"); - - b.Property("RequestCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0) - .HasColumnName("request_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId", "Dimension", "ScopeHash", "BucketStart") - .HasName("pk_sms_send_rate_limits"); - - b.HasIndex("UpdatedAt") - .HasDatabaseName("ix_sms_send_rate_limits_updated_at"); - - b.ToTable("sms_send_rate_limits", null, t => - { - t.HasCheckConstraint("ck_sms_send_rate_limits_request_count", "request_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempts") - .HasColumnType("integer") - .HasColumnName("attempts"); - - b.Property("CodeHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("code_hash"); - - b.Property("ConsumedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("consumed_at"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phone") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Purpose") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("purpose"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_sms_verification_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_sms_verification_codes_tenant_id_id"); - - b.HasIndex("TenantId", "Phone", "Purpose") - .IsUnique() - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "CreatedAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_created_at") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "ExpiresAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_expires_at"); - - b.ToTable("sms_verification_codes", null, t => - { - t.HasCheckConstraint("ck_sms_verification_codes_attempts", "attempts >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BillingStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("billing_status"); - - 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("LegalName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("legal_name"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OwnerUserId") - .HasColumnType("uuid") - .HasColumnName("owner_user_id"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("slug"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenants"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenants_legacy_id"); - - b.HasIndex("OwnerUserId") - .HasDatabaseName("ix_tenants_owner_user_id"); - - b.HasIndex("Slug") - .IsUnique() - .HasDatabaseName("ix_tenants_slug"); - - b.ToTable("tenants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ConfigPublic") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("config_public") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_auth_providers"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_auth_providers_tenant_id_id"); - - b.HasIndex("TenantId", "Provider") - .IsUnique() - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider"); - - b.HasIndex("TenantId", "Provider", "Status") - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider_status"); - - b.ToTable("tenant_auth_providers", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("BrandName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("brand_name"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FaviconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("favicon_url"); - - b.Property("LogoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("logo_url"); - - b.Property("OrganizationName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("organization_name"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ServiceAccountName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("service_account_name"); - - b.Property("ServiceWechat") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("service_wechat"); - - b.Property("ShortName") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("short_name"); - - b.Property("Slogan") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("slogan"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_branding"); - - b.ToTable("tenant_branding", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Code") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("code"); - - 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("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_classes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_classes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_classes_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_classes_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_code") - .HasFilter("code is not null and code <> ''"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_tenant_classes_tenant_id_region_id") - .HasFilter("region_id is not null"); - - b.HasIndex("TenantId", "Status", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_tenant_classes_tenant_id_status_sort_order_created_at"); - - b.ToTable("tenant_classes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_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("JoinedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("joined_at") - .HasDefaultValueSql("now()"); - - b.Property("LeftAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("left_at"); - - b.Property("MemberType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("member_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_class_members"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_class_members_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_class_members_user_id"); - - b.HasIndex("TenantId", "ClassId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_status_member_type"); - - b.HasIndex("TenantId", "ClassId", "UserId", "MemberType") - .IsUnique() - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_user_id_member_type"); - - b.HasIndex("TenantId", "UserId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_user_id_status_member_type"); - - b.ToTable("tenant_class_members", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", 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("DomainType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("domain_type"); - - b.Property("Host") - .IsRequired() - .HasMaxLength(253) - .HasColumnType("citext") - .HasColumnName("host"); - - b.Property("IsPrimary") - .HasColumnType("boolean") - .HasColumnName("is_primary"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VerificationToken") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("verification_token"); - - b.Property("VerifiedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("verified_at"); - - b.HasKey("Id") - .HasName("pk_tenant_domains"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_domains_tenant_id_id"); - - b.HasIndex("Host") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_host"); - - b.HasIndex("TenantId", "IsPrimary") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_tenant_id_is_primary") - .HasFilter("is_primary"); - - b.ToTable("tenant_domains", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", 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("LegacyRole") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("legacy_role"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Role") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("role"); - - b.Property("RoleTemplateId") - .HasColumnType("uuid") - .HasColumnName("role_template_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_memberships"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_memberships_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_memberships_user_id"); - - b.HasIndex("TenantId", "RoleTemplateId") - .HasDatabaseName("ix_tenant_memberships_tenant_id_role_template_id"); - - b.HasIndex("TenantId", "UserId", "Role") - .IsUnique() - .HasDatabaseName("ix_tenant_memberships_tenant_id_user_id_role"); - - b.ToTable("tenant_memberships", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BaseRole") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("base_role"); - - 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("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DataScope") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("data_scope") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("FieldPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("field_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("IsSystem") - .HasColumnType("boolean") - .HasColumnName("is_system"); - - b.Property("MenuPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("menu_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ModulePermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_role_templates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_role_templates_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_role_templates_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_role_templates_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_role_templates_tenant_id_code"); - - b.HasIndex("TenantId", "Status", "SortOrder") - .HasDatabaseName("ix_tenant_role_templates_tenant_id_status_sort_order"); - - b.ToTable("tenant_role_templates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("AdminFeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("admin_feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PublicConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_settings"); - - b.ToTable("tenant_settings", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignedToUserId") - .HasColumnType("uuid") - .HasColumnName("assigned_to_user_id"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_id"); - - b.Property("CompletedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("completed_at"); - - b.Property("CompletedBy") - .HasColumnType("uuid") - .HasColumnName("completed_by"); - - 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("DueAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("due_at"); - - b.Property("FollowupType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("followup_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .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.HasKey("Id") - .HasName("pk_tenant_student_followups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_followups_tenant_id_id"); - - b.HasIndex("AssignedToUserId") - .HasDatabaseName("ix_tenant_student_followups_assigned_to_user_id"); - - b.HasIndex("CompletedBy") - .HasDatabaseName("ix_tenant_student_followups_completed_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_followups_student_user_id"); - - b.HasIndex("TenantId", "AssignedToUserId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_assigned_to_user_id_stat~") - .HasFilter("assigned_to_user_id is not null"); - - b.HasIndex("TenantId", "ClassId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_class_id_status_due_at") - .HasFilter("class_id is not null"); - - b.HasIndex("TenantId", "StudentUserId", "Status", "DueAt", "CreatedAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_student_user_id_status_d~"); - - b.ToTable("tenant_student_followups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Content") - .IsRequired() - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("IsPinned") - .HasColumnType("boolean") - .HasColumnName("is_pinned"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NoteType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("note_type"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - 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_tenant_student_notes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_notes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_student_notes_created_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_notes_student_user_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_student_notes_updated_by"); - - b.HasIndex("TenantId", "CreatedBy", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_created_by_created_at") - .HasFilter("created_by is not null"); - - b.HasIndex("TenantId", "StudentUserId", "IsPinned", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_student_user_id_is_pinned_cr~"); - - b.ToTable("tenant_student_notes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Category", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_categories_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Major", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_majors_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.ModuleNode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_module_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_module_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Region", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_regions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.RegionModule", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_region_modules_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_region_modules_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.School", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_schools_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Subject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.ActivationCode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AgentUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_users_agent_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_activation_codes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UsedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_users_used_by"); - - b.HasOne("Tiku.Domain.Commerce.CodeBatch", null) - .WithMany() - .HasForeignKey("TenantId", "BatchId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_code_batches_tenant_id_batch_id"); - - b.HasOne("Tiku.Domain.Commerce.CouponRedemption", null) - .WithMany() - .HasForeignKey("TenantId", "CouponRedemptionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_coupon_redemptions_tenant_id_coupon_redemp~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "UsedRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_regions_tenant_id_used_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CodeBatch", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_code_batches_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Coupon", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_coupons_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_coupons_svip_plans_tenant_id_plan_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CouponRedemption", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_coupon_redemptions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_users_user_id"); - - b.HasOne("Tiku.Domain.Commerce.Coupon", null) - .WithMany() - .HasForeignKey("TenantId", "CouponId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_coupons_tenant_id_coupon_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_svip_plans_tenant_id_plan_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Entitlement", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_entitlements_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_entitlements_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Order", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_orders_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_orders_users_user_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_orders_svip_plans_tenant_id_plan_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_orders_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.OrderItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_order_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_order_items_orders_tenant_id_order_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Payment", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payments_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payments_orders_tenant_id_order_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.PaymentEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payment_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_payment_events_payments_tenant_id_payment_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Product", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_products_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_products_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.SvipPlan", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_svip_plans_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_svip_plans_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantPaymentAccount", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_payment_accounts_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantSubscription", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_subscriptions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantUsageRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_usage_records_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.AppAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_app_assets_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAsset", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_assets_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_updated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("VerifiedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_verified_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentEntry", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_entries_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportIssue", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportItem", null) - .WithMany() - .HasForeignKey("TenantId", "ItemId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_import_issues_content_import_items_tenant_id_item_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportJob", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_import_jobs_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_jobs_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "TargetCategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_categories_tenant_id_target_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "TargetContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_content_nodes_tenant_id_target_content_~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "TargetQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_question_banks_tenant_id_target_questio~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "TargetRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_regions_tenant_id_target_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentNode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_nodes_content_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookChapter", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_chapters_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.HandbookSubject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_chapters_handbook_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.HandbookChapter", null) - .WithMany() - .HasForeignKey("TenantId", "ChapterId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_entries_handbook_chapters_tenant_id_chapter_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_images_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_blueprints_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_question_collections_tenant_id_collecti~"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_question_banks_tenant_id_question_bank~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_question_collections_tenant_id_co~"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_type_groups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_type_groups_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_videos_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.Content.VideoExplanation", null) - .WithMany() - .HasForeignKey("TenantId", "VideoId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_video_explanations_tenant_id_video_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SourceSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_source_subject_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_video_explanations_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_video_explanations_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_units_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_words_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyUnit", null) - .WithMany() - .HasForeignKey("TenantId", "UnitId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_vocabulary_units_tenant_id_unit_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedMajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_majors_tenant_id_selected_major_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedSchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_schools_tenant_id_selected_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_identities_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId", "QuestionVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_question_versions_tenant_id_question_id_ques~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "UserId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "UserId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_practice_sessions_tenant_id_user_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_dashboard_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_dashboard_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_exam_dates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_access_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_users_user_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_practice_sessions_tenant_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_question_collections_tenant_id_collection~"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_practice_blueprints_tenant_id_blue~"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_question_collections_tenant_id_col~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_practice_sessions_tenant_id_practi~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_sessions_tenant_i~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSessionReport", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_session_reports_t~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_recent_practices_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_recent_practices_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("HandledBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_handled_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_reports_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_report_status_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.Report", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_reports_tenant_id_report_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_revenue_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_revenue_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "PrimaryCollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_collections_tenant_id_primary_collection~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_banks_tenant_id_question_bank_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_subjects_tenant_id_subject_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "Id", "CurrentVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_versions_tenant_id_id_current_version_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_banks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_banks_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_versions_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_versions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_login_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_auth_login_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_send_rate_limits_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_verification_codes_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("OwnerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenants_users_owner_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_auth_providers_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantBranding", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_branding_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_classes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_classes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_domains_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantRoleTemplate", null) - .WithMany() - .HasForeignKey("TenantId", "RoleTemplateId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_memberships_tenant_role_templates_tenant_id_role_tem~"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_role_templates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantSettings", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_settings_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedToUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_assigned_to_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CompletedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_completed_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_updated_by"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725213505_AddCommercePersistence.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725213505_AddCommercePersistence.cs deleted file mode 100644 index 8f38fdd..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725213505_AddCommercePersistence.cs +++ /dev/null @@ -1,853 +0,0 @@ -using System; -using System.Text.Json; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Tiku.Infrastructure.Persistence.Migrations -{ - /// - public partial class AddCommercePersistence : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "code_batches", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - created_by = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - sale_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - channel = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - campaign_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - default_unit_price_cents = table.Column(type: "integer", nullable: false), - cost_price_cents = table.Column(type: "integer", nullable: false), - total_count = table.Column(type: "integer", nullable: false), - days = table.Column(type: "integer", nullable: true), - legacy_region_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - issued_at = table.Column(type: "timestamp with time zone", nullable: true), - remark = table.Column(type: "text", nullable: true), - commission_rate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_code_batches", x => x.id); - table.UniqueConstraint("ak_code_batches_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_code_batches_amounts", "default_unit_price_cents >= 0 and cost_price_cents >= 0"); - table.CheckConstraint("ck_code_batches_counts", "total_count >= 0"); - table.ForeignKey( - name: "fk_code_batches_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "entitlements", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - user_id = table.Column(type: "uuid", nullable: false), - entitlement_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - scope_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - scope_id = table.Column(type: "uuid", nullable: true), - source_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - source_id = table.Column(type: "uuid", nullable: true), - legacy_source_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - starts_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - expires_at = table.Column(type: "timestamp with time zone", nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_entitlements", x => x.id); - table.UniqueConstraint("ak_entitlements_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_entitlements_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_entitlements_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "products", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - title = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - legacy_price_text = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - link = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - tags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - sort_order = table.Column(type: "integer", nullable: false), - cover = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - preview_iframe = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - detail_images = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_products", x => x.id); - table.UniqueConstraint("ak_products_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_products_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_products_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "svip_plans", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - price_cents = table.Column(type: "integer", nullable: false), - original_price_cents = table.Column(type: "integer", nullable: true), - days = table.Column(type: "integer", nullable: false), - description = table.Column(type: "text", nullable: true), - per_day_label = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - badge = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - recommended = table.Column(type: "boolean", nullable: false), - coupon_only = table.Column(type: "boolean", nullable: false), - vp_product_id = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - vp_enabled = table.Column(type: "boolean", nullable: false), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_svip_plans", x => x.id); - table.UniqueConstraint("ak_svip_plans_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_svip_plans_days", "days >= 0"); - table.CheckConstraint("ck_svip_plans_price", "price_cents >= 0 and (original_price_cents is null or original_price_cents >= 0)"); - table.ForeignKey( - name: "fk_svip_plans_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_svip_plans_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_payment_accounts", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - display_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - config_public = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_payment_accounts", x => x.id); - table.UniqueConstraint("ak_tenant_payment_accounts_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_tenant_payment_accounts_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_subscriptions", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - plan_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - starts_at = table.Column(type: "timestamp with time zone", nullable: true), - expires_at = table.Column(type: "timestamp with time zone", nullable: true), - billing_cycle = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - amount_cents = table.Column(type: "integer", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_subscriptions", x => x.id); - table.UniqueConstraint("ak_tenant_subscriptions_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_tenant_subscriptions_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_usage_records", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - metric_key = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - metric_value = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), - period_start = table.Column(type: "date", nullable: false), - period_end = table.Column(type: "date", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_usage_records", x => x.id); - table.UniqueConstraint("ak_tenant_usage_records_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_tenant_usage_records_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "coupons", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - plan_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - code = table.Column(type: "citext", maxLength: 100, nullable: false), - discount_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - discount_value = table.Column(type: "numeric(10,2)", precision: 10, scale: 2, nullable: true), - valid_from = table.Column(type: "timestamp with time zone", nullable: true), - valid_to = table.Column(type: "timestamp with time zone", nullable: true), - max_uses = table.Column(type: "integer", nullable: true), - used_count = table.Column(type: "integer", nullable: false), - source = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - remark = table.Column(type: "text", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_coupons", x => x.id); - table.UniqueConstraint("ak_coupons_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_coupons_svip_plans_tenant_id_plan_id", - columns: x => new { x.tenant_id, x.plan_id }, - principalTable: "svip_plans", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_coupons_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "orders", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: true), - plan_id = table.Column(type: "uuid", nullable: true), - region_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_user_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_plan_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_region_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - order_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - product_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - product_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - amount_cents = table.Column(type: "integer", nullable: false), - pay_method = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - pay_provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - trade_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - days = table.Column(type: "integer", nullable: true), - paid_at = table.Column(type: "timestamp with time zone", nullable: true), - raw_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_orders", x => x.id); - table.UniqueConstraint("ak_orders_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_orders_amount", "amount_cents >= 0"); - table.ForeignKey( - name: "fk_orders_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_orders_svip_plans_tenant_id_plan_id", - columns: x => new { x.tenant_id, x.plan_id }, - principalTable: "svip_plans", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_orders_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_orders_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "coupon_redemptions", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - coupon_id = table.Column(type: "uuid", nullable: true), - user_id = table.Column(type: "uuid", nullable: true), - plan_id = table.Column(type: "uuid", nullable: true), - order_id = table.Column(type: "uuid", nullable: true), - region_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - coupon_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - discount_applied_cents = table.Column(type: "integer", nullable: true), - source = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - remark = table.Column(type: "text", nullable: true), - claimed_at = table.Column(type: "timestamp with time zone", nullable: true), - used_at = table.Column(type: "timestamp with time zone", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_coupon_redemptions", x => x.id); - table.UniqueConstraint("ak_coupon_redemptions_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_coupon_redemptions_coupons_tenant_id_coupon_id", - columns: x => new { x.tenant_id, x.coupon_id }, - principalTable: "coupons", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_coupon_redemptions_orders_tenant_id_order_id", - columns: x => new { x.tenant_id, x.order_id }, - principalTable: "orders", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_coupon_redemptions_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_coupon_redemptions_svip_plans_tenant_id_plan_id", - columns: x => new { x.tenant_id, x.plan_id }, - principalTable: "svip_plans", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_coupon_redemptions_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_coupon_redemptions_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "order_items", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - order_id = table.Column(type: "uuid", nullable: false), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - item_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - item_id = table.Column(type: "uuid", nullable: true), - name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - quantity = table.Column(type: "integer", nullable: false), - unit_amount_cents = table.Column(type: "integer", nullable: false), - total_amount_cents = table.Column(type: "integer", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_order_items", x => x.id); - table.UniqueConstraint("ak_order_items_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_order_items_amounts", "unit_amount_cents >= 0 and total_amount_cents >= 0"); - table.CheckConstraint("ck_order_items_quantity", "quantity > 0"); - table.ForeignKey( - name: "fk_order_items_orders_tenant_id_order_id", - columns: x => new { x.tenant_id, x.order_id }, - principalTable: "orders", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_order_items_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "payments", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - order_id = table.Column(type: "uuid", nullable: false), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - legacy_order_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - method = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - amount_cents = table.Column(type: "integer", nullable: false), - provider_trade_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - paid_at = table.Column(type: "timestamp with time zone", nullable: true), - raw_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_payments", x => x.id); - table.UniqueConstraint("ak_payments_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_payments_amount", "amount_cents >= 0"); - table.ForeignKey( - name: "fk_payments_orders_tenant_id_order_id", - columns: x => new { x.tenant_id, x.order_id }, - principalTable: "orders", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_payments_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "activation_codes", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - used_by = table.Column(type: "uuid", nullable: true), - agent_user_id = table.Column(type: "uuid", nullable: true), - batch_id = table.Column(type: "uuid", nullable: true), - used_region_id = table.Column(type: "uuid", nullable: true), - coupon_redemption_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - code = table.Column(type: "citext", maxLength: 100, nullable: false), - days = table.Column(type: "integer", nullable: false), - is_used = table.Column(type: "boolean", nullable: false), - used_at = table.Column(type: "timestamp with time zone", nullable: true), - sale_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - unit_price_cents = table.Column(type: "integer", nullable: true), - sold_to = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - coupon_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - remark = table.Column(type: "text", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_activation_codes", x => x.id); - table.UniqueConstraint("ak_activation_codes_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_activation_codes_code_batches_tenant_id_batch_id", - columns: x => new { x.tenant_id, x.batch_id }, - principalTable: "code_batches", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_activation_codes_coupon_redemptions_tenant_id_coupon_redemp~", - columns: x => new { x.tenant_id, x.coupon_redemption_id }, - principalTable: "coupon_redemptions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_activation_codes_regions_tenant_id_used_region_id", - columns: x => new { x.tenant_id, x.used_region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_activation_codes_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_activation_codes_users_agent_user_id", - column: x => x.agent_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_activation_codes_users_used_by", - column: x => x.used_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "payment_events", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - payment_id = table.Column(type: "uuid", nullable: true), - provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - event_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - event_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - signature_valid = table.Column(type: "boolean", nullable: true), - payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - processed_at = table.Column(type: "timestamp with time zone", nullable: true), - error = table.Column(type: "text", nullable: true), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_payment_events", x => x.id); - table.UniqueConstraint("ak_payment_events_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_payment_events_payments_tenant_id_payment_id", - columns: x => new { x.tenant_id, x.payment_id }, - principalTable: "payments", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_payment_events_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "ix_activation_codes_agent_user_id", - table: "activation_codes", - column: "agent_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_activation_codes_tenant_id_batch_id", - table: "activation_codes", - columns: new[] { "tenant_id", "batch_id" }); - - migrationBuilder.CreateIndex( - name: "ix_activation_codes_tenant_id_code", - table: "activation_codes", - columns: new[] { "tenant_id", "code" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_activation_codes_tenant_id_coupon_redemption_id", - table: "activation_codes", - columns: new[] { "tenant_id", "coupon_redemption_id" }); - - migrationBuilder.CreateIndex( - name: "ix_activation_codes_tenant_id_legacy_id", - table: "activation_codes", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_activation_codes_tenant_id_used_region_id", - table: "activation_codes", - columns: new[] { "tenant_id", "used_region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_activation_codes_used_by", - table: "activation_codes", - column: "used_by"); - - migrationBuilder.CreateIndex( - name: "ix_code_batches_tenant_id_legacy_id", - table: "code_batches", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_coupon_redemptions_tenant_id_coupon_id", - table: "coupon_redemptions", - columns: new[] { "tenant_id", "coupon_id" }); - - migrationBuilder.CreateIndex( - name: "ix_coupon_redemptions_tenant_id_legacy_id", - table: "coupon_redemptions", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_coupon_redemptions_tenant_id_order_id_user_id", - table: "coupon_redemptions", - columns: new[] { "tenant_id", "order_id", "user_id" }, - filter: "order_id is not null"); - - migrationBuilder.CreateIndex( - name: "ix_coupon_redemptions_tenant_id_plan_id", - table: "coupon_redemptions", - columns: new[] { "tenant_id", "plan_id" }); - - migrationBuilder.CreateIndex( - name: "ix_coupon_redemptions_tenant_id_region_id", - table: "coupon_redemptions", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_coupon_redemptions_tenant_id_user_id_coupon_id", - table: "coupon_redemptions", - columns: new[] { "tenant_id", "user_id", "coupon_id" }, - unique: true, - filter: "coupon_id is not null"); - - migrationBuilder.CreateIndex( - name: "ix_coupon_redemptions_user_id", - table: "coupon_redemptions", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_coupons_tenant_id_code", - table: "coupons", - columns: new[] { "tenant_id", "code" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_coupons_tenant_id_legacy_id", - table: "coupons", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_coupons_tenant_id_plan_id", - table: "coupons", - columns: new[] { "tenant_id", "plan_id" }); - - migrationBuilder.CreateIndex( - name: "ix_entitlements_tenant_id_user_id_status_expires_at", - table: "entitlements", - columns: new[] { "tenant_id", "user_id", "status", "expires_at" }); - - migrationBuilder.CreateIndex( - name: "ix_entitlements_user_id", - table: "entitlements", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_order_items_tenant_id_legacy_id", - table: "order_items", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_order_items_tenant_id_order_id", - table: "order_items", - columns: new[] { "tenant_id", "order_id" }); - - migrationBuilder.CreateIndex( - name: "ix_orders_tenant_id_legacy_id", - table: "orders", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_orders_tenant_id_order_no", - table: "orders", - columns: new[] { "tenant_id", "order_no" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_orders_tenant_id_plan_id", - table: "orders", - columns: new[] { "tenant_id", "plan_id" }); - - migrationBuilder.CreateIndex( - name: "ix_orders_tenant_id_region_id", - table: "orders", - columns: new[] { "tenant_id", "region_id" }); - - migrationBuilder.CreateIndex( - name: "ix_orders_tenant_id_user_id_created_at", - table: "orders", - columns: new[] { "tenant_id", "user_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_orders_user_id", - table: "orders", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_payment_events_provider_event_id", - table: "payment_events", - columns: new[] { "provider", "event_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_payment_events_tenant_id_payment_id", - table: "payment_events", - columns: new[] { "tenant_id", "payment_id" }); - - migrationBuilder.CreateIndex( - name: "ix_payments_provider_provider_trade_no", - table: "payments", - columns: new[] { "provider", "provider_trade_no" }, - unique: true, - filter: "provider_trade_no is not null"); - - migrationBuilder.CreateIndex( - name: "ix_payments_tenant_id_legacy_id", - table: "payments", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_payments_tenant_id_order_id_updated_at", - table: "payments", - columns: new[] { "tenant_id", "order_id", "updated_at" }); - - migrationBuilder.CreateIndex( - name: "ix_products_tenant_id_legacy_id", - table: "products", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_products_tenant_id_region_id_type_sort_order", - table: "products", - columns: new[] { "tenant_id", "region_id", "type", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_svip_plans_tenant_id_legacy_id", - table: "svip_plans", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_svip_plans_tenant_id_region_id_is_active_sort_order", - table: "svip_plans", - columns: new[] { "tenant_id", "region_id", "is_active", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_payment_accounts_tenant_id_provider", - table: "tenant_payment_accounts", - columns: new[] { "tenant_id", "provider" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_subscriptions_tenant_id_status_expires_at", - table: "tenant_subscriptions", - columns: new[] { "tenant_id", "status", "expires_at" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_usage_records_tenant_id_metric_key_period_start_peri~", - table: "tenant_usage_records", - columns: new[] { "tenant_id", "metric_key", "period_start", "period_end" }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "activation_codes"); - - migrationBuilder.DropTable( - name: "entitlements"); - - migrationBuilder.DropTable( - name: "order_items"); - - migrationBuilder.DropTable( - name: "payment_events"); - - migrationBuilder.DropTable( - name: "products"); - - migrationBuilder.DropTable( - name: "tenant_payment_accounts"); - - migrationBuilder.DropTable( - name: "tenant_subscriptions"); - - migrationBuilder.DropTable( - name: "tenant_usage_records"); - - migrationBuilder.DropTable( - name: "code_batches"); - - migrationBuilder.DropTable( - name: "coupon_redemptions"); - - migrationBuilder.DropTable( - name: "payments"); - - migrationBuilder.DropTable( - name: "coupons"); - - migrationBuilder.DropTable( - name: "orders"); - - migrationBuilder.DropTable( - name: "svip_plans"); - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725214048_AddReferralCrmAndCommissionPersistence.Designer.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725214048_AddReferralCrmAndCommissionPersistence.Designer.cs deleted file mode 100644 index 64ac0b8..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725214048_AddReferralCrmAndCommissionPersistence.Designer.cs +++ /dev/null @@ -1,11024 +0,0 @@ -// -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("20260725214048_AddReferralCrmAndCommissionPersistence")] - partial class AddReferralCrmAndCommissionPersistence - { - /// - 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.Commerce.ActivationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AgentUserId") - .HasColumnType("uuid") - .HasColumnName("agent_user_id"); - - b.Property("BatchId") - .HasColumnType("uuid") - .HasColumnName("batch_id"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CouponCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("coupon_code"); - - b.Property("CouponRedemptionId") - .HasColumnType("uuid") - .HasColumnName("coupon_redemption_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("IsUsed") - .HasColumnType("boolean") - .HasColumnName("is_used"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("SoldTo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("sold_to"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitPriceCents") - .HasColumnType("integer") - .HasColumnName("unit_price_cents"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("used_at"); - - b.Property("UsedBy") - .HasColumnType("uuid") - .HasColumnName("used_by"); - - b.Property("UsedRegionId") - .HasColumnType("uuid") - .HasColumnName("used_region_id"); - - b.HasKey("Id") - .HasName("pk_activation_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_activation_codes_tenant_id_id"); - - b.HasIndex("AgentUserId") - .HasDatabaseName("ix_activation_codes_agent_user_id"); - - b.HasIndex("UsedBy") - .HasDatabaseName("ix_activation_codes_used_by"); - - b.HasIndex("TenantId", "BatchId") - .HasDatabaseName("ix_activation_codes_tenant_id_batch_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_activation_codes_tenant_id_code"); - - b.HasIndex("TenantId", "CouponRedemptionId") - .HasDatabaseName("ix_activation_codes_tenant_id_coupon_redemption_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_activation_codes_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UsedRegionId") - .HasDatabaseName("ix_activation_codes_tenant_id_used_region_id"); - - b.ToTable("activation_codes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CodeBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CampaignName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("campaign_name"); - - b.Property("Channel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("channel"); - - b.Property("CommissionRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("commission_rate"); - - b.Property("CostPriceCents") - .HasColumnType("integer") - .HasColumnName("cost_price_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("DefaultUnitPriceCents") - .HasColumnType("integer") - .HasColumnName("default_unit_price_cents"); - - b.Property("IssuedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("issued_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - 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.HasKey("Id") - .HasName("pk_code_batches"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_code_batches_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_code_batches_tenant_id_legacy_id"); - - b.ToTable("code_batches", null, t => - { - t.HasCheckConstraint("ck_code_batches_amounts", "default_unit_price_cents >= 0 and cost_price_cents >= 0"); - - t.HasCheckConstraint("ck_code_batches_counts", "total_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Coupon", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DiscountType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("discount_type"); - - b.Property("DiscountValue") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("discount_value"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("MaxUses") - .HasColumnType("integer") - .HasColumnName("max_uses"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("Source") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("ValidFrom") - .HasColumnType("timestamp with time zone") - .HasColumnName("valid_from"); - - b.Property("ValidTo") - .HasColumnType("timestamp with time zone") - .HasColumnName("valid_to"); - - b.HasKey("Id") - .HasName("pk_coupons"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_coupons_tenant_id_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_coupons_tenant_id_code"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_coupons_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_coupons_tenant_id_plan_id"); - - b.ToTable("coupons", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CouponRedemption", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ClaimedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("claimed_at"); - - b.Property("CouponCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("coupon_code"); - - b.Property("CouponId") - .HasColumnType("uuid") - .HasColumnName("coupon_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DiscountAppliedCents") - .HasColumnType("integer") - .HasColumnName("discount_applied_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("Source") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("used_at"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_coupon_redemptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_coupon_redemptions_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_coupon_redemptions_user_id"); - - b.HasIndex("TenantId", "CouponId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_coupon_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_coupon_redemptions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_plan_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_region_id"); - - b.HasIndex("TenantId", "OrderId", "UserId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_order_id_user_id") - .HasFilter("order_id is not null"); - - b.HasIndex("TenantId", "UserId", "CouponId") - .IsUnique() - .HasDatabaseName("ix_coupon_redemptions_tenant_id_user_id_coupon_id") - .HasFilter("coupon_id is not null"); - - b.ToTable("coupon_redemptions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Entitlement", 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("EntitlementType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("entitlement_type"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("LegacySourceId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_source_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("StartsAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at") - .HasDefaultValueSql("now()"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_entitlements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_entitlements_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_entitlements_user_id"); - - b.HasIndex("TenantId", "UserId", "Status", "ExpiresAt") - .HasDatabaseName("ix_entitlements_tenant_id_user_id_status_expires_at"); - - b.ToTable("entitlements", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPlanId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_plan_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("OrderNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("order_no"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PayMethod") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("pay_method"); - - b.Property("PayProvider") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("pay_provider"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("ProductName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("product_name"); - - b.Property("ProductType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("product_type"); - - b.Property("RawPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("trade_no"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_orders"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_orders_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_orders_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_orders_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderNo") - .IsUnique() - .HasDatabaseName("ix_orders_tenant_id_order_no"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_orders_tenant_id_plan_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_orders_tenant_id_region_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_orders_tenant_id_user_id_created_at"); - - b.ToTable("orders", null, t => - { - t.HasCheckConstraint("ck_orders_amount", "amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.OrderItem", 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("ItemId") - .HasColumnType("uuid") - .HasColumnName("item_id"); - - b.Property("ItemType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("item_type"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("Quantity") - .HasColumnType("integer") - .HasColumnName("quantity"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalAmountCents") - .HasColumnType("integer") - .HasColumnName("total_amount_cents"); - - b.Property("UnitAmountCents") - .HasColumnType("integer") - .HasColumnName("unit_amount_cents"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_order_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_order_items_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_order_items_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderId") - .HasDatabaseName("ix_order_items_tenant_id_order_id"); - - b.ToTable("order_items", null, t => - { - t.HasCheckConstraint("ck_order_items_amounts", "unit_amount_cents >= 0 and total_amount_cents >= 0"); - - t.HasCheckConstraint("ck_order_items_quantity", "quantity > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Payment", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - 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("LegacyOrderId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_order_id"); - - b.Property("Method") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("method"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderTradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_trade_no"); - - b.Property("RawPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_payments"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_payments_tenant_id_id"); - - b.HasIndex("Provider", "ProviderTradeNo") - .IsUnique() - .HasDatabaseName("ix_payments_provider_provider_trade_no") - .HasFilter("provider_trade_no is not null"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_payments_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderId", "UpdatedAt") - .HasDatabaseName("ix_payments_tenant_id_order_id_updated_at"); - - b.ToTable("payments", null, t => - { - t.HasCheckConstraint("ck_payments_amount", "amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.PaymentEvent", 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("Error") - .HasColumnType("text") - .HasColumnName("error"); - - b.Property("EventId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("event_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("Payload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("ProcessedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("processed_at"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("SignatureValid") - .HasColumnType("boolean") - .HasColumnName("signature_valid"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_payment_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_payment_events_tenant_id_id"); - - b.HasIndex("Provider", "EventId") - .IsUnique() - .HasDatabaseName("ix_payment_events_provider_event_id"); - - b.HasIndex("TenantId", "PaymentId") - .HasDatabaseName("ix_payment_events_tenant_id_payment_id"); - - b.ToTable("payment_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Product", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Cover") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cover"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DetailImages") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("detail_images") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPriceText") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("legacy_price_text"); - - b.Property("Link") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("link"); - - b.Property("PreviewIframe") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("preview_iframe"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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_products"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_products_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_products_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "Type", "SortOrder") - .HasDatabaseName("ix_products_tenant_id_region_id_type_sort_order"); - - b.ToTable("products", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.SvipPlan", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Badge") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("badge"); - - b.Property("CouponOnly") - .HasColumnType("boolean") - .HasColumnName("coupon_only"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - 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(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OriginalPriceCents") - .HasColumnType("integer") - .HasColumnName("original_price_cents"); - - b.Property("PerDayLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("per_day_label"); - - b.Property("PriceCents") - .HasColumnType("integer") - .HasColumnName("price_cents"); - - b.Property("Recommended") - .HasColumnType("boolean") - .HasColumnName("recommended"); - - 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("VpEnabled") - .HasColumnType("boolean") - .HasColumnName("vp_enabled"); - - b.Property("VpProductId") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("vp_product_id"); - - b.HasKey("Id") - .HasName("pk_svip_plans"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_svip_plans_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_svip_plans_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_svip_plans_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("svip_plans", null, t => - { - t.HasCheckConstraint("ck_svip_plans_days", "days >= 0"); - - t.HasCheckConstraint("ck_svip_plans_price", "price_cents >= 0 and (original_price_cents is null or original_price_cents >= 0)"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantPaymentAccount", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ConfigPublic") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("config_public") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_payment_accounts"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_payment_accounts_tenant_id_id"); - - b.HasIndex("TenantId", "Provider") - .IsUnique() - .HasDatabaseName("ix_tenant_payment_accounts_tenant_id_provider"); - - b.ToTable("tenant_payment_accounts", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantSubscription", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("BillingCycle") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("billing_cycle"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PlanCode") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("plan_code"); - - b.Property("StartsAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_subscriptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_subscriptions_tenant_id_id"); - - b.HasIndex("TenantId", "Status", "ExpiresAt") - .HasDatabaseName("ix_tenant_subscriptions_tenant_id_status_expires_at"); - - b.ToTable("tenant_subscriptions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantUsageRecord", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("MetricKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("metric_key"); - - b.Property("MetricValue") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)") - .HasColumnName("metric_value"); - - b.Property("PeriodEnd") - .HasColumnType("date") - .HasColumnName("period_end"); - - b.Property("PeriodStart") - .HasColumnType("date") - .HasColumnName("period_start"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_tenant_usage_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_usage_records_tenant_id_id"); - - b.HasIndex("TenantId", "MetricKey", "PeriodStart", "PeriodEnd") - .HasDatabaseName("ix_tenant_usage_records_tenant_id_metric_key_period_start_peri~"); - - b.ToTable("tenant_usage_records", (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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_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_handbook_chapters"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_chapters_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_chapters_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_subject_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_chapters_tenant_id_entry_id_content_node_id_subjec~"); - - b.ToTable("handbook_chapters", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ChapterId") - .HasColumnType("uuid") - .HasColumnName("chapter_id"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Summary") - .HasColumnType("text") - .HasColumnName("summary"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_handbook_entries"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_entries_tenant_id_id"); - - b.HasIndex("TenantId", "ChapterId") - .HasDatabaseName("ix_handbook_entries_tenant_id_chapter_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_entries_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_entries_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "ChapterId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_entries_tenant_id_entry_id_content_node_id_chapter~"); - - b.ToTable("handbook_entries", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", 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("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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - 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_handbook_subjects"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_subjects_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_subjects_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "MajorId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_major_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_school_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_subjects_tenant_id_entry_id_content_node_id_region~"); - - b.ToTable("handbook_subjects", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("CdnUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cdn_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FileName") - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("file_name"); - - 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("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.HasKey("Id") - .HasName("pk_images"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_images_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_images_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "Category", "IsPublic") - .HasDatabaseName("ix_images_tenant_id_category_is_public"); - - b.ToTable("images", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", 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("AssemblyType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assembly_type"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_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("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PassScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("pass_score"); - - b.Property("QuestionLimit") - .HasColumnType("integer") - .HasColumnName("question_limit"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Rules") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("rules") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Sections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sections") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_practice_blueprints"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_blueprints_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_practice_blueprints_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_practice_blueprints_updated_by"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_collection_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_practice_blueprints_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_region_id"); - - b.HasIndex("TenantId", "NodeId", "CollectionId", "Mode", "Status", "SortOrder") - .HasDatabaseName("ix_practice_blueprints_tenant_id_node_id_collection_id_mode_st~"); - - b.ToTable("practice_blueprints", null, t => - { - t.HasCheckConstraint("ck_practice_blueprints_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_practice_blueprints_question_limit", "question_limit is null or question_limit > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", 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("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - b.Property("CollectionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("collection_type"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Filters") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("filters") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_question_collections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collections_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_collections_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_question_collections_updated_by"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_question_collections_tenant_id_category_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_question_collections_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_collections_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_question_collections_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_collections_tenant_id_region_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_question_collections_tenant_id_subject_id"); - - b.HasIndex("TenantId", "NodeId", "Status", "SortOrder") - .HasDatabaseName("ix_question_collections_tenant_id_node_id_status_sort_order"); - - b.ToTable("question_collections", null, t => - { - t.HasCheckConstraint("ck_question_collections_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_question_collections_question_count", "question_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Required") - .HasColumnType("boolean") - .HasColumnName("required"); - - b.Property("Score") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - 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_question_collection_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collection_items_tenant_id_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_question_collection_items_tenant_id_question_id"); - - b.HasIndex("TenantId", "CollectionId", "QuestionId") - .IsUnique() - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_question_~"); - - b.HasIndex("TenantId", "CollectionId", "SectionKey", "SortOrder") - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_section_k~"); - - b.ToTable("question_collection_items", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", 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("DisplayName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Types") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("types") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_question_type_groups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_type_groups_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_type_groups_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_question_type_groups_tenant_id_subject_id_is_active_sort_or~"); - - b.ToTable("question_type_groups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", 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("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("LegacyVideoId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_video_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_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("VideoId") - .HasColumnType("uuid") - .HasColumnName("video_id"); - - b.Property("VideoType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("video_type"); - - b.HasKey("Id") - .HasName("pk_question_videos"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_videos_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "VideoId") - .HasDatabaseName("ix_question_videos_tenant_id_video_id"); - - b.HasIndex("TenantId", "QuestionId", "VideoId", "VideoType") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_question_id_video_id_video_type"); - - b.ToTable("question_videos", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("SourceSubjectId") - .HasColumnType("uuid") - .HasColumnName("source_subject_id"); - - b.Property("TargetSubjectId") - .HasColumnType("uuid") - .HasColumnName("target_subject_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Id") - .HasColumnType("uuid") - .HasColumnName("id"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacySourceSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_source_subject_id"); - - b.Property("LegacyTargetSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_target_subject_id"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at"); - - b.HasKey("TenantId", "SourceSubjectId", "TargetSubjectId") - .HasName("pk_subject_shares"); - - b.HasIndex("TenantId", "TargetSubjectId") - .HasDatabaseName("ix_subject_shares_tenant_id_target_subject_id"); - - b.ToTable("subject_shares", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", 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("FavoritedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("favorited_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Note") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.HasKey("Id") - .HasName("pk_user_word_favorites"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_favorites_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_favorites_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_favorites_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_favorites_tenant_id_user_id_word_id"); - - b.ToTable("user_word_favorites", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CorrectStreak") - .HasColumnType("integer") - .HasColumnName("correct_streak"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DueLevel") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("due_level"); - - b.Property("EaseFactor") - .ValueGeneratedOnAdd() - .HasPrecision(4, 2) - .HasColumnType("numeric(4,2)") - .HasDefaultValue(2.50m) - .HasColumnName("ease_factor"); - - b.Property("LastResult") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("last_result"); - - b.Property("LastReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_review_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NextReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_review_at"); - - b.Property("ReviewCount") - .HasColumnType("integer") - .HasColumnName("review_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_user_word_progress"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_progress_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_progress_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_progress_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_word_id"); - - b.HasIndex("TenantId", "UserId", "NextReviewAt", "Status", "DueLevel") - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_next_review_at_status_~"); - - b.ToTable("user_word_progress", null, t => - { - t.HasCheckConstraint("ck_user_word_progress_correct_streak", "correct_streak >= 0"); - - t.HasCheckConstraint("ck_user_word_progress_ease_factor", "ease_factor >= 1.30 and ease_factor <= 3.00"); - - t.HasCheckConstraint("ck_user_word_progress_review_count", "review_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("IsGeneral") - .HasColumnType("boolean") - .HasColumnName("is_general"); - - b.Property("KnowledgeTags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("knowledge_tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ThumbnailUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("thumbnail_url"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VideoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("video_url"); - - b.HasKey("Id") - .HasName("pk_video_explanations"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_video_explanations_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_video_explanations_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SourceHash") - .HasDatabaseName("ix_video_explanations_tenant_id_source_hash") - .HasFilter("source_hash is not null"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_video_explanations_tenant_id_subject_id_is_active_sort_order"); - - b.ToTable("video_explanations", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WordCount") - .HasColumnType("integer") - .HasColumnName("word_count"); - - b.HasKey("Id") - .HasName("pk_vocabulary_units"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_units_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_units_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_region_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_units_tenant_id_entry_id_content_node_id_region_~"); - - b.ToTable("vocabulary_units", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Example") - .HasColumnType("text") - .HasColumnName("example"); - - b.Property("ExampleTranslation") - .HasColumnType("text") - .HasColumnName("example_translation"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Meaning") - .HasColumnType("text") - .HasColumnName("meaning"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phonetic") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("phonetic"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitId") - .HasColumnType("uuid") - .HasColumnName("unit_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Word") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("word"); - - b.HasKey("Id") - .HasName("pk_vocabulary_words"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_words_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_words_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_words_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UnitId", "IsActive", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_vocabulary_words_tenant_id_unit_id_is_active_sort_order_cre~"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "UnitId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_words_tenant_id_entry_id_content_node_id_unit_id~"); - - b.ToTable("vocabulary_words", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlement", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CommissionAmountCents") - .HasColumnType("integer") - .HasColumnName("commission_amount_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DefaultRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("default_rate"); - - b.Property("EffectiveRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("effective_rate"); - - b.Property("GeneratedBy") - .HasColumnType("uuid") - .HasColumnName("generated_by"); - - b.Property("GrossAmountCents") - .HasColumnType("integer") - .HasColumnName("gross_amount_cents"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PaidBy") - .HasColumnType("uuid") - .HasColumnName("paid_by"); - - b.Property("PaidUserCount") - .HasColumnType("integer") - .HasColumnName("paid_user_count"); - - b.Property("PaymentAccount") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("payment_account"); - - b.Property("PaymentMethod") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("payment_method"); - - b.Property("PeriodEnd") - .HasColumnType("date") - .HasColumnName("period_end"); - - b.Property("PeriodStart") - .HasColumnType("date") - .HasColumnName("period_start"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("ReviewedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("reviewed_at"); - - b.Property("ReviewedBy") - .HasColumnType("uuid") - .HasColumnName("reviewed_by"); - - b.Property("SettlementNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("settlement_no"); - - b.Property("SourceCount") - .HasColumnType("integer") - .HasColumnName("source_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_commission_settlements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commission_settlements_tenant_id_id"); - - b.HasIndex("GeneratedBy") - .HasDatabaseName("ix_commission_settlements_generated_by"); - - b.HasIndex("PaidBy") - .HasDatabaseName("ix_commission_settlements_paid_by"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_commission_settlements_referrer_user_id"); - - b.HasIndex("ReviewedBy") - .HasDatabaseName("ix_commission_settlements_reviewed_by"); - - b.HasIndex("TenantId", "SettlementNo") - .IsUnique() - .HasDatabaseName("ix_commission_settlements_tenant_id_settlement_no"); - - b.HasIndex("TenantId", "ReferrerUserId", "PeriodStart") - .HasDatabaseName("ix_commission_settlements_referrer_start"); - - b.HasIndex("TenantId", "ReferrerUserId", "PeriodStart", "PeriodEnd") - .IsUnique() - .HasDatabaseName("ux_commission_settlements_referrer_period"); - - b.ToTable("commission_settlements", null, t => - { - t.HasCheckConstraint("ck_commission_settlements_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commission_settlements_counts", "source_count >= 0 and paid_user_count >= 0"); - - t.HasCheckConstraint("ck_commission_settlements_period", "period_end >= period_start"); - - t.HasCheckConstraint("ck_commission_settlements_rates", "default_rate >= 0 and default_rate <= 1 and (effective_rate is null or (effective_rate >= 0 and effective_rate <= 1))"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlementItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AttributionType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("attribution_type"); - - b.Property("CommissionAmountCents") - .HasColumnType("integer") - .HasColumnName("commission_amount_cents"); - - b.Property("CommissionRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("commission_rate"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("GrossAmountCents") - .HasColumnType("integer") - .HasColumnName("gross_amount_cents"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RateSource") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("rate_source"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("SettlementId") - .HasColumnType("uuid") - .HasColumnName("settlement_id"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_no"); - - b.Property("SourcePaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("source_paid_at"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_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_commission_settlement_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commission_settlement_items_tenant_id_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_commission_settlement_items_referrer_user_id"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_commission_settlement_items_student_user_id"); - - b.HasIndex("TenantId", "SettlementId") - .HasDatabaseName("ix_commission_settlement_items_tenant_id_settlement_id"); - - b.HasIndex("TenantId", "ReferrerUserId", "SourcePaidAt") - .HasDatabaseName("ix_commission_settlement_items_tenant_id_referrer_user_id_sour~"); - - b.HasIndex("TenantId", "SourceType", "SourceId") - .IsUnique() - .HasDatabaseName("ix_commission_settlement_items_tenant_id_source_type_source_id"); - - b.ToTable("commission_settlement_items", null, t => - { - t.HasCheckConstraint("ck_commission_settlement_items_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commission_settlement_items_rate", "commission_rate >= 0 and commission_rate <= 1"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignmentConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("assignment_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("AssignmentCursor") - .HasColumnType("integer") - .HasColumnName("assignment_cursor"); - - b.Property("AssignmentMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assignment_mode"); - - b.Property("AssignmentPool") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("assignment_pool") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DelaySeconds") - .HasColumnType("integer") - .HasColumnName("delay_seconds"); - - b.Property("Enabled") - .HasColumnType("boolean") - .HasColumnName("enabled"); - - b.Property("ExamType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("exam_type"); - - b.Property("FormName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("form_name"); - - b.Property("SecretRef") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("secret_ref"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TimeoutSeconds") - .HasColumnType("integer") - .HasColumnName("timeout_seconds"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Url") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("url"); - - b.HasKey("Id") - .HasName("pk_crm_config"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_config_tenant_id_id"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_crm_config_tenant_id"); - - b.HasIndex("TenantId", "AssignmentMode") - .HasDatabaseName("ix_crm_config_tenant_id_assignment_mode"); - - b.ToTable("crm_config", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempt") - .HasColumnType("integer") - .HasColumnName("attempt"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ErrorMessage") - .HasColumnType("text") - .HasColumnName("error_message"); - - b.Property("HttpCode") - .HasColumnType("integer") - .HasColumnName("http_code"); - - b.Property("LeadId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Outcome") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("outcome"); - - b.Property("RecordId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("record_id"); - - b.Property("RequestBody") - .HasColumnType("text") - .HasColumnName("request_body"); - - b.Property("RequestPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("request_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ResponseSummary") - .HasMaxLength(2000) - .HasColumnType("character varying(2000)") - .HasColumnName("response_summary"); - - b.Property("SignedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("signed_at"); - - 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_crm_webhook_log"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_webhook_log_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_log_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RecordId", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_log_tenant_id_record_id_created_at"); - - b.ToTable("crm_webhook_log", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookQueueItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempts") - .HasColumnType("integer") - .HasColumnName("attempts"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IdempotencyKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("idempotency_key"); - - b.Property("LastAttemptAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_attempt_at"); - - b.Property("LastError") - .HasColumnType("text") - .HasColumnName("last_error"); - - b.Property("LastHttpCode") - .HasColumnType("integer") - .HasColumnName("last_http_code"); - - b.Property("LastResponseSummary") - .HasColumnType("text") - .HasColumnName("last_response_summary"); - - b.Property("LeadId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("NextAttemptAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_attempt_at"); - - b.Property("Payload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("RecordId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("record_id"); - - b.Property("ScheduledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("scheduled_at"); - - b.Property("SentAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("sent_at"); - - b.Property("Source") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TargetUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("target_url"); - - 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_crm_webhook_queue"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_webhook_queue_tenant_id_id"); - - b.HasIndex("TenantId", "IdempotencyKey") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_idempotency_key") - .HasFilter("idempotency_key is not null"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RecordId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_record_id") - .HasFilter("record_id is not null"); - - b.HasIndex("TenantId", "RecordId", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_record_id_created_at") - .HasFilter("record_id is not null"); - - b.HasIndex("TenantId", "Source", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_source_created_at") - .HasFilter("source = 'tenant.student.crm_push'"); - - b.HasIndex("TenantId", "Status", "ScheduledAt", "NextAttemptAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_status_scheduled_at_next_attemp~"); - - b.ToTable("crm_webhook_queue", null, t => - { - t.HasCheckConstraint("ck_crm_webhook_queue_attempts", "attempts >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Channel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("channel"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("LandingPath") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("landing_path"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_referral_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_codes_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_referral_codes_user_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_referral_codes_tenant_id_code"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_referral_codes_tenant_id_user_id"); - - b.HasIndex("TenantId", "Code", "Status") - .HasDatabaseName("ix_referral_codes_tenant_id_code_status"); - - b.ToTable("referral_codes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralLead", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("assigned_at"); - - b.Property("AssignedBy") - .HasColumnType("uuid") - .HasColumnName("assigned_by"); - - b.Property("AssignedToUserId") - .HasColumnType("uuid") - .HasColumnName("assigned_to_user_id"); - - b.Property("AssignmentMode") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assignment_mode"); - - b.Property("BindType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("bind_type"); - - b.Property("BoundAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("bound_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FirstTrackId") - .HasColumnType("uuid") - .HasColumnName("first_track_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ProtectedUntil") - .HasColumnType("timestamp with time zone") - .HasColumnName("protected_until"); - - b.Property("RefCode") - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Source") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_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_referral_leads"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_leads_tenant_id_id"); - - b.HasIndex("AssignedBy") - .HasDatabaseName("ix_referral_leads_assigned_by"); - - b.HasIndex("AssignedToUserId") - .HasDatabaseName("ix_referral_leads_assigned_to_user_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_referral_leads_referrer_user_id"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_referral_leads_student_user_id"); - - b.HasIndex("TenantId", "FirstTrackId") - .HasDatabaseName("ix_referral_leads_tenant_id_first_track_id"); - - b.HasIndex("TenantId", "StudentUserId") - .IsUnique() - .HasDatabaseName("ix_referral_leads_tenant_id_student_user_id"); - - b.HasIndex("TenantId", "ReferrerUserId", "BoundAt") - .HasDatabaseName("ix_referral_leads_tenant_id_referrer_user_id_bound_at"); - - b.HasIndex("TenantId", "AssignedToUserId", "Status", "BoundAt") - .HasDatabaseName("ix_referral_leads_tenant_id_assigned_to_user_id_status_bound_at"); - - b.ToTable("referral_leads", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralQrcode", 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("ErrorMessage") - .HasColumnType("text") - .HasColumnName("error_message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Page") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("page"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("QrcodeUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("qrcode_url"); - - b.Property("RefCode") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("Scene") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("scene"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_referral_qrcodes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_qrcodes_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_referral_qrcodes_user_id"); - - b.HasIndex("TenantId", "RefCode", "Status") - .HasDatabaseName("ix_referral_qrcodes_tenant_id_ref_code_status"); - - b.HasIndex("TenantId", "Provider", "Scene", "Page") - .IsUnique() - .HasDatabaseName("ix_referral_qrcodes_tenant_id_provider_scene_page"); - - b.ToTable("referral_qrcodes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTeamEdge", 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("LeaderUserId") - .HasColumnType("uuid") - .HasColumnName("leader_user_id"); - - b.Property("MemberUserId") - .HasColumnType("uuid") - .HasColumnName("member_user_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RelationType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("relation_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_referral_team_edges"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_team_edges_tenant_id_id"); - - b.HasIndex("LeaderUserId") - .HasDatabaseName("ix_referral_team_edges_leader_user_id"); - - b.HasIndex("MemberUserId") - .HasDatabaseName("ix_referral_team_edges_member_user_id"); - - b.HasIndex("TenantId", "LeaderUserId", "Status") - .HasDatabaseName("ix_referral_team_edges_tenant_id_leader_user_id_status"); - - b.HasIndex("TenantId", "MemberUserId", "RelationType") - .IsUnique() - .HasDatabaseName("ix_referral_team_edges_tenant_id_member_user_id_relation_type"); - - b.ToTable("referral_team_edges", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTrack", 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("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("IpAddress") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("ip_address"); - - b.Property("LeadId") - .HasColumnType("uuid") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RefCode") - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Source") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source"); - - b.Property("TargetUserId") - .HasColumnType("uuid") - .HasColumnName("target_user_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserAgent") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_referral_tracks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_tracks_tenant_id_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_referral_tracks_referrer_user_id"); - - b.HasIndex("TargetUserId") - .HasDatabaseName("ix_referral_tracks_target_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_referral_tracks_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "LeadId", "CreatedAt") - .HasDatabaseName("ix_referral_tracks_tenant_id_lead_id_created_at"); - - b.HasIndex("TenantId", "RefCode", "EventType", "CreatedAt") - .HasDatabaseName("ix_referral_tracks_tenant_id_ref_code_event_type_created_at"); - - b.ToTable("referral_tracks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.TenantCommissionSetting", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - 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("DefaultRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("default_rate"); - - b.Property("MinSettlementCents") - .HasColumnType("integer") - .HasColumnName("min_settlement_cents"); - - b.Property("SettlementCycle") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("settlement_cycle"); - - 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_tenant_commission_settings"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_commission_settings_tenant_id_id"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_tenant_commission_settings_tenant_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_commission_settings_updated_by"); - - b.ToTable("tenant_commission_settings", null, t => - { - t.HasCheckConstraint("ck_tenant_commission_settings_default_rate", "default_rate >= 0 and default_rate <= 1"); - - t.HasCheckConstraint("ck_tenant_commission_settings_min_settlement", "min_settlement_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", 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("LastCheckInDate") - .HasColumnType("date") - .HasColumnName("last_check_in_date"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("MasteredWordsCount") - .HasColumnType("integer") - .HasColumnName("mastered_words_count"); - - b.Property("ModuleSelections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_selections") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Progress") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("progress") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionsAnsweredToday") - .HasColumnType("integer") - .HasColumnName("questions_answered_today"); - - b.Property("RecentActivities") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("recent_activities") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SelectedMajorId") - .HasColumnType("uuid") - .HasColumnName("selected_major_id"); - - b.Property("SelectedSchoolId") - .HasColumnType("uuid") - .HasColumnName("selected_school_id"); - - b.Property("Stats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("stats") - .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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_student_profiles"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_student_profiles_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_student_profiles_user_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_student_profiles_tenant_id_region_id"); - - b.HasIndex("TenantId", "SelectedMajorId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_major_id"); - - b.HasIndex("TenantId", "SelectedSchoolId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_school_id"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_student_profiles_tenant_id_user_id"); - - b.ToTable("student_profiles", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AvatarUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("avatar_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("LastSeenAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_seen_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPasswordHash") - .HasMaxLength(512) - .HasColumnType("character varying(512)") - .HasColumnName("legacy_password_hash"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PasswordMigrationRequired") - .HasColumnType("boolean") - .HasColumnName("password_migration_required"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("PrimaryRole") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("primary_role"); - - b.Property("RawProfile") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_profile") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Score") - .HasColumnType("integer") - .HasColumnName("score"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Username") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("username"); - - b.HasKey("Id") - .HasName("pk_users"); - - b.HasIndex("Email") - .IsUnique() - .HasDatabaseName("ix_users_email"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_users_legacy_id"); - - b.HasIndex("Phone") - .IsUnique() - .HasDatabaseName("ix_users_phone"); - - b.HasIndex("Username") - .IsUnique() - .HasDatabaseName("ix_users_username"); - - b.ToTable("users", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", 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("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("OpenId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("open_id"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderSubject") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("provider_subject"); - - b.Property("SecretPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("secret_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UnionId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("union_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_identities"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_identities_user_id"); - - b.HasIndex("Provider", "ProviderSubject") - .IsUnique() - .HasDatabaseName("ix_user_identities_provider_provider_subject"); - - b.ToTable("user_identities", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("AnsweredAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("answered_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IsCorrect") - .HasColumnType("boolean") - .HasColumnName("is_correct"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("QuestionVersionId") - .HasColumnType("uuid") - .HasColumnName("question_version_id"); - - b.Property("SelectedOptions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("selected_options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_answer_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_answer_records_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_answer_records_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_answer_records_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id"); - - b.HasIndex("TenantId", "QuestionId", "QuestionVersionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id_question_version_id"); - - b.HasIndex("TenantId", "UserId", "PracticeSessionId") - .HasDatabaseName("ix_answer_records_tenant_id_user_id_practice_session_id"); - - b.ToTable("answer_records", null, t => - { - t.HasCheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActiveUsers") - .HasColumnType("integer") - .HasColumnName("active_users"); - - 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("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("NewOrders") - .HasColumnType("integer") - .HasColumnName("new_orders"); - - b.Property("NewQuestions") - .HasColumnType("integer") - .HasColumnName("new_questions"); - - b.Property("NewRevenueCents") - .HasColumnType("integer") - .HasColumnName("new_revenue_cents"); - - b.Property("NewUsers") - .HasColumnType("integer") - .HasColumnName("new_users"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_dashboard_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_dashboard_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_stat_date_region_id"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId"), false); - - b.ToTable("dashboard_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", 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("ExamAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("exam_at"); - - b.Property("ExamName") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("exam_name"); - - b.Property("ExamType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("exam_type"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("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_exam_dates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_exam_dates_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_exam_dates_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_exam_dates_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId", "ExamAt") - .HasDatabaseName("ix_exam_dates_tenant_id_school_id_exam_at"); - - b.ToTable("exam_dates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_favorite_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_favorite_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_favorite_questions_tenant_id_question_id"); - - b.ToTable("favorite_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("access_mode"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EntitlementId") - .HasColumnType("uuid") - .HasColumnName("entitlement_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("GrantedCount") - .HasColumnType("integer") - .HasColumnName("granted_count"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("Reason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("reason"); - - b.Property("RequestedCount") - .HasColumnType("integer") - .HasColumnName("requested_count"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_access_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_access_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_access_events_user_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_access_events_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_practice_access_events_tenant_id_user_id_created_at"); - - b.ToTable("practice_access_events", null, t => - { - t.HasCheckConstraint("ck_practice_access_events_consumed_free_quota", "consumed_free_quota >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_granted_count", "granted_count >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_requested_count", "requested_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", 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("FreeLimit") - .HasColumnType("integer") - .HasColumnName("free_limit"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsageDate") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasColumnName("usage_date") - .HasDefaultValueSql("current_date"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_daily_usage"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_daily_usage_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_daily_usage_user_id"); - - b.HasIndex("TenantId", "UserId", "UsageDate") - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date"); - - b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId") - .IsUnique() - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date_scope_typ~"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId"), false); - - b.ToTable("practice_daily_usage", null, t => - { - t.HasCheckConstraint("ck_practice_daily_usage_free_limit", "free_limit >= 0"); - - t.HasCheckConstraint("ck_practice_daily_usage_used_count", "used_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessEntitlementId") - .HasColumnType("uuid") - .HasColumnName("access_entitlement_id"); - - b.Property("AccessMode") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasDefaultValue("free") - .HasColumnName("access_mode"); - - b.Property("AccessSnapshot") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("access_snapshot") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("ContentNodeId") - .HasColumnType("uuid") - .HasColumnName("content_node_id"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("FinishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("finished_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at") - .HasDefaultValueSql("now()"); - - b.Property("TargetId") - .HasColumnType("uuid") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_sessions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "UserId", "Id") - .HasName("ak_practice_sessions_tenant_id_user_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_sessions_user_id"); - - b.HasIndex("TenantId", "BlueprintId") - .HasDatabaseName("ix_practice_sessions_tenant_id_blueprint_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_sessions_tenant_id_collection_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_practice_sessions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_sessions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "UserId", "StartedAt") - .HasDatabaseName("ix_practice_sessions_tenant_id_user_id_started_at"); - - b.ToTable("practice_sessions", null, t => - { - t.HasCheckConstraint("ck_practice_sessions_consumed_free_quota", "consumed_free_quota >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionResults") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_results") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionStats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("section_stats") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at"); - - b.Property("SubmittedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("submitted_at") - .HasDefaultValueSql("now()"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalQuestions") - .HasColumnType("integer") - .HasColumnName("total_questions"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.Property("WrongQuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("wrong_question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.HasKey("Id") - .HasName("pk_practice_session_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_reports_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_session_reports_user_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_session_reports_tenant_id_collection_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .IsUnique() - .HasDatabaseName("ix_practice_session_reports_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "BlueprintId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_blueprint_id_submitted_at") - .HasFilter("blueprint_id is not null"); - - b.HasIndex("TenantId", "UserId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_user_id_submitted_at"); - - b.ToTable("practice_session_reports", null, t => - { - t.HasCheckConstraint("ck_practice_session_reports_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_reports_counts", "total_questions >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_duration", "duration_seconds >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("question_type"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - b.Property("SectionName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("section_name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_practice_session_report_sections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_report_sections_tenant_id_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_practice_session~"); - - b.HasIndex("TenantId", "ReportId", "SectionKey") - .IsUnique() - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sectio~"); - - b.HasIndex("TenantId", "ReportId", "SortOrder") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sort_o~"); - - b.ToTable("practice_session_report_sections", null, t => - { - t.HasCheckConstraint("ck_practice_session_report_sections_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_report_sections_counts", "question_count >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_report_sections_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", 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("LastAccessAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_access_at"); - - b.Property("LastPracticeAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_practice_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("practice_type"); - - b.Property("Progress") - .HasColumnType("integer") - .HasColumnName("progress"); - - b.Property("TargetLegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("target_legacy_id"); - - b.Property("TargetName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("target_name"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_recent_practices"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_recent_practices_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_recent_practices_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_recent_practices_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "LastAccessAt") - .HasDatabaseName("ix_recent_practices_tenant_id_user_id_last_access_at"); - - b.ToTable("recent_practices", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attachments") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("attachments") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("Contact") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("contact"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("HandledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("handled_at"); - - b.Property("HandledBy") - .HasColumnType("uuid") - .HasColumnName("handled_by"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Resolution") - .HasColumnType("text") - .HasColumnName("resolution"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_reports_tenant_id_id"); - - b.HasIndex("HandledBy") - .HasDatabaseName("ix_reports_handled_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_reports_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_reports_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_question_id_created_at") - .HasFilter("question_id is not null"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_status_created_at"); - - b.ToTable("reports", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_report_status_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_report_status_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_report_status_events_actor_user_id"); - - b.HasIndex("TenantId", "ReportId", "CreatedAt") - .HasDatabaseName("ix_report_status_events_tenant_id_report_id_created_at"); - - b.ToTable("report_status_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CodeCount") - .HasColumnType("integer") - .HasColumnName("code_count"); - - b.Property("CodeEstimated") - .HasColumnType("integer") - .HasColumnName("code_estimated"); - - b.Property("CodeUsed") - .HasColumnType("integer") - .HasColumnName("code_used"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EstimatedRevenueCents") - .HasColumnType("integer") - .HasColumnName("estimated_revenue_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("OrderCount") - .HasColumnType("integer") - .HasColumnName("order_count"); - - b.Property("RealRevenueCents") - .HasColumnType("integer") - .HasColumnName("real_revenue_cents"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_revenue_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_revenue_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_stat_date_region_id_sale_type"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType"), false); - - b.ToTable("revenue_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BalanceAfter") - .HasColumnType("integer") - .HasColumnName("balance_after"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("IdempotencyKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("idempotency_key"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Points") - .HasColumnType("integer") - .HasColumnName("points"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_score_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_score_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_score_events_user_id"); - - b.HasIndex("TenantId", "IdempotencyKey") - .IsUnique() - .HasDatabaseName("ix_user_score_events_tenant_id_idempotency_key"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_user_score_events_tenant_id_user_id_created_at"); - - b.ToTable("user_score_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("LastWrongAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("last_wrong_at") - .HasDefaultValueSql("now()"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("WrongCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(1) - .HasColumnName("wrong_count"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_wrong_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_wrong_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_wrong_questions_tenant_id_question_id"); - - b.ToTable("wrong_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - 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("CurrentVersionId") - .HasColumnType("uuid") - .HasColumnName("current_version_id"); - - b.Property("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExamMarkers") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("exam_markers") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("HasVideoExplanation") - .HasColumnType("boolean") - .HasColumnName("has_video_explanation"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyNodeId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_node_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("MediaUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("media_url"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PrimaryCollectionId") - .HasColumnType("uuid") - .HasColumnName("primary_collection_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Type") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("type"); - - b.Property("TypeLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("type_label"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_questions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_questions_tenant_id_id"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_questions_tenant_id_category_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_questions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_questions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_questions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "NodeId") - .HasDatabaseName("ix_questions_tenant_id_node_id"); - - b.HasIndex("TenantId", "PrimaryCollectionId") - .HasDatabaseName("ix_questions_tenant_id_primary_collection_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_questions_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_questions_tenant_id_subject_id"); - - b.HasIndex("TenantId", "Id", "CurrentVersionId") - .HasDatabaseName("ix_questions_tenant_id_id_current_version_id"); - - b.ToTable("questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SourceScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_scope"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_banks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_banks_tenant_id_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_banks_tenant_id_region_id"); - - b.ToTable("question_banks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("CodeLang") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("code_lang"); - - b.Property("CodeTemplate") - .HasColumnType("text") - .HasColumnName("code_template"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CorrectOptionIndex") - .HasColumnType("integer") - .HasColumnName("correct_option_index"); - - b.Property("CorrectOptionIndices") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("correct_option_indices") - .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("Explanation") - .HasColumnType("text") - .HasColumnName("explanation"); - - b.Property("Options") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubQuestions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sub_questions") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("VersionNo") - .HasColumnType("integer") - .HasColumnName("version_no"); - - b.HasKey("Id") - .HasName("pk_question_versions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_versions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "QuestionId", "Id") - .HasName("ak_question_versions_tenant_id_question_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_versions_created_by"); - - b.HasIndex("QuestionId", "VersionNo") - .IsUnique() - .HasDatabaseName("ix_question_versions_question_id_version_no"); - - b.ToTable("question_versions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", 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("FailureCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("failure_code"); - - b.Property("Identifier") - .HasMaxLength(320) - .HasColumnType("character varying(320)") - .HasColumnName("identifier"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Result") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("result"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_login_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_login_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_login_events_user_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_auth_login_events_tenant_id_user_id_created_at"); - - b.ToTable("auth_login_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", 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("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("RevokedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("revoked_at"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TokenHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("token_hash"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_sessions_tenant_id_id"); - - b.HasIndex("TokenHash") - .IsUnique() - .HasDatabaseName("ix_auth_sessions_token_hash"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_sessions_user_id"); - - b.HasIndex("TenantId", "UserId", "ExpiresAt") - .HasDatabaseName("ix_auth_sessions_tenant_id_user_id_expires_at") - .HasFilter("revoked_at is null"); - - b.ToTable("auth_sessions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Dimension") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("dimension"); - - b.Property("ScopeHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("scope_hash"); - - b.Property("BucketStart") - .HasColumnType("timestamp with time zone") - .HasColumnName("bucket_start"); - - b.Property("RequestCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0) - .HasColumnName("request_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId", "Dimension", "ScopeHash", "BucketStart") - .HasName("pk_sms_send_rate_limits"); - - b.HasIndex("UpdatedAt") - .HasDatabaseName("ix_sms_send_rate_limits_updated_at"); - - b.ToTable("sms_send_rate_limits", null, t => - { - t.HasCheckConstraint("ck_sms_send_rate_limits_request_count", "request_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempts") - .HasColumnType("integer") - .HasColumnName("attempts"); - - b.Property("CodeHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("code_hash"); - - b.Property("ConsumedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("consumed_at"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phone") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Purpose") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("purpose"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_sms_verification_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_sms_verification_codes_tenant_id_id"); - - b.HasIndex("TenantId", "Phone", "Purpose") - .IsUnique() - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "CreatedAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_created_at") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "ExpiresAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_expires_at"); - - b.ToTable("sms_verification_codes", null, t => - { - t.HasCheckConstraint("ck_sms_verification_codes_attempts", "attempts >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BillingStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("billing_status"); - - 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("LegalName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("legal_name"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OwnerUserId") - .HasColumnType("uuid") - .HasColumnName("owner_user_id"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("slug"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenants"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenants_legacy_id"); - - b.HasIndex("OwnerUserId") - .HasDatabaseName("ix_tenants_owner_user_id"); - - b.HasIndex("Slug") - .IsUnique() - .HasDatabaseName("ix_tenants_slug"); - - b.ToTable("tenants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ConfigPublic") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("config_public") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_auth_providers"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_auth_providers_tenant_id_id"); - - b.HasIndex("TenantId", "Provider") - .IsUnique() - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider"); - - b.HasIndex("TenantId", "Provider", "Status") - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider_status"); - - b.ToTable("tenant_auth_providers", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("BrandName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("brand_name"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FaviconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("favicon_url"); - - b.Property("LogoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("logo_url"); - - b.Property("OrganizationName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("organization_name"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ServiceAccountName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("service_account_name"); - - b.Property("ServiceWechat") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("service_wechat"); - - b.Property("ShortName") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("short_name"); - - b.Property("Slogan") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("slogan"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_branding"); - - b.ToTable("tenant_branding", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Code") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("code"); - - 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("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_classes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_classes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_classes_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_classes_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_code") - .HasFilter("code is not null and code <> ''"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_tenant_classes_tenant_id_region_id") - .HasFilter("region_id is not null"); - - b.HasIndex("TenantId", "Status", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_tenant_classes_tenant_id_status_sort_order_created_at"); - - b.ToTable("tenant_classes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_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("JoinedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("joined_at") - .HasDefaultValueSql("now()"); - - b.Property("LeftAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("left_at"); - - b.Property("MemberType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("member_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_class_members"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_class_members_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_class_members_user_id"); - - b.HasIndex("TenantId", "ClassId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_status_member_type"); - - b.HasIndex("TenantId", "ClassId", "UserId", "MemberType") - .IsUnique() - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_user_id_member_type"); - - b.HasIndex("TenantId", "UserId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_user_id_status_member_type"); - - b.ToTable("tenant_class_members", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", 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("DomainType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("domain_type"); - - b.Property("Host") - .IsRequired() - .HasMaxLength(253) - .HasColumnType("citext") - .HasColumnName("host"); - - b.Property("IsPrimary") - .HasColumnType("boolean") - .HasColumnName("is_primary"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VerificationToken") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("verification_token"); - - b.Property("VerifiedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("verified_at"); - - b.HasKey("Id") - .HasName("pk_tenant_domains"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_domains_tenant_id_id"); - - b.HasIndex("Host") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_host"); - - b.HasIndex("TenantId", "IsPrimary") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_tenant_id_is_primary") - .HasFilter("is_primary"); - - b.ToTable("tenant_domains", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", 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("LegacyRole") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("legacy_role"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Role") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("role"); - - b.Property("RoleTemplateId") - .HasColumnType("uuid") - .HasColumnName("role_template_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_memberships"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_memberships_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_memberships_user_id"); - - b.HasIndex("TenantId", "RoleTemplateId") - .HasDatabaseName("ix_tenant_memberships_tenant_id_role_template_id"); - - b.HasIndex("TenantId", "UserId", "Role") - .IsUnique() - .HasDatabaseName("ix_tenant_memberships_tenant_id_user_id_role"); - - b.ToTable("tenant_memberships", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BaseRole") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("base_role"); - - 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("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DataScope") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("data_scope") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("FieldPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("field_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("IsSystem") - .HasColumnType("boolean") - .HasColumnName("is_system"); - - b.Property("MenuPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("menu_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ModulePermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_role_templates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_role_templates_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_role_templates_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_role_templates_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_role_templates_tenant_id_code"); - - b.HasIndex("TenantId", "Status", "SortOrder") - .HasDatabaseName("ix_tenant_role_templates_tenant_id_status_sort_order"); - - b.ToTable("tenant_role_templates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("AdminFeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("admin_feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PublicConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_settings"); - - b.ToTable("tenant_settings", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignedToUserId") - .HasColumnType("uuid") - .HasColumnName("assigned_to_user_id"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_id"); - - b.Property("CompletedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("completed_at"); - - b.Property("CompletedBy") - .HasColumnType("uuid") - .HasColumnName("completed_by"); - - 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("DueAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("due_at"); - - b.Property("FollowupType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("followup_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .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.HasKey("Id") - .HasName("pk_tenant_student_followups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_followups_tenant_id_id"); - - b.HasIndex("AssignedToUserId") - .HasDatabaseName("ix_tenant_student_followups_assigned_to_user_id"); - - b.HasIndex("CompletedBy") - .HasDatabaseName("ix_tenant_student_followups_completed_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_followups_student_user_id"); - - b.HasIndex("TenantId", "AssignedToUserId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_assigned_to_user_id_stat~") - .HasFilter("assigned_to_user_id is not null"); - - b.HasIndex("TenantId", "ClassId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_class_id_status_due_at") - .HasFilter("class_id is not null"); - - b.HasIndex("TenantId", "StudentUserId", "Status", "DueAt", "CreatedAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_student_user_id_status_d~"); - - b.ToTable("tenant_student_followups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Content") - .IsRequired() - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("IsPinned") - .HasColumnType("boolean") - .HasColumnName("is_pinned"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NoteType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("note_type"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - 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_tenant_student_notes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_notes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_student_notes_created_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_notes_student_user_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_student_notes_updated_by"); - - b.HasIndex("TenantId", "CreatedBy", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_created_by_created_at") - .HasFilter("created_by is not null"); - - b.HasIndex("TenantId", "StudentUserId", "IsPinned", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_student_user_id_is_pinned_cr~"); - - b.ToTable("tenant_student_notes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Category", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_categories_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Major", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_majors_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.ModuleNode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_module_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_module_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Region", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_regions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.RegionModule", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_region_modules_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_region_modules_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.School", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_schools_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Subject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.ActivationCode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AgentUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_users_agent_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_activation_codes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UsedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_users_used_by"); - - b.HasOne("Tiku.Domain.Commerce.CodeBatch", null) - .WithMany() - .HasForeignKey("TenantId", "BatchId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_code_batches_tenant_id_batch_id"); - - b.HasOne("Tiku.Domain.Commerce.CouponRedemption", null) - .WithMany() - .HasForeignKey("TenantId", "CouponRedemptionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_coupon_redemptions_tenant_id_coupon_redemp~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "UsedRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_regions_tenant_id_used_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CodeBatch", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_code_batches_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Coupon", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_coupons_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_coupons_svip_plans_tenant_id_plan_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CouponRedemption", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_coupon_redemptions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_users_user_id"); - - b.HasOne("Tiku.Domain.Commerce.Coupon", null) - .WithMany() - .HasForeignKey("TenantId", "CouponId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_coupons_tenant_id_coupon_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_svip_plans_tenant_id_plan_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Entitlement", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_entitlements_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_entitlements_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Order", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_orders_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_orders_users_user_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_orders_svip_plans_tenant_id_plan_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_orders_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.OrderItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_order_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_order_items_orders_tenant_id_order_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Payment", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payments_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payments_orders_tenant_id_order_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.PaymentEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payment_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_payment_events_payments_tenant_id_payment_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Product", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_products_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_products_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.SvipPlan", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_svip_plans_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_svip_plans_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantPaymentAccount", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_payment_accounts_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantSubscription", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_subscriptions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantUsageRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_usage_records_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.AppAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_app_assets_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAsset", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_assets_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_updated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("VerifiedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_verified_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentEntry", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_entries_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportIssue", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportItem", null) - .WithMany() - .HasForeignKey("TenantId", "ItemId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_import_issues_content_import_items_tenant_id_item_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportJob", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_import_jobs_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_jobs_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "TargetCategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_categories_tenant_id_target_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "TargetContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_content_nodes_tenant_id_target_content_~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "TargetQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_question_banks_tenant_id_target_questio~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "TargetRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_regions_tenant_id_target_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentNode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_nodes_content_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookChapter", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_chapters_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.HandbookSubject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_chapters_handbook_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.HandbookChapter", null) - .WithMany() - .HasForeignKey("TenantId", "ChapterId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_entries_handbook_chapters_tenant_id_chapter_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_images_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_blueprints_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_question_collections_tenant_id_collecti~"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_question_banks_tenant_id_question_bank~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_question_collections_tenant_id_co~"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_type_groups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_type_groups_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_videos_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.Content.VideoExplanation", null) - .WithMany() - .HasForeignKey("TenantId", "VideoId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_video_explanations_tenant_id_video_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SourceSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_source_subject_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_video_explanations_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_video_explanations_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_units_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_words_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyUnit", null) - .WithMany() - .HasForeignKey("TenantId", "UnitId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_vocabulary_units_tenant_id_unit_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlement", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("GeneratedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_generated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("PaidBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_paid_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlements_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReviewedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_reviewed_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlements_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlementItem", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlement_items_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlement_items_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlement_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.CommissionSettlement", null) - .WithMany() - .HasForeignKey("TenantId", "SettlementId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlement_items_commission_settlements_tenant_i~"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmConfig", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_config_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookLog", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_webhook_log_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookQueueItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_webhook_queue_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralCode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_codes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_codes_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralLead", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_assigned_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedToUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_assigned_to_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_leads_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_leads_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.ReferralTrack", null) - .WithMany() - .HasForeignKey("TenantId", "FirstTrackId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_referral_tracks_tenant_id_first_track_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralQrcode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_qrcodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_qrcodes_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTeamEdge", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("LeaderUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_team_edges_users_leader_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("MemberUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_team_edges_users_member_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_team_edges_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTrack", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("TargetUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_users_target_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_tracks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.ReferralLead", null) - .WithMany() - .HasForeignKey("TenantId", "LeadId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_referral_leads_tenant_id_lead_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.TenantCommissionSetting", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_commission_settings_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_commission_settings_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedMajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_majors_tenant_id_selected_major_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedSchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_schools_tenant_id_selected_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_identities_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId", "QuestionVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_question_versions_tenant_id_question_id_ques~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "UserId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "UserId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_practice_sessions_tenant_id_user_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_dashboard_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_dashboard_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_exam_dates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_access_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_users_user_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_practice_sessions_tenant_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_question_collections_tenant_id_collection~"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_practice_blueprints_tenant_id_blue~"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_question_collections_tenant_id_col~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_practice_sessions_tenant_id_practi~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_sessions_tenant_i~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSessionReport", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_session_reports_t~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_recent_practices_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_recent_practices_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("HandledBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_handled_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_reports_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_report_status_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.Report", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_reports_tenant_id_report_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_revenue_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_revenue_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "PrimaryCollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_collections_tenant_id_primary_collection~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_banks_tenant_id_question_bank_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_subjects_tenant_id_subject_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "Id", "CurrentVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_versions_tenant_id_id_current_version_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_banks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_banks_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_versions_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_versions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_login_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_auth_login_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_send_rate_limits_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_verification_codes_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("OwnerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenants_users_owner_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_auth_providers_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantBranding", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_branding_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_classes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_classes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_domains_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantRoleTemplate", null) - .WithMany() - .HasForeignKey("TenantId", "RoleTemplateId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_memberships_tenant_role_templates_tenant_id_role_tem~"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_role_templates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantSettings", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_settings_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedToUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_assigned_to_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CompletedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_completed_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_updated_by"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725214048_AddReferralCrmAndCommissionPersistence.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725214048_AddReferralCrmAndCommissionPersistence.cs deleted file mode 100644 index 66bb231..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725214048_AddReferralCrmAndCommissionPersistence.cs +++ /dev/null @@ -1,799 +0,0 @@ -using System; -using System.Text.Json; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Tiku.Infrastructure.Persistence.Migrations -{ - /// - public partial class AddReferralCrmAndCommissionPersistence : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "commission_settlements", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - referrer_user_id = table.Column(type: "uuid", nullable: false), - generated_by = table.Column(type: "uuid", nullable: true), - reviewed_by = table.Column(type: "uuid", nullable: true), - paid_by = table.Column(type: "uuid", nullable: true), - settlement_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - period_start = table.Column(type: "date", nullable: false), - period_end = table.Column(type: "date", nullable: false), - source_count = table.Column(type: "integer", nullable: false), - paid_user_count = table.Column(type: "integer", nullable: false), - gross_amount_cents = table.Column(type: "integer", nullable: false), - commission_amount_cents = table.Column(type: "integer", nullable: false), - default_rate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), - effective_rate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: true), - reviewed_at = table.Column(type: "timestamp with time zone", nullable: true), - paid_at = table.Column(type: "timestamp with time zone", nullable: true), - payment_method = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - payment_account = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - remark = table.Column(type: "text", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_commission_settlements", x => x.id); - table.UniqueConstraint("ak_commission_settlements_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_commission_settlements_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); - table.CheckConstraint("ck_commission_settlements_counts", "source_count >= 0 and paid_user_count >= 0"); - table.CheckConstraint("ck_commission_settlements_period", "period_end >= period_start"); - table.CheckConstraint("ck_commission_settlements_rates", "default_rate >= 0 and default_rate <= 1 and (effective_rate is null or (effective_rate >= 0 and effective_rate <= 1))"); - table.ForeignKey( - name: "fk_commission_settlements_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_commission_settlements_users_generated_by", - column: x => x.generated_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_commission_settlements_users_paid_by", - column: x => x.paid_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_commission_settlements_users_referrer_user_id", - column: x => x.referrer_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_commission_settlements_users_reviewed_by", - column: x => x.reviewed_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "crm_config", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - enabled = table.Column(type: "boolean", nullable: false), - url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - secret_ref = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - form_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - exam_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - timeout_seconds = table.Column(type: "integer", nullable: true), - delay_seconds = table.Column(type: "integer", nullable: true), - assignment_mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - assignment_pool = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - assignment_cursor = table.Column(type: "integer", nullable: false), - assignment_config = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_crm_config", x => x.id); - table.UniqueConstraint("ak_crm_config_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_crm_config_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "crm_webhook_log", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - record_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - lead_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - http_code = table.Column(type: "integer", nullable: true), - outcome = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - error_message = table.Column(type: "text", nullable: true), - request_body = table.Column(type: "text", nullable: true), - request_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - response_summary = table.Column(type: "character varying(2000)", maxLength: 2000, nullable: true), - signed_at = table.Column(type: "timestamp with time zone", nullable: true), - attempt = table.Column(type: "integer", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_crm_webhook_log", x => x.id); - table.UniqueConstraint("ak_crm_webhook_log_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_crm_webhook_log_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "crm_webhook_queue", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - record_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - lead_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - source = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - provider = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - scheduled_at = table.Column(type: "timestamp with time zone", nullable: true), - attempts = table.Column(type: "integer", nullable: false), - next_attempt_at = table.Column(type: "timestamp with time zone", nullable: true), - last_attempt_at = table.Column(type: "timestamp with time zone", nullable: true), - last_error = table.Column(type: "text", nullable: true), - last_http_code = table.Column(type: "integer", nullable: true), - last_response_summary = table.Column(type: "text", nullable: true), - sent_at = table.Column(type: "timestamp with time zone", nullable: true), - idempotency_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - target_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_crm_webhook_queue", x => x.id); - table.UniqueConstraint("ak_crm_webhook_queue_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_crm_webhook_queue_attempts", "attempts >= 0"); - table.ForeignKey( - name: "fk_crm_webhook_queue_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "referral_codes", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: false), - code = table.Column(type: "citext", maxLength: 100, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - channel = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - landing_path = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_referral_codes", x => x.id); - table.UniqueConstraint("ak_referral_codes_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_referral_codes_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_referral_codes_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "referral_qrcodes", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: true), - ref_code = table.Column(type: "citext", maxLength: 100, nullable: false), - scene = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - page = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - provider = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - qrcode_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - error_message = table.Column(type: "text", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_referral_qrcodes", x => x.id); - table.UniqueConstraint("ak_referral_qrcodes_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_referral_qrcodes_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_referral_qrcodes_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "referral_team_edges", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - member_user_id = table.Column(type: "uuid", nullable: false), - leader_user_id = table.Column(type: "uuid", nullable: true), - relation_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_referral_team_edges", x => x.id); - table.UniqueConstraint("ak_referral_team_edges_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_referral_team_edges_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_referral_team_edges_users_leader_user_id", - column: x => x.leader_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_referral_team_edges_users_member_user_id", - column: x => x.member_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_commission_settings", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - default_rate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), - min_settlement_cents = table.Column(type: "integer", nullable: false), - settlement_cycle = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - config = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - updated_by = table.Column(type: "uuid", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_commission_settings", x => x.id); - table.UniqueConstraint("ak_tenant_commission_settings_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_tenant_commission_settings_default_rate", "default_rate >= 0 and default_rate <= 1"); - table.CheckConstraint("ck_tenant_commission_settings_min_settlement", "min_settlement_cents >= 0"); - table.ForeignKey( - name: "fk_tenant_commission_settings_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_commission_settings_users_updated_by", - column: x => x.updated_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "commission_settlement_items", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - settlement_id = table.Column(type: "uuid", nullable: true), - referrer_user_id = table.Column(type: "uuid", nullable: false), - student_user_id = table.Column(type: "uuid", nullable: true), - source_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - source_id = table.Column(type: "uuid", nullable: false), - source_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - source_paid_at = table.Column(type: "timestamp with time zone", nullable: true), - gross_amount_cents = table.Column(type: "integer", nullable: false), - commission_rate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), - commission_amount_cents = table.Column(type: "integer", nullable: false), - rate_source = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - attribution_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_commission_settlement_items", x => x.id); - table.UniqueConstraint("ak_commission_settlement_items_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_commission_settlement_items_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); - table.CheckConstraint("ck_commission_settlement_items_rate", "commission_rate >= 0 and commission_rate <= 1"); - table.ForeignKey( - name: "fk_commission_settlement_items_commission_settlements_tenant_i~", - columns: x => new { x.tenant_id, x.settlement_id }, - principalTable: "commission_settlements", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_commission_settlement_items_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_commission_settlement_items_users_referrer_user_id", - column: x => x.referrer_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_commission_settlement_items_users_student_user_id", - column: x => x.student_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "referral_leads", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - student_user_id = table.Column(type: "uuid", nullable: false), - referrer_user_id = table.Column(type: "uuid", nullable: true), - first_track_id = table.Column(type: "uuid", nullable: true), - assigned_to_user_id = table.Column(type: "uuid", nullable: true), - assigned_by = table.Column(type: "uuid", nullable: true), - ref_code = table.Column(type: "citext", maxLength: 100, nullable: true), - source = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - bind_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - protected_until = table.Column(type: "timestamp with time zone", nullable: true), - assignment_mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - assigned_at = table.Column(type: "timestamp with time zone", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - bound_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_referral_leads", x => x.id); - table.UniqueConstraint("ak_referral_leads_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_referral_leads_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_referral_leads_users_assigned_by", - column: x => x.assigned_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_referral_leads_users_assigned_to_user_id", - column: x => x.assigned_to_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_referral_leads_users_referrer_user_id", - column: x => x.referrer_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_referral_leads_users_student_user_id", - column: x => x.student_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "referral_tracks", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - lead_id = table.Column(type: "uuid", nullable: true), - referrer_user_id = table.Column(type: "uuid", nullable: true), - target_user_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - event_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - ref_code = table.Column(type: "citext", maxLength: 100, nullable: true), - source = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - ip_address = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - user_agent = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_referral_tracks", x => x.id); - table.UniqueConstraint("ak_referral_tracks_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_referral_tracks_referral_leads_tenant_id_lead_id", - columns: x => new { x.tenant_id, x.lead_id }, - principalTable: "referral_leads", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_referral_tracks_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_referral_tracks_users_referrer_user_id", - column: x => x.referrer_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_referral_tracks_users_target_user_id", - column: x => x.target_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateIndex( - name: "ix_commission_settlement_items_referrer_user_id", - table: "commission_settlement_items", - column: "referrer_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_commission_settlement_items_student_user_id", - table: "commission_settlement_items", - column: "student_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_commission_settlement_items_tenant_id_referrer_user_id_sour~", - table: "commission_settlement_items", - columns: new[] { "tenant_id", "referrer_user_id", "source_paid_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commission_settlement_items_tenant_id_settlement_id", - table: "commission_settlement_items", - columns: new[] { "tenant_id", "settlement_id" }); - - migrationBuilder.CreateIndex( - name: "ix_commission_settlement_items_tenant_id_source_type_source_id", - table: "commission_settlement_items", - columns: new[] { "tenant_id", "source_type", "source_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_commission_settlements_generated_by", - table: "commission_settlements", - column: "generated_by"); - - migrationBuilder.CreateIndex( - name: "ix_commission_settlements_paid_by", - table: "commission_settlements", - column: "paid_by"); - - migrationBuilder.CreateIndex( - name: "ix_commission_settlements_referrer_start", - table: "commission_settlements", - columns: new[] { "tenant_id", "referrer_user_id", "period_start" }); - - migrationBuilder.CreateIndex( - name: "ix_commission_settlements_referrer_user_id", - table: "commission_settlements", - column: "referrer_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_commission_settlements_reviewed_by", - table: "commission_settlements", - column: "reviewed_by"); - - migrationBuilder.CreateIndex( - name: "ix_commission_settlements_tenant_id_settlement_no", - table: "commission_settlements", - columns: new[] { "tenant_id", "settlement_no" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ux_commission_settlements_referrer_period", - table: "commission_settlements", - columns: new[] { "tenant_id", "referrer_user_id", "period_start", "period_end" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_crm_config_tenant_id", - table: "crm_config", - column: "tenant_id", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_crm_config_tenant_id_assignment_mode", - table: "crm_config", - columns: new[] { "tenant_id", "assignment_mode" }); - - migrationBuilder.CreateIndex( - name: "ix_crm_webhook_log_tenant_id_legacy_id", - table: "crm_webhook_log", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_crm_webhook_log_tenant_id_record_id_created_at", - table: "crm_webhook_log", - columns: new[] { "tenant_id", "record_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_crm_webhook_queue_tenant_id_idempotency_key", - table: "crm_webhook_queue", - columns: new[] { "tenant_id", "idempotency_key" }, - unique: true, - filter: "idempotency_key is not null"); - - migrationBuilder.CreateIndex( - name: "ix_crm_webhook_queue_tenant_id_legacy_id", - table: "crm_webhook_queue", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_crm_webhook_queue_tenant_id_record_id", - table: "crm_webhook_queue", - columns: new[] { "tenant_id", "record_id" }, - unique: true, - filter: "record_id is not null"); - - migrationBuilder.CreateIndex( - name: "ix_crm_webhook_queue_tenant_id_record_id_created_at", - table: "crm_webhook_queue", - columns: new[] { "tenant_id", "record_id", "created_at" }, - filter: "record_id is not null"); - - migrationBuilder.CreateIndex( - name: "ix_crm_webhook_queue_tenant_id_source_created_at", - table: "crm_webhook_queue", - columns: new[] { "tenant_id", "source", "created_at" }, - filter: "source = 'tenant.student.crm_push'"); - - migrationBuilder.CreateIndex( - name: "ix_crm_webhook_queue_tenant_id_status_scheduled_at_next_attemp~", - table: "crm_webhook_queue", - columns: new[] { "tenant_id", "status", "scheduled_at", "next_attempt_at" }); - - migrationBuilder.CreateIndex( - name: "ix_referral_codes_tenant_id_code", - table: "referral_codes", - columns: new[] { "tenant_id", "code" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_referral_codes_tenant_id_code_status", - table: "referral_codes", - columns: new[] { "tenant_id", "code", "status" }); - - migrationBuilder.CreateIndex( - name: "ix_referral_codes_tenant_id_user_id", - table: "referral_codes", - columns: new[] { "tenant_id", "user_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_referral_codes_user_id", - table: "referral_codes", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_referral_leads_assigned_by", - table: "referral_leads", - column: "assigned_by"); - - migrationBuilder.CreateIndex( - name: "ix_referral_leads_assigned_to_user_id", - table: "referral_leads", - column: "assigned_to_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_referral_leads_referrer_user_id", - table: "referral_leads", - column: "referrer_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_referral_leads_student_user_id", - table: "referral_leads", - column: "student_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_referral_leads_tenant_id_assigned_to_user_id_status_bound_at", - table: "referral_leads", - columns: new[] { "tenant_id", "assigned_to_user_id", "status", "bound_at" }); - - migrationBuilder.CreateIndex( - name: "ix_referral_leads_tenant_id_first_track_id", - table: "referral_leads", - columns: new[] { "tenant_id", "first_track_id" }); - - migrationBuilder.CreateIndex( - name: "ix_referral_leads_tenant_id_referrer_user_id_bound_at", - table: "referral_leads", - columns: new[] { "tenant_id", "referrer_user_id", "bound_at" }); - - migrationBuilder.CreateIndex( - name: "ix_referral_leads_tenant_id_student_user_id", - table: "referral_leads", - columns: new[] { "tenant_id", "student_user_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_referral_qrcodes_tenant_id_provider_scene_page", - table: "referral_qrcodes", - columns: new[] { "tenant_id", "provider", "scene", "page" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_referral_qrcodes_tenant_id_ref_code_status", - table: "referral_qrcodes", - columns: new[] { "tenant_id", "ref_code", "status" }); - - migrationBuilder.CreateIndex( - name: "ix_referral_qrcodes_user_id", - table: "referral_qrcodes", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_referral_team_edges_leader_user_id", - table: "referral_team_edges", - column: "leader_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_referral_team_edges_member_user_id", - table: "referral_team_edges", - column: "member_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_referral_team_edges_tenant_id_leader_user_id_status", - table: "referral_team_edges", - columns: new[] { "tenant_id", "leader_user_id", "status" }); - - migrationBuilder.CreateIndex( - name: "ix_referral_team_edges_tenant_id_member_user_id_relation_type", - table: "referral_team_edges", - columns: new[] { "tenant_id", "member_user_id", "relation_type" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_referral_tracks_referrer_user_id", - table: "referral_tracks", - column: "referrer_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_referral_tracks_target_user_id", - table: "referral_tracks", - column: "target_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_referral_tracks_tenant_id_lead_id_created_at", - table: "referral_tracks", - columns: new[] { "tenant_id", "lead_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_referral_tracks_tenant_id_legacy_id", - table: "referral_tracks", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_referral_tracks_tenant_id_ref_code_event_type_created_at", - table: "referral_tracks", - columns: new[] { "tenant_id", "ref_code", "event_type", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_commission_settings_tenant_id", - table: "tenant_commission_settings", - column: "tenant_id", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_commission_settings_updated_by", - table: "tenant_commission_settings", - column: "updated_by"); - - migrationBuilder.AddForeignKey( - name: "fk_referral_leads_referral_tracks_tenant_id_first_track_id", - table: "referral_leads", - columns: new[] { "tenant_id", "first_track_id" }, - principalTable: "referral_tracks", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.SetNull); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "fk_referral_leads_referral_tracks_tenant_id_first_track_id", - table: "referral_leads"); - - migrationBuilder.DropTable( - name: "commission_settlement_items"); - - migrationBuilder.DropTable( - name: "crm_config"); - - migrationBuilder.DropTable( - name: "crm_webhook_log"); - - migrationBuilder.DropTable( - name: "crm_webhook_queue"); - - migrationBuilder.DropTable( - name: "referral_codes"); - - migrationBuilder.DropTable( - name: "referral_qrcodes"); - - migrationBuilder.DropTable( - name: "referral_team_edges"); - - migrationBuilder.DropTable( - name: "tenant_commission_settings"); - - migrationBuilder.DropTable( - name: "commission_settlements"); - - migrationBuilder.DropTable( - name: "referral_tracks"); - - migrationBuilder.DropTable( - name: "referral_leads"); - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725214512_AddOperationsContentAndAuditPersistence.Designer.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725214512_AddOperationsContentAndAuditPersistence.Designer.cs deleted file mode 100644 index 32343f4..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725214512_AddOperationsContentAndAuditPersistence.Designer.cs +++ /dev/null @@ -1,12108 +0,0 @@ -// -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("20260725214512_AddOperationsContentAndAuditPersistence")] - partial class AddOperationsContentAndAuditPersistence - { - /// - 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.Commerce.ActivationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AgentUserId") - .HasColumnType("uuid") - .HasColumnName("agent_user_id"); - - b.Property("BatchId") - .HasColumnType("uuid") - .HasColumnName("batch_id"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CouponCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("coupon_code"); - - b.Property("CouponRedemptionId") - .HasColumnType("uuid") - .HasColumnName("coupon_redemption_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("IsUsed") - .HasColumnType("boolean") - .HasColumnName("is_used"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("SoldTo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("sold_to"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitPriceCents") - .HasColumnType("integer") - .HasColumnName("unit_price_cents"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("used_at"); - - b.Property("UsedBy") - .HasColumnType("uuid") - .HasColumnName("used_by"); - - b.Property("UsedRegionId") - .HasColumnType("uuid") - .HasColumnName("used_region_id"); - - b.HasKey("Id") - .HasName("pk_activation_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_activation_codes_tenant_id_id"); - - b.HasIndex("AgentUserId") - .HasDatabaseName("ix_activation_codes_agent_user_id"); - - b.HasIndex("UsedBy") - .HasDatabaseName("ix_activation_codes_used_by"); - - b.HasIndex("TenantId", "BatchId") - .HasDatabaseName("ix_activation_codes_tenant_id_batch_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_activation_codes_tenant_id_code"); - - b.HasIndex("TenantId", "CouponRedemptionId") - .HasDatabaseName("ix_activation_codes_tenant_id_coupon_redemption_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_activation_codes_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UsedRegionId") - .HasDatabaseName("ix_activation_codes_tenant_id_used_region_id"); - - b.ToTable("activation_codes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CodeBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CampaignName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("campaign_name"); - - b.Property("Channel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("channel"); - - b.Property("CommissionRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("commission_rate"); - - b.Property("CostPriceCents") - .HasColumnType("integer") - .HasColumnName("cost_price_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("DefaultUnitPriceCents") - .HasColumnType("integer") - .HasColumnName("default_unit_price_cents"); - - b.Property("IssuedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("issued_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - 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.HasKey("Id") - .HasName("pk_code_batches"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_code_batches_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_code_batches_tenant_id_legacy_id"); - - b.ToTable("code_batches", null, t => - { - t.HasCheckConstraint("ck_code_batches_amounts", "default_unit_price_cents >= 0 and cost_price_cents >= 0"); - - t.HasCheckConstraint("ck_code_batches_counts", "total_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Coupon", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DiscountType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("discount_type"); - - b.Property("DiscountValue") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("discount_value"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("MaxUses") - .HasColumnType("integer") - .HasColumnName("max_uses"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("Source") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("ValidFrom") - .HasColumnType("timestamp with time zone") - .HasColumnName("valid_from"); - - b.Property("ValidTo") - .HasColumnType("timestamp with time zone") - .HasColumnName("valid_to"); - - b.HasKey("Id") - .HasName("pk_coupons"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_coupons_tenant_id_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_coupons_tenant_id_code"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_coupons_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_coupons_tenant_id_plan_id"); - - b.ToTable("coupons", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CouponRedemption", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ClaimedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("claimed_at"); - - b.Property("CouponCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("coupon_code"); - - b.Property("CouponId") - .HasColumnType("uuid") - .HasColumnName("coupon_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DiscountAppliedCents") - .HasColumnType("integer") - .HasColumnName("discount_applied_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("Source") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("used_at"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_coupon_redemptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_coupon_redemptions_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_coupon_redemptions_user_id"); - - b.HasIndex("TenantId", "CouponId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_coupon_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_coupon_redemptions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_plan_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_region_id"); - - b.HasIndex("TenantId", "OrderId", "UserId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_order_id_user_id") - .HasFilter("order_id is not null"); - - b.HasIndex("TenantId", "UserId", "CouponId") - .IsUnique() - .HasDatabaseName("ix_coupon_redemptions_tenant_id_user_id_coupon_id") - .HasFilter("coupon_id is not null"); - - b.ToTable("coupon_redemptions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Entitlement", 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("EntitlementType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("entitlement_type"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("LegacySourceId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_source_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("StartsAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at") - .HasDefaultValueSql("now()"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_entitlements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_entitlements_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_entitlements_user_id"); - - b.HasIndex("TenantId", "UserId", "Status", "ExpiresAt") - .HasDatabaseName("ix_entitlements_tenant_id_user_id_status_expires_at"); - - b.ToTable("entitlements", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPlanId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_plan_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("OrderNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("order_no"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PayMethod") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("pay_method"); - - b.Property("PayProvider") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("pay_provider"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("ProductName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("product_name"); - - b.Property("ProductType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("product_type"); - - b.Property("RawPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("trade_no"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_orders"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_orders_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_orders_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_orders_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderNo") - .IsUnique() - .HasDatabaseName("ix_orders_tenant_id_order_no"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_orders_tenant_id_plan_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_orders_tenant_id_region_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_orders_tenant_id_user_id_created_at"); - - b.ToTable("orders", null, t => - { - t.HasCheckConstraint("ck_orders_amount", "amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.OrderItem", 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("ItemId") - .HasColumnType("uuid") - .HasColumnName("item_id"); - - b.Property("ItemType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("item_type"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("Quantity") - .HasColumnType("integer") - .HasColumnName("quantity"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalAmountCents") - .HasColumnType("integer") - .HasColumnName("total_amount_cents"); - - b.Property("UnitAmountCents") - .HasColumnType("integer") - .HasColumnName("unit_amount_cents"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_order_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_order_items_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_order_items_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderId") - .HasDatabaseName("ix_order_items_tenant_id_order_id"); - - b.ToTable("order_items", null, t => - { - t.HasCheckConstraint("ck_order_items_amounts", "unit_amount_cents >= 0 and total_amount_cents >= 0"); - - t.HasCheckConstraint("ck_order_items_quantity", "quantity > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Payment", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - 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("LegacyOrderId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_order_id"); - - b.Property("Method") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("method"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderTradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_trade_no"); - - b.Property("RawPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_payments"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_payments_tenant_id_id"); - - b.HasIndex("Provider", "ProviderTradeNo") - .IsUnique() - .HasDatabaseName("ix_payments_provider_provider_trade_no") - .HasFilter("provider_trade_no is not null"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_payments_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderId", "UpdatedAt") - .HasDatabaseName("ix_payments_tenant_id_order_id_updated_at"); - - b.ToTable("payments", null, t => - { - t.HasCheckConstraint("ck_payments_amount", "amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.PaymentEvent", 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("Error") - .HasColumnType("text") - .HasColumnName("error"); - - b.Property("EventId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("event_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("Payload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("ProcessedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("processed_at"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("SignatureValid") - .HasColumnType("boolean") - .HasColumnName("signature_valid"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_payment_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_payment_events_tenant_id_id"); - - b.HasIndex("Provider", "EventId") - .IsUnique() - .HasDatabaseName("ix_payment_events_provider_event_id"); - - b.HasIndex("TenantId", "PaymentId") - .HasDatabaseName("ix_payment_events_tenant_id_payment_id"); - - b.ToTable("payment_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Product", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Cover") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cover"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DetailImages") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("detail_images") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPriceText") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("legacy_price_text"); - - b.Property("Link") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("link"); - - b.Property("PreviewIframe") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("preview_iframe"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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_products"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_products_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_products_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "Type", "SortOrder") - .HasDatabaseName("ix_products_tenant_id_region_id_type_sort_order"); - - b.ToTable("products", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.SvipPlan", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Badge") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("badge"); - - b.Property("CouponOnly") - .HasColumnType("boolean") - .HasColumnName("coupon_only"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - 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(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OriginalPriceCents") - .HasColumnType("integer") - .HasColumnName("original_price_cents"); - - b.Property("PerDayLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("per_day_label"); - - b.Property("PriceCents") - .HasColumnType("integer") - .HasColumnName("price_cents"); - - b.Property("Recommended") - .HasColumnType("boolean") - .HasColumnName("recommended"); - - 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("VpEnabled") - .HasColumnType("boolean") - .HasColumnName("vp_enabled"); - - b.Property("VpProductId") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("vp_product_id"); - - b.HasKey("Id") - .HasName("pk_svip_plans"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_svip_plans_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_svip_plans_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_svip_plans_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("svip_plans", null, t => - { - t.HasCheckConstraint("ck_svip_plans_days", "days >= 0"); - - t.HasCheckConstraint("ck_svip_plans_price", "price_cents >= 0 and (original_price_cents is null or original_price_cents >= 0)"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantPaymentAccount", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ConfigPublic") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("config_public") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_payment_accounts"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_payment_accounts_tenant_id_id"); - - b.HasIndex("TenantId", "Provider") - .IsUnique() - .HasDatabaseName("ix_tenant_payment_accounts_tenant_id_provider"); - - b.ToTable("tenant_payment_accounts", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantSubscription", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("BillingCycle") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("billing_cycle"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PlanCode") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("plan_code"); - - b.Property("StartsAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_subscriptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_subscriptions_tenant_id_id"); - - b.HasIndex("TenantId", "Status", "ExpiresAt") - .HasDatabaseName("ix_tenant_subscriptions_tenant_id_status_expires_at"); - - b.ToTable("tenant_subscriptions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantUsageRecord", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("MetricKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("metric_key"); - - b.Property("MetricValue") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)") - .HasColumnName("metric_value"); - - b.Property("PeriodEnd") - .HasColumnType("date") - .HasColumnName("period_end"); - - b.Property("PeriodStart") - .HasColumnType("date") - .HasColumnName("period_start"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_tenant_usage_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_usage_records_tenant_id_id"); - - b.HasIndex("TenantId", "MetricKey", "PeriodStart", "PeriodEnd") - .HasDatabaseName("ix_tenant_usage_records_tenant_id_metric_key_period_start_peri~"); - - b.ToTable("tenant_usage_records", (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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_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_handbook_chapters"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_chapters_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_chapters_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_subject_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_chapters_tenant_id_entry_id_content_node_id_subjec~"); - - b.ToTable("handbook_chapters", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ChapterId") - .HasColumnType("uuid") - .HasColumnName("chapter_id"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Summary") - .HasColumnType("text") - .HasColumnName("summary"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_handbook_entries"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_entries_tenant_id_id"); - - b.HasIndex("TenantId", "ChapterId") - .HasDatabaseName("ix_handbook_entries_tenant_id_chapter_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_entries_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_entries_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "ChapterId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_entries_tenant_id_entry_id_content_node_id_chapter~"); - - b.ToTable("handbook_entries", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", 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("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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - 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_handbook_subjects"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_subjects_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_subjects_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "MajorId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_major_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_school_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_subjects_tenant_id_entry_id_content_node_id_region~"); - - b.ToTable("handbook_subjects", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("CdnUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cdn_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FileName") - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("file_name"); - - 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("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.HasKey("Id") - .HasName("pk_images"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_images_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_images_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "Category", "IsPublic") - .HasDatabaseName("ix_images_tenant_id_category_is_public"); - - b.ToTable("images", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", 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("AssemblyType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assembly_type"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_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("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PassScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("pass_score"); - - b.Property("QuestionLimit") - .HasColumnType("integer") - .HasColumnName("question_limit"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Rules") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("rules") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Sections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sections") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_practice_blueprints"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_blueprints_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_practice_blueprints_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_practice_blueprints_updated_by"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_collection_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_practice_blueprints_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_region_id"); - - b.HasIndex("TenantId", "NodeId", "CollectionId", "Mode", "Status", "SortOrder") - .HasDatabaseName("ix_practice_blueprints_tenant_id_node_id_collection_id_mode_st~"); - - b.ToTable("practice_blueprints", null, t => - { - t.HasCheckConstraint("ck_practice_blueprints_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_practice_blueprints_question_limit", "question_limit is null or question_limit > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", 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("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - b.Property("CollectionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("collection_type"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Filters") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("filters") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_question_collections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collections_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_collections_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_question_collections_updated_by"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_question_collections_tenant_id_category_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_question_collections_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_collections_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_question_collections_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_collections_tenant_id_region_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_question_collections_tenant_id_subject_id"); - - b.HasIndex("TenantId", "NodeId", "Status", "SortOrder") - .HasDatabaseName("ix_question_collections_tenant_id_node_id_status_sort_order"); - - b.ToTable("question_collections", null, t => - { - t.HasCheckConstraint("ck_question_collections_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_question_collections_question_count", "question_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Required") - .HasColumnType("boolean") - .HasColumnName("required"); - - b.Property("Score") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - 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_question_collection_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collection_items_tenant_id_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_question_collection_items_tenant_id_question_id"); - - b.HasIndex("TenantId", "CollectionId", "QuestionId") - .IsUnique() - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_question_~"); - - b.HasIndex("TenantId", "CollectionId", "SectionKey", "SortOrder") - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_section_k~"); - - b.ToTable("question_collection_items", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", 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("DisplayName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Types") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("types") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_question_type_groups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_type_groups_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_type_groups_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_question_type_groups_tenant_id_subject_id_is_active_sort_or~"); - - b.ToTable("question_type_groups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", 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("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("LegacyVideoId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_video_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_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("VideoId") - .HasColumnType("uuid") - .HasColumnName("video_id"); - - b.Property("VideoType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("video_type"); - - b.HasKey("Id") - .HasName("pk_question_videos"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_videos_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "VideoId") - .HasDatabaseName("ix_question_videos_tenant_id_video_id"); - - b.HasIndex("TenantId", "QuestionId", "VideoId", "VideoType") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_question_id_video_id_video_type"); - - b.ToTable("question_videos", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("SourceSubjectId") - .HasColumnType("uuid") - .HasColumnName("source_subject_id"); - - b.Property("TargetSubjectId") - .HasColumnType("uuid") - .HasColumnName("target_subject_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Id") - .HasColumnType("uuid") - .HasColumnName("id"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacySourceSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_source_subject_id"); - - b.Property("LegacyTargetSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_target_subject_id"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at"); - - b.HasKey("TenantId", "SourceSubjectId", "TargetSubjectId") - .HasName("pk_subject_shares"); - - b.HasIndex("TenantId", "TargetSubjectId") - .HasDatabaseName("ix_subject_shares_tenant_id_target_subject_id"); - - b.ToTable("subject_shares", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", 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("FavoritedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("favorited_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Note") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.HasKey("Id") - .HasName("pk_user_word_favorites"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_favorites_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_favorites_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_favorites_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_favorites_tenant_id_user_id_word_id"); - - b.ToTable("user_word_favorites", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CorrectStreak") - .HasColumnType("integer") - .HasColumnName("correct_streak"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DueLevel") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("due_level"); - - b.Property("EaseFactor") - .ValueGeneratedOnAdd() - .HasPrecision(4, 2) - .HasColumnType("numeric(4,2)") - .HasDefaultValue(2.50m) - .HasColumnName("ease_factor"); - - b.Property("LastResult") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("last_result"); - - b.Property("LastReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_review_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NextReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_review_at"); - - b.Property("ReviewCount") - .HasColumnType("integer") - .HasColumnName("review_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_user_word_progress"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_progress_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_progress_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_progress_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_word_id"); - - b.HasIndex("TenantId", "UserId", "NextReviewAt", "Status", "DueLevel") - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_next_review_at_status_~"); - - b.ToTable("user_word_progress", null, t => - { - t.HasCheckConstraint("ck_user_word_progress_correct_streak", "correct_streak >= 0"); - - t.HasCheckConstraint("ck_user_word_progress_ease_factor", "ease_factor >= 1.30 and ease_factor <= 3.00"); - - t.HasCheckConstraint("ck_user_word_progress_review_count", "review_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("IsGeneral") - .HasColumnType("boolean") - .HasColumnName("is_general"); - - b.Property("KnowledgeTags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("knowledge_tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ThumbnailUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("thumbnail_url"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VideoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("video_url"); - - b.HasKey("Id") - .HasName("pk_video_explanations"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_video_explanations_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_video_explanations_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SourceHash") - .HasDatabaseName("ix_video_explanations_tenant_id_source_hash") - .HasFilter("source_hash is not null"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_video_explanations_tenant_id_subject_id_is_active_sort_order"); - - b.ToTable("video_explanations", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WordCount") - .HasColumnType("integer") - .HasColumnName("word_count"); - - b.HasKey("Id") - .HasName("pk_vocabulary_units"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_units_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_units_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_region_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_units_tenant_id_entry_id_content_node_id_region_~"); - - b.ToTable("vocabulary_units", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Example") - .HasColumnType("text") - .HasColumnName("example"); - - b.Property("ExampleTranslation") - .HasColumnType("text") - .HasColumnName("example_translation"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Meaning") - .HasColumnType("text") - .HasColumnName("meaning"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phonetic") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("phonetic"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitId") - .HasColumnType("uuid") - .HasColumnName("unit_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Word") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("word"); - - b.HasKey("Id") - .HasName("pk_vocabulary_words"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_words_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_words_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_words_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UnitId", "IsActive", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_vocabulary_words_tenant_id_unit_id_is_active_sort_order_cre~"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "UnitId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_words_tenant_id_entry_id_content_node_id_unit_id~"); - - b.ToTable("vocabulary_words", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlement", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CommissionAmountCents") - .HasColumnType("integer") - .HasColumnName("commission_amount_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DefaultRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("default_rate"); - - b.Property("EffectiveRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("effective_rate"); - - b.Property("GeneratedBy") - .HasColumnType("uuid") - .HasColumnName("generated_by"); - - b.Property("GrossAmountCents") - .HasColumnType("integer") - .HasColumnName("gross_amount_cents"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PaidBy") - .HasColumnType("uuid") - .HasColumnName("paid_by"); - - b.Property("PaidUserCount") - .HasColumnType("integer") - .HasColumnName("paid_user_count"); - - b.Property("PaymentAccount") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("payment_account"); - - b.Property("PaymentMethod") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("payment_method"); - - b.Property("PeriodEnd") - .HasColumnType("date") - .HasColumnName("period_end"); - - b.Property("PeriodStart") - .HasColumnType("date") - .HasColumnName("period_start"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("ReviewedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("reviewed_at"); - - b.Property("ReviewedBy") - .HasColumnType("uuid") - .HasColumnName("reviewed_by"); - - b.Property("SettlementNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("settlement_no"); - - b.Property("SourceCount") - .HasColumnType("integer") - .HasColumnName("source_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_commission_settlements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commission_settlements_tenant_id_id"); - - b.HasIndex("GeneratedBy") - .HasDatabaseName("ix_commission_settlements_generated_by"); - - b.HasIndex("PaidBy") - .HasDatabaseName("ix_commission_settlements_paid_by"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_commission_settlements_referrer_user_id"); - - b.HasIndex("ReviewedBy") - .HasDatabaseName("ix_commission_settlements_reviewed_by"); - - b.HasIndex("TenantId", "SettlementNo") - .IsUnique() - .HasDatabaseName("ix_commission_settlements_tenant_id_settlement_no"); - - b.HasIndex("TenantId", "ReferrerUserId", "PeriodStart") - .HasDatabaseName("ix_commission_settlements_referrer_start"); - - b.HasIndex("TenantId", "ReferrerUserId", "PeriodStart", "PeriodEnd") - .IsUnique() - .HasDatabaseName("ux_commission_settlements_referrer_period"); - - b.ToTable("commission_settlements", null, t => - { - t.HasCheckConstraint("ck_commission_settlements_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commission_settlements_counts", "source_count >= 0 and paid_user_count >= 0"); - - t.HasCheckConstraint("ck_commission_settlements_period", "period_end >= period_start"); - - t.HasCheckConstraint("ck_commission_settlements_rates", "default_rate >= 0 and default_rate <= 1 and (effective_rate is null or (effective_rate >= 0 and effective_rate <= 1))"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlementItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AttributionType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("attribution_type"); - - b.Property("CommissionAmountCents") - .HasColumnType("integer") - .HasColumnName("commission_amount_cents"); - - b.Property("CommissionRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("commission_rate"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("GrossAmountCents") - .HasColumnType("integer") - .HasColumnName("gross_amount_cents"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RateSource") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("rate_source"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("SettlementId") - .HasColumnType("uuid") - .HasColumnName("settlement_id"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_no"); - - b.Property("SourcePaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("source_paid_at"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_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_commission_settlement_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commission_settlement_items_tenant_id_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_commission_settlement_items_referrer_user_id"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_commission_settlement_items_student_user_id"); - - b.HasIndex("TenantId", "SettlementId") - .HasDatabaseName("ix_commission_settlement_items_tenant_id_settlement_id"); - - b.HasIndex("TenantId", "ReferrerUserId", "SourcePaidAt") - .HasDatabaseName("ix_commission_settlement_items_tenant_id_referrer_user_id_sour~"); - - b.HasIndex("TenantId", "SourceType", "SourceId") - .IsUnique() - .HasDatabaseName("ix_commission_settlement_items_tenant_id_source_type_source_id"); - - b.ToTable("commission_settlement_items", null, t => - { - t.HasCheckConstraint("ck_commission_settlement_items_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commission_settlement_items_rate", "commission_rate >= 0 and commission_rate <= 1"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignmentConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("assignment_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("AssignmentCursor") - .HasColumnType("integer") - .HasColumnName("assignment_cursor"); - - b.Property("AssignmentMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assignment_mode"); - - b.Property("AssignmentPool") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("assignment_pool") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DelaySeconds") - .HasColumnType("integer") - .HasColumnName("delay_seconds"); - - b.Property("Enabled") - .HasColumnType("boolean") - .HasColumnName("enabled"); - - b.Property("ExamType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("exam_type"); - - b.Property("FormName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("form_name"); - - b.Property("SecretRef") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("secret_ref"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TimeoutSeconds") - .HasColumnType("integer") - .HasColumnName("timeout_seconds"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Url") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("url"); - - b.HasKey("Id") - .HasName("pk_crm_config"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_config_tenant_id_id"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_crm_config_tenant_id"); - - b.HasIndex("TenantId", "AssignmentMode") - .HasDatabaseName("ix_crm_config_tenant_id_assignment_mode"); - - b.ToTable("crm_config", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempt") - .HasColumnType("integer") - .HasColumnName("attempt"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ErrorMessage") - .HasColumnType("text") - .HasColumnName("error_message"); - - b.Property("HttpCode") - .HasColumnType("integer") - .HasColumnName("http_code"); - - b.Property("LeadId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Outcome") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("outcome"); - - b.Property("RecordId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("record_id"); - - b.Property("RequestBody") - .HasColumnType("text") - .HasColumnName("request_body"); - - b.Property("RequestPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("request_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ResponseSummary") - .HasMaxLength(2000) - .HasColumnType("character varying(2000)") - .HasColumnName("response_summary"); - - b.Property("SignedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("signed_at"); - - 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_crm_webhook_log"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_webhook_log_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_log_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RecordId", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_log_tenant_id_record_id_created_at"); - - b.ToTable("crm_webhook_log", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookQueueItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempts") - .HasColumnType("integer") - .HasColumnName("attempts"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IdempotencyKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("idempotency_key"); - - b.Property("LastAttemptAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_attempt_at"); - - b.Property("LastError") - .HasColumnType("text") - .HasColumnName("last_error"); - - b.Property("LastHttpCode") - .HasColumnType("integer") - .HasColumnName("last_http_code"); - - b.Property("LastResponseSummary") - .HasColumnType("text") - .HasColumnName("last_response_summary"); - - b.Property("LeadId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("NextAttemptAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_attempt_at"); - - b.Property("Payload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("RecordId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("record_id"); - - b.Property("ScheduledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("scheduled_at"); - - b.Property("SentAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("sent_at"); - - b.Property("Source") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TargetUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("target_url"); - - 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_crm_webhook_queue"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_webhook_queue_tenant_id_id"); - - b.HasIndex("TenantId", "IdempotencyKey") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_idempotency_key") - .HasFilter("idempotency_key is not null"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RecordId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_record_id") - .HasFilter("record_id is not null"); - - b.HasIndex("TenantId", "RecordId", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_record_id_created_at") - .HasFilter("record_id is not null"); - - b.HasIndex("TenantId", "Source", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_source_created_at") - .HasFilter("source = 'tenant.student.crm_push'"); - - b.HasIndex("TenantId", "Status", "ScheduledAt", "NextAttemptAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_status_scheduled_at_next_attemp~"); - - b.ToTable("crm_webhook_queue", null, t => - { - t.HasCheckConstraint("ck_crm_webhook_queue_attempts", "attempts >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Channel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("channel"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("LandingPath") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("landing_path"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_referral_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_codes_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_referral_codes_user_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_referral_codes_tenant_id_code"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_referral_codes_tenant_id_user_id"); - - b.HasIndex("TenantId", "Code", "Status") - .HasDatabaseName("ix_referral_codes_tenant_id_code_status"); - - b.ToTable("referral_codes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralLead", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("assigned_at"); - - b.Property("AssignedBy") - .HasColumnType("uuid") - .HasColumnName("assigned_by"); - - b.Property("AssignedToUserId") - .HasColumnType("uuid") - .HasColumnName("assigned_to_user_id"); - - b.Property("AssignmentMode") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assignment_mode"); - - b.Property("BindType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("bind_type"); - - b.Property("BoundAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("bound_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FirstTrackId") - .HasColumnType("uuid") - .HasColumnName("first_track_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ProtectedUntil") - .HasColumnType("timestamp with time zone") - .HasColumnName("protected_until"); - - b.Property("RefCode") - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Source") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_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_referral_leads"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_leads_tenant_id_id"); - - b.HasIndex("AssignedBy") - .HasDatabaseName("ix_referral_leads_assigned_by"); - - b.HasIndex("AssignedToUserId") - .HasDatabaseName("ix_referral_leads_assigned_to_user_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_referral_leads_referrer_user_id"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_referral_leads_student_user_id"); - - b.HasIndex("TenantId", "FirstTrackId") - .HasDatabaseName("ix_referral_leads_tenant_id_first_track_id"); - - b.HasIndex("TenantId", "StudentUserId") - .IsUnique() - .HasDatabaseName("ix_referral_leads_tenant_id_student_user_id"); - - b.HasIndex("TenantId", "ReferrerUserId", "BoundAt") - .HasDatabaseName("ix_referral_leads_tenant_id_referrer_user_id_bound_at"); - - b.HasIndex("TenantId", "AssignedToUserId", "Status", "BoundAt") - .HasDatabaseName("ix_referral_leads_tenant_id_assigned_to_user_id_status_bound_at"); - - b.ToTable("referral_leads", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralQrcode", 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("ErrorMessage") - .HasColumnType("text") - .HasColumnName("error_message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Page") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("page"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("QrcodeUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("qrcode_url"); - - b.Property("RefCode") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("Scene") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("scene"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_referral_qrcodes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_qrcodes_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_referral_qrcodes_user_id"); - - b.HasIndex("TenantId", "RefCode", "Status") - .HasDatabaseName("ix_referral_qrcodes_tenant_id_ref_code_status"); - - b.HasIndex("TenantId", "Provider", "Scene", "Page") - .IsUnique() - .HasDatabaseName("ix_referral_qrcodes_tenant_id_provider_scene_page"); - - b.ToTable("referral_qrcodes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTeamEdge", 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("LeaderUserId") - .HasColumnType("uuid") - .HasColumnName("leader_user_id"); - - b.Property("MemberUserId") - .HasColumnType("uuid") - .HasColumnName("member_user_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RelationType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("relation_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_referral_team_edges"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_team_edges_tenant_id_id"); - - b.HasIndex("LeaderUserId") - .HasDatabaseName("ix_referral_team_edges_leader_user_id"); - - b.HasIndex("MemberUserId") - .HasDatabaseName("ix_referral_team_edges_member_user_id"); - - b.HasIndex("TenantId", "LeaderUserId", "Status") - .HasDatabaseName("ix_referral_team_edges_tenant_id_leader_user_id_status"); - - b.HasIndex("TenantId", "MemberUserId", "RelationType") - .IsUnique() - .HasDatabaseName("ix_referral_team_edges_tenant_id_member_user_id_relation_type"); - - b.ToTable("referral_team_edges", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTrack", 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("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("IpAddress") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("ip_address"); - - b.Property("LeadId") - .HasColumnType("uuid") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RefCode") - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Source") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source"); - - b.Property("TargetUserId") - .HasColumnType("uuid") - .HasColumnName("target_user_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserAgent") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_referral_tracks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_tracks_tenant_id_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_referral_tracks_referrer_user_id"); - - b.HasIndex("TargetUserId") - .HasDatabaseName("ix_referral_tracks_target_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_referral_tracks_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "LeadId", "CreatedAt") - .HasDatabaseName("ix_referral_tracks_tenant_id_lead_id_created_at"); - - b.HasIndex("TenantId", "RefCode", "EventType", "CreatedAt") - .HasDatabaseName("ix_referral_tracks_tenant_id_ref_code_event_type_created_at"); - - b.ToTable("referral_tracks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.TenantCommissionSetting", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - 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("DefaultRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("default_rate"); - - b.Property("MinSettlementCents") - .HasColumnType("integer") - .HasColumnName("min_settlement_cents"); - - b.Property("SettlementCycle") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("settlement_cycle"); - - 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_tenant_commission_settings"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_commission_settings_tenant_id_id"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_tenant_commission_settings_tenant_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_commission_settings_updated_by"); - - b.ToTable("tenant_commission_settings", null, t => - { - t.HasCheckConstraint("ck_tenant_commission_settings_default_rate", "default_rate >= 0 and default_rate <= 1"); - - t.HasCheckConstraint("ck_tenant_commission_settings_min_settlement", "min_settlement_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", 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("LastCheckInDate") - .HasColumnType("date") - .HasColumnName("last_check_in_date"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("MasteredWordsCount") - .HasColumnType("integer") - .HasColumnName("mastered_words_count"); - - b.Property("ModuleSelections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_selections") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Progress") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("progress") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionsAnsweredToday") - .HasColumnType("integer") - .HasColumnName("questions_answered_today"); - - b.Property("RecentActivities") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("recent_activities") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SelectedMajorId") - .HasColumnType("uuid") - .HasColumnName("selected_major_id"); - - b.Property("SelectedSchoolId") - .HasColumnType("uuid") - .HasColumnName("selected_school_id"); - - b.Property("Stats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("stats") - .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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_student_profiles"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_student_profiles_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_student_profiles_user_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_student_profiles_tenant_id_region_id"); - - b.HasIndex("TenantId", "SelectedMajorId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_major_id"); - - b.HasIndex("TenantId", "SelectedSchoolId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_school_id"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_student_profiles_tenant_id_user_id"); - - b.ToTable("student_profiles", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AvatarUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("avatar_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("LastSeenAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_seen_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPasswordHash") - .HasMaxLength(512) - .HasColumnType("character varying(512)") - .HasColumnName("legacy_password_hash"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PasswordMigrationRequired") - .HasColumnType("boolean") - .HasColumnName("password_migration_required"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("PrimaryRole") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("primary_role"); - - b.Property("RawProfile") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_profile") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Score") - .HasColumnType("integer") - .HasColumnName("score"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Username") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("username"); - - b.HasKey("Id") - .HasName("pk_users"); - - b.HasIndex("Email") - .IsUnique() - .HasDatabaseName("ix_users_email"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_users_legacy_id"); - - b.HasIndex("Phone") - .IsUnique() - .HasDatabaseName("ix_users_phone"); - - b.HasIndex("Username") - .IsUnique() - .HasDatabaseName("ix_users_username"); - - b.ToTable("users", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", 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("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("OpenId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("open_id"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderSubject") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("provider_subject"); - - b.Property("SecretPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("secret_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UnionId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("union_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_identities"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_identities_user_id"); - - b.HasIndex("Provider", "ProviderSubject") - .IsUnique() - .HasDatabaseName("ix_user_identities_provider_provider_subject"); - - b.ToTable("user_identities", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("AnsweredAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("answered_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IsCorrect") - .HasColumnType("boolean") - .HasColumnName("is_correct"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("QuestionVersionId") - .HasColumnType("uuid") - .HasColumnName("question_version_id"); - - b.Property("SelectedOptions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("selected_options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_answer_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_answer_records_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_answer_records_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_answer_records_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id"); - - b.HasIndex("TenantId", "QuestionId", "QuestionVersionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id_question_version_id"); - - b.HasIndex("TenantId", "UserId", "PracticeSessionId") - .HasDatabaseName("ix_answer_records_tenant_id_user_id_practice_session_id"); - - b.ToTable("answer_records", null, t => - { - t.HasCheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActiveUsers") - .HasColumnType("integer") - .HasColumnName("active_users"); - - 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("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("NewOrders") - .HasColumnType("integer") - .HasColumnName("new_orders"); - - b.Property("NewQuestions") - .HasColumnType("integer") - .HasColumnName("new_questions"); - - b.Property("NewRevenueCents") - .HasColumnType("integer") - .HasColumnName("new_revenue_cents"); - - b.Property("NewUsers") - .HasColumnType("integer") - .HasColumnName("new_users"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_dashboard_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_dashboard_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_stat_date_region_id"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId"), false); - - b.ToTable("dashboard_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", 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("ExamAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("exam_at"); - - b.Property("ExamName") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("exam_name"); - - b.Property("ExamType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("exam_type"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("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_exam_dates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_exam_dates_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_exam_dates_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_exam_dates_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId", "ExamAt") - .HasDatabaseName("ix_exam_dates_tenant_id_school_id_exam_at"); - - b.ToTable("exam_dates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_favorite_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_favorite_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_favorite_questions_tenant_id_question_id"); - - b.ToTable("favorite_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("access_mode"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EntitlementId") - .HasColumnType("uuid") - .HasColumnName("entitlement_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("GrantedCount") - .HasColumnType("integer") - .HasColumnName("granted_count"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("Reason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("reason"); - - b.Property("RequestedCount") - .HasColumnType("integer") - .HasColumnName("requested_count"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_access_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_access_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_access_events_user_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_access_events_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_practice_access_events_tenant_id_user_id_created_at"); - - b.ToTable("practice_access_events", null, t => - { - t.HasCheckConstraint("ck_practice_access_events_consumed_free_quota", "consumed_free_quota >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_granted_count", "granted_count >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_requested_count", "requested_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", 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("FreeLimit") - .HasColumnType("integer") - .HasColumnName("free_limit"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsageDate") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasColumnName("usage_date") - .HasDefaultValueSql("current_date"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_daily_usage"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_daily_usage_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_daily_usage_user_id"); - - b.HasIndex("TenantId", "UserId", "UsageDate") - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date"); - - b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId") - .IsUnique() - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date_scope_typ~"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId"), false); - - b.ToTable("practice_daily_usage", null, t => - { - t.HasCheckConstraint("ck_practice_daily_usage_free_limit", "free_limit >= 0"); - - t.HasCheckConstraint("ck_practice_daily_usage_used_count", "used_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessEntitlementId") - .HasColumnType("uuid") - .HasColumnName("access_entitlement_id"); - - b.Property("AccessMode") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasDefaultValue("free") - .HasColumnName("access_mode"); - - b.Property("AccessSnapshot") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("access_snapshot") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("ContentNodeId") - .HasColumnType("uuid") - .HasColumnName("content_node_id"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("FinishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("finished_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at") - .HasDefaultValueSql("now()"); - - b.Property("TargetId") - .HasColumnType("uuid") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_sessions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "UserId", "Id") - .HasName("ak_practice_sessions_tenant_id_user_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_sessions_user_id"); - - b.HasIndex("TenantId", "BlueprintId") - .HasDatabaseName("ix_practice_sessions_tenant_id_blueprint_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_sessions_tenant_id_collection_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_practice_sessions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_sessions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "UserId", "StartedAt") - .HasDatabaseName("ix_practice_sessions_tenant_id_user_id_started_at"); - - b.ToTable("practice_sessions", null, t => - { - t.HasCheckConstraint("ck_practice_sessions_consumed_free_quota", "consumed_free_quota >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionResults") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_results") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionStats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("section_stats") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at"); - - b.Property("SubmittedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("submitted_at") - .HasDefaultValueSql("now()"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalQuestions") - .HasColumnType("integer") - .HasColumnName("total_questions"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.Property("WrongQuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("wrong_question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.HasKey("Id") - .HasName("pk_practice_session_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_reports_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_session_reports_user_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_session_reports_tenant_id_collection_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .IsUnique() - .HasDatabaseName("ix_practice_session_reports_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "BlueprintId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_blueprint_id_submitted_at") - .HasFilter("blueprint_id is not null"); - - b.HasIndex("TenantId", "UserId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_user_id_submitted_at"); - - b.ToTable("practice_session_reports", null, t => - { - t.HasCheckConstraint("ck_practice_session_reports_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_reports_counts", "total_questions >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_duration", "duration_seconds >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("question_type"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - b.Property("SectionName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("section_name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_practice_session_report_sections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_report_sections_tenant_id_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_practice_session~"); - - b.HasIndex("TenantId", "ReportId", "SectionKey") - .IsUnique() - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sectio~"); - - b.HasIndex("TenantId", "ReportId", "SortOrder") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sort_o~"); - - b.ToTable("practice_session_report_sections", null, t => - { - t.HasCheckConstraint("ck_practice_session_report_sections_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_report_sections_counts", "question_count >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_report_sections_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", 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("LastAccessAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_access_at"); - - b.Property("LastPracticeAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_practice_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("practice_type"); - - b.Property("Progress") - .HasColumnType("integer") - .HasColumnName("progress"); - - b.Property("TargetLegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("target_legacy_id"); - - b.Property("TargetName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("target_name"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_recent_practices"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_recent_practices_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_recent_practices_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_recent_practices_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "LastAccessAt") - .HasDatabaseName("ix_recent_practices_tenant_id_user_id_last_access_at"); - - b.ToTable("recent_practices", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attachments") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("attachments") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("Contact") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("contact"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("HandledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("handled_at"); - - b.Property("HandledBy") - .HasColumnType("uuid") - .HasColumnName("handled_by"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Resolution") - .HasColumnType("text") - .HasColumnName("resolution"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_reports_tenant_id_id"); - - b.HasIndex("HandledBy") - .HasDatabaseName("ix_reports_handled_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_reports_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_reports_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_question_id_created_at") - .HasFilter("question_id is not null"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_status_created_at"); - - b.ToTable("reports", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_report_status_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_report_status_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_report_status_events_actor_user_id"); - - b.HasIndex("TenantId", "ReportId", "CreatedAt") - .HasDatabaseName("ix_report_status_events_tenant_id_report_id_created_at"); - - b.ToTable("report_status_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CodeCount") - .HasColumnType("integer") - .HasColumnName("code_count"); - - b.Property("CodeEstimated") - .HasColumnType("integer") - .HasColumnName("code_estimated"); - - b.Property("CodeUsed") - .HasColumnType("integer") - .HasColumnName("code_used"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EstimatedRevenueCents") - .HasColumnType("integer") - .HasColumnName("estimated_revenue_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("OrderCount") - .HasColumnType("integer") - .HasColumnName("order_count"); - - b.Property("RealRevenueCents") - .HasColumnType("integer") - .HasColumnName("real_revenue_cents"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_revenue_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_revenue_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_stat_date_region_id_sale_type"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType"), false); - - b.ToTable("revenue_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BalanceAfter") - .HasColumnType("integer") - .HasColumnName("balance_after"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("IdempotencyKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("idempotency_key"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Points") - .HasColumnType("integer") - .HasColumnName("points"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_score_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_score_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_score_events_user_id"); - - b.HasIndex("TenantId", "IdempotencyKey") - .IsUnique() - .HasDatabaseName("ix_user_score_events_tenant_id_idempotency_key"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_user_score_events_tenant_id_user_id_created_at"); - - b.ToTable("user_score_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("LastWrongAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("last_wrong_at") - .HasDefaultValueSql("now()"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("WrongCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(1) - .HasColumnName("wrong_count"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_wrong_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_wrong_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_wrong_questions_tenant_id_question_id"); - - b.ToTable("wrong_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Announcement", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BackgroundColor") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("background_color"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("Link") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("link"); - - 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_announcements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_announcements_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_announcements_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "IsActive", "SortOrder") - .HasDatabaseName("ix_announcements_tenant_id_is_active_sort_order"); - - b.ToTable("announcements", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.AuditLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Action") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("action"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - 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("IpAddress") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("ip_address"); - - b.Property("TargetId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_audit_logs"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_audit_logs_actor_user_id"); - - b.HasIndex("TenantId", "CreatedAt") - .HasDatabaseName("ix_audit_logs_tenant_id_created_at"); - - b.HasIndex("TenantId", "TargetType", "TargetId", "CreatedAt") - .HasDatabaseName("ix_audit_logs_tenant_id_target_type_target_id_created_at"); - - b.ToTable("audit_logs", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Badge", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("ConditionExtra") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("condition_extra") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ConditionField") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("condition_field"); - - b.Property("ConditionOperator") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("condition_operator"); - - b.Property("ConditionValue") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)") - .HasColumnName("condition_value"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("IconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("icon_url"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Level") - .HasColumnType("integer") - .HasColumnName("level"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnlockType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("unlock_type"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_badges"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_badges_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_badges_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "Category", "IsActive", "SortOrder") - .HasDatabaseName("ix_badges_tenant_id_category_is_active_sort_order"); - - b.ToTable("badges", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Banner", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BackgroundColor") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("background_color"); - - b.Property("BorderColor") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("border_color"); - - b.Property("ButtonLink") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("button_link"); - - b.Property("ButtonText") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("button_text"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Subtitle") - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("subtitle"); - - 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.HasKey("Id") - .HasName("pk_banners"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_banners_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_banners_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_banners_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("banners", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Faq", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Answer") - .HasColumnType("text") - .HasColumnName("answer"); - - 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("Question") - .HasColumnType("text") - .HasColumnName("question"); - - 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.HasKey("Id") - .HasName("pk_faqs"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_faqs_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_faqs_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_faqs_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("faqs", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantContentNotification", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActionLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("action_label"); - - b.Property("ActionPath") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("action_path"); - - b.Property("AdoptionId") - .HasColumnType("uuid") - .HasColumnName("adoption_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("DedupeKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("dedupe_key"); - - b.Property("Message") - .IsRequired() - .HasColumnType("text") - .HasColumnName("message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NotificationType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("notification_type"); - - b.Property("ReadAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("read_at"); - - b.Property("ReadBy") - .HasColumnType("uuid") - .HasColumnName("read_by"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("Severity") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("severity"); - - b.Property("SourceQuestionBankId") - .HasColumnType("uuid") - .HasColumnName("source_question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenant_content_notifications"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_content_notifications_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_content_notifications_created_by"); - - b.HasIndex("ReadBy") - .HasDatabaseName("ix_tenant_content_notifications_read_by"); - - b.HasIndex("TenantId", "SourceQuestionBankId") - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_source_question_bank~"); - - b.HasIndex("TenantId", "NotificationType", "DedupeKey") - .IsUnique() - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_notification_type_de~") - .HasFilter("dedupe_key is not null"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_status_created_at"); - - b.HasIndex("TenantId", "AdoptionId", "NotificationType", "Status") - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_adoption_id_notifica~"); - - b.ToTable("tenant_content_notifications", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantThemeConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActivePublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("active_public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ActiveTemplateCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("active_template_code"); - - b.Property("ActiveTheme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("active_theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DraftPublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("draft_public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("DraftTemplateCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("draft_template_code"); - - b.Property("DraftTheme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("draft_theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("DraftUpdatedBy") - .HasColumnType("uuid") - .HasColumnName("draft_updated_by"); - - b.Property("PublishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("published_at"); - - b.Property("PublishedBy") - .HasColumnType("uuid") - .HasColumnName("published_by"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_theme_configs"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_theme_configs_tenant_id_id"); - - b.HasIndex("ActiveTemplateCode") - .HasDatabaseName("ix_tenant_theme_configs_active_template_code"); - - b.HasIndex("DraftTemplateCode") - .HasDatabaseName("ix_tenant_theme_configs_draft_template_code"); - - b.HasIndex("DraftUpdatedBy") - .HasDatabaseName("ix_tenant_theme_configs_draft_updated_by"); - - b.HasIndex("PublishedBy") - .HasDatabaseName("ix_tenant_theme_configs_published_by"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_tenant_theme_configs_tenant_id"); - - b.ToTable("tenant_theme_configs", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantThemeTemplate", 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("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PreviewImageUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("preview_image_url"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenant_theme_templates"); - - b.HasAlternateKey("Code") - .HasName("ak_tenant_theme_templates_code"); - - b.HasIndex("Code") - .IsUnique() - .HasDatabaseName("ix_tenant_theme_templates_code"); - - b.HasIndex("Status", "SortOrder", "Code") - .HasDatabaseName("ix_tenant_theme_templates_status_sort_order_code"); - - b.ToTable("tenant_theme_templates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserBadge", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BadgeId") - .HasColumnType("uuid") - .HasColumnName("badge_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("GrantedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("granted_at"); - - b.Property("GrantedBy") - .HasColumnType("uuid") - .HasColumnName("granted_by"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_badges"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_badges_tenant_id_id"); - - b.HasIndex("GrantedBy") - .HasDatabaseName("ix_user_badges_granted_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_badges_user_id"); - - b.HasIndex("TenantId", "BadgeId") - .HasDatabaseName("ix_user_badges_tenant_id_badge_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_user_badges_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "BadgeId") - .IsUnique() - .HasDatabaseName("ix_user_badges_tenant_id_user_id_badge_id"); - - b.ToTable("user_badges", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserNotification", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActionLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("action_label"); - - b.Property("ActionPath") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("action_path"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DedupeKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("dedupe_key"); - - b.Property("Message") - .IsRequired() - .HasColumnType("text") - .HasColumnName("message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NotificationType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("notification_type"); - - b.Property("ReadAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("read_at"); - - b.Property("Severity") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("severity"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_notifications"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_notifications_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_user_notifications_created_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_notifications_user_id"); - - b.HasIndex("TenantId", "SourceType", "SourceId") - .HasDatabaseName("ix_user_notifications_tenant_id_source_type_source_id"); - - b.HasIndex("TenantId", "UserId", "NotificationType", "DedupeKey") - .IsUnique() - .HasDatabaseName("ix_user_notifications_tenant_id_user_id_notification_type_dedu~") - .HasFilter("dedupe_key is not null"); - - b.HasIndex("TenantId", "UserId", "Status", "CreatedAt") - .HasDatabaseName("ix_user_notifications_tenant_id_user_id_status_created_at"); - - b.ToTable("user_notifications", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - 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("CurrentVersionId") - .HasColumnType("uuid") - .HasColumnName("current_version_id"); - - b.Property("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExamMarkers") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("exam_markers") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("HasVideoExplanation") - .HasColumnType("boolean") - .HasColumnName("has_video_explanation"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyNodeId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_node_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("MediaUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("media_url"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PrimaryCollectionId") - .HasColumnType("uuid") - .HasColumnName("primary_collection_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Type") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("type"); - - b.Property("TypeLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("type_label"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_questions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_questions_tenant_id_id"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_questions_tenant_id_category_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_questions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_questions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_questions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "NodeId") - .HasDatabaseName("ix_questions_tenant_id_node_id"); - - b.HasIndex("TenantId", "PrimaryCollectionId") - .HasDatabaseName("ix_questions_tenant_id_primary_collection_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_questions_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_questions_tenant_id_subject_id"); - - b.HasIndex("TenantId", "Id", "CurrentVersionId") - .HasDatabaseName("ix_questions_tenant_id_id_current_version_id"); - - b.ToTable("questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SourceScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_scope"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_banks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_banks_tenant_id_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_banks_tenant_id_region_id"); - - b.ToTable("question_banks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("CodeLang") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("code_lang"); - - b.Property("CodeTemplate") - .HasColumnType("text") - .HasColumnName("code_template"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CorrectOptionIndex") - .HasColumnType("integer") - .HasColumnName("correct_option_index"); - - b.Property("CorrectOptionIndices") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("correct_option_indices") - .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("Explanation") - .HasColumnType("text") - .HasColumnName("explanation"); - - b.Property("Options") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubQuestions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sub_questions") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("VersionNo") - .HasColumnType("integer") - .HasColumnName("version_no"); - - b.HasKey("Id") - .HasName("pk_question_versions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_versions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "QuestionId", "Id") - .HasName("ak_question_versions_tenant_id_question_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_versions_created_by"); - - b.HasIndex("QuestionId", "VersionNo") - .IsUnique() - .HasDatabaseName("ix_question_versions_question_id_version_no"); - - b.ToTable("question_versions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", 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("FailureCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("failure_code"); - - b.Property("Identifier") - .HasMaxLength(320) - .HasColumnType("character varying(320)") - .HasColumnName("identifier"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Result") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("result"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_login_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_login_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_login_events_user_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_auth_login_events_tenant_id_user_id_created_at"); - - b.ToTable("auth_login_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", 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("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("RevokedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("revoked_at"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TokenHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("token_hash"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_sessions_tenant_id_id"); - - b.HasIndex("TokenHash") - .IsUnique() - .HasDatabaseName("ix_auth_sessions_token_hash"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_sessions_user_id"); - - b.HasIndex("TenantId", "UserId", "ExpiresAt") - .HasDatabaseName("ix_auth_sessions_tenant_id_user_id_expires_at") - .HasFilter("revoked_at is null"); - - b.ToTable("auth_sessions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Dimension") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("dimension"); - - b.Property("ScopeHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("scope_hash"); - - b.Property("BucketStart") - .HasColumnType("timestamp with time zone") - .HasColumnName("bucket_start"); - - b.Property("RequestCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0) - .HasColumnName("request_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId", "Dimension", "ScopeHash", "BucketStart") - .HasName("pk_sms_send_rate_limits"); - - b.HasIndex("UpdatedAt") - .HasDatabaseName("ix_sms_send_rate_limits_updated_at"); - - b.ToTable("sms_send_rate_limits", null, t => - { - t.HasCheckConstraint("ck_sms_send_rate_limits_request_count", "request_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempts") - .HasColumnType("integer") - .HasColumnName("attempts"); - - b.Property("CodeHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("code_hash"); - - b.Property("ConsumedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("consumed_at"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phone") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Purpose") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("purpose"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_sms_verification_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_sms_verification_codes_tenant_id_id"); - - b.HasIndex("TenantId", "Phone", "Purpose") - .IsUnique() - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "CreatedAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_created_at") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "ExpiresAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_expires_at"); - - b.ToTable("sms_verification_codes", null, t => - { - t.HasCheckConstraint("ck_sms_verification_codes_attempts", "attempts >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BillingStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("billing_status"); - - 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("LegalName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("legal_name"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OwnerUserId") - .HasColumnType("uuid") - .HasColumnName("owner_user_id"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("slug"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenants"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenants_legacy_id"); - - b.HasIndex("OwnerUserId") - .HasDatabaseName("ix_tenants_owner_user_id"); - - b.HasIndex("Slug") - .IsUnique() - .HasDatabaseName("ix_tenants_slug"); - - b.ToTable("tenants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ConfigPublic") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("config_public") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_auth_providers"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_auth_providers_tenant_id_id"); - - b.HasIndex("TenantId", "Provider") - .IsUnique() - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider"); - - b.HasIndex("TenantId", "Provider", "Status") - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider_status"); - - b.ToTable("tenant_auth_providers", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("BrandName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("brand_name"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FaviconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("favicon_url"); - - b.Property("LogoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("logo_url"); - - b.Property("OrganizationName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("organization_name"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ServiceAccountName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("service_account_name"); - - b.Property("ServiceWechat") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("service_wechat"); - - b.Property("ShortName") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("short_name"); - - b.Property("Slogan") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("slogan"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_branding"); - - b.ToTable("tenant_branding", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Code") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("code"); - - 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("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_classes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_classes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_classes_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_classes_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_code") - .HasFilter("code is not null and code <> ''"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_tenant_classes_tenant_id_region_id") - .HasFilter("region_id is not null"); - - b.HasIndex("TenantId", "Status", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_tenant_classes_tenant_id_status_sort_order_created_at"); - - b.ToTable("tenant_classes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_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("JoinedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("joined_at") - .HasDefaultValueSql("now()"); - - b.Property("LeftAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("left_at"); - - b.Property("MemberType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("member_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_class_members"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_class_members_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_class_members_user_id"); - - b.HasIndex("TenantId", "ClassId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_status_member_type"); - - b.HasIndex("TenantId", "ClassId", "UserId", "MemberType") - .IsUnique() - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_user_id_member_type"); - - b.HasIndex("TenantId", "UserId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_user_id_status_member_type"); - - b.ToTable("tenant_class_members", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", 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("DomainType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("domain_type"); - - b.Property("Host") - .IsRequired() - .HasMaxLength(253) - .HasColumnType("citext") - .HasColumnName("host"); - - b.Property("IsPrimary") - .HasColumnType("boolean") - .HasColumnName("is_primary"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VerificationToken") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("verification_token"); - - b.Property("VerifiedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("verified_at"); - - b.HasKey("Id") - .HasName("pk_tenant_domains"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_domains_tenant_id_id"); - - b.HasIndex("Host") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_host"); - - b.HasIndex("TenantId", "IsPrimary") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_tenant_id_is_primary") - .HasFilter("is_primary"); - - b.ToTable("tenant_domains", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", 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("LegacyRole") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("legacy_role"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Role") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("role"); - - b.Property("RoleTemplateId") - .HasColumnType("uuid") - .HasColumnName("role_template_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_memberships"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_memberships_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_memberships_user_id"); - - b.HasIndex("TenantId", "RoleTemplateId") - .HasDatabaseName("ix_tenant_memberships_tenant_id_role_template_id"); - - b.HasIndex("TenantId", "UserId", "Role") - .IsUnique() - .HasDatabaseName("ix_tenant_memberships_tenant_id_user_id_role"); - - b.ToTable("tenant_memberships", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BaseRole") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("base_role"); - - 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("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DataScope") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("data_scope") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("FieldPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("field_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("IsSystem") - .HasColumnType("boolean") - .HasColumnName("is_system"); - - b.Property("MenuPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("menu_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ModulePermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_role_templates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_role_templates_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_role_templates_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_role_templates_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_role_templates_tenant_id_code"); - - b.HasIndex("TenantId", "Status", "SortOrder") - .HasDatabaseName("ix_tenant_role_templates_tenant_id_status_sort_order"); - - b.ToTable("tenant_role_templates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("AdminFeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("admin_feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PublicConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_settings"); - - b.ToTable("tenant_settings", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignedToUserId") - .HasColumnType("uuid") - .HasColumnName("assigned_to_user_id"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_id"); - - b.Property("CompletedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("completed_at"); - - b.Property("CompletedBy") - .HasColumnType("uuid") - .HasColumnName("completed_by"); - - 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("DueAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("due_at"); - - b.Property("FollowupType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("followup_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .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.HasKey("Id") - .HasName("pk_tenant_student_followups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_followups_tenant_id_id"); - - b.HasIndex("AssignedToUserId") - .HasDatabaseName("ix_tenant_student_followups_assigned_to_user_id"); - - b.HasIndex("CompletedBy") - .HasDatabaseName("ix_tenant_student_followups_completed_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_followups_student_user_id"); - - b.HasIndex("TenantId", "AssignedToUserId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_assigned_to_user_id_stat~") - .HasFilter("assigned_to_user_id is not null"); - - b.HasIndex("TenantId", "ClassId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_class_id_status_due_at") - .HasFilter("class_id is not null"); - - b.HasIndex("TenantId", "StudentUserId", "Status", "DueAt", "CreatedAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_student_user_id_status_d~"); - - b.ToTable("tenant_student_followups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Content") - .IsRequired() - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("IsPinned") - .HasColumnType("boolean") - .HasColumnName("is_pinned"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NoteType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("note_type"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - 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_tenant_student_notes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_notes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_student_notes_created_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_notes_student_user_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_student_notes_updated_by"); - - b.HasIndex("TenantId", "CreatedBy", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_created_by_created_at") - .HasFilter("created_by is not null"); - - b.HasIndex("TenantId", "StudentUserId", "IsPinned", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_student_user_id_is_pinned_cr~"); - - b.ToTable("tenant_student_notes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Category", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_categories_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Major", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_majors_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.ModuleNode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_module_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_module_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Region", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_regions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.RegionModule", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_region_modules_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_region_modules_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.School", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_schools_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Subject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.ActivationCode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AgentUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_users_agent_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_activation_codes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UsedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_users_used_by"); - - b.HasOne("Tiku.Domain.Commerce.CodeBatch", null) - .WithMany() - .HasForeignKey("TenantId", "BatchId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_code_batches_tenant_id_batch_id"); - - b.HasOne("Tiku.Domain.Commerce.CouponRedemption", null) - .WithMany() - .HasForeignKey("TenantId", "CouponRedemptionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_coupon_redemptions_tenant_id_coupon_redemp~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "UsedRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_regions_tenant_id_used_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CodeBatch", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_code_batches_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Coupon", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_coupons_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_coupons_svip_plans_tenant_id_plan_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CouponRedemption", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_coupon_redemptions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_users_user_id"); - - b.HasOne("Tiku.Domain.Commerce.Coupon", null) - .WithMany() - .HasForeignKey("TenantId", "CouponId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_coupons_tenant_id_coupon_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_svip_plans_tenant_id_plan_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Entitlement", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_entitlements_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_entitlements_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Order", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_orders_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_orders_users_user_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_orders_svip_plans_tenant_id_plan_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_orders_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.OrderItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_order_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_order_items_orders_tenant_id_order_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Payment", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payments_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payments_orders_tenant_id_order_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.PaymentEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payment_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_payment_events_payments_tenant_id_payment_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Product", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_products_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_products_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.SvipPlan", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_svip_plans_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_svip_plans_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantPaymentAccount", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_payment_accounts_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantSubscription", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_subscriptions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantUsageRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_usage_records_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.AppAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_app_assets_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAsset", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_assets_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_updated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("VerifiedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_verified_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentEntry", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_entries_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportIssue", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportItem", null) - .WithMany() - .HasForeignKey("TenantId", "ItemId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_import_issues_content_import_items_tenant_id_item_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportJob", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_import_jobs_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_jobs_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "TargetCategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_categories_tenant_id_target_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "TargetContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_content_nodes_tenant_id_target_content_~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "TargetQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_question_banks_tenant_id_target_questio~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "TargetRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_regions_tenant_id_target_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentNode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_nodes_content_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookChapter", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_chapters_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.HandbookSubject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_chapters_handbook_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.HandbookChapter", null) - .WithMany() - .HasForeignKey("TenantId", "ChapterId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_entries_handbook_chapters_tenant_id_chapter_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_images_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_blueprints_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_question_collections_tenant_id_collecti~"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_question_banks_tenant_id_question_bank~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_question_collections_tenant_id_co~"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_type_groups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_type_groups_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_videos_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.Content.VideoExplanation", null) - .WithMany() - .HasForeignKey("TenantId", "VideoId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_video_explanations_tenant_id_video_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SourceSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_source_subject_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_video_explanations_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_video_explanations_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_units_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_words_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyUnit", null) - .WithMany() - .HasForeignKey("TenantId", "UnitId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_vocabulary_units_tenant_id_unit_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlement", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("GeneratedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_generated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("PaidBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_paid_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlements_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReviewedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_reviewed_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlements_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlementItem", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlement_items_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlement_items_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlement_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.CommissionSettlement", null) - .WithMany() - .HasForeignKey("TenantId", "SettlementId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlement_items_commission_settlements_tenant_i~"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmConfig", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_config_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookLog", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_webhook_log_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookQueueItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_webhook_queue_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralCode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_codes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_codes_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralLead", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_assigned_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedToUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_assigned_to_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_leads_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_leads_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.ReferralTrack", null) - .WithMany() - .HasForeignKey("TenantId", "FirstTrackId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_referral_tracks_tenant_id_first_track_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralQrcode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_qrcodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_qrcodes_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTeamEdge", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("LeaderUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_team_edges_users_leader_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("MemberUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_team_edges_users_member_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_team_edges_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTrack", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("TargetUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_users_target_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_tracks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.ReferralLead", null) - .WithMany() - .HasForeignKey("TenantId", "LeadId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_referral_leads_tenant_id_lead_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.TenantCommissionSetting", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_commission_settings_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_commission_settings_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedMajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_majors_tenant_id_selected_major_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedSchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_schools_tenant_id_selected_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_identities_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId", "QuestionVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_question_versions_tenant_id_question_id_ques~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "UserId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "UserId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_practice_sessions_tenant_id_user_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_dashboard_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_dashboard_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_exam_dates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_access_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_users_user_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_practice_sessions_tenant_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_question_collections_tenant_id_collection~"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_practice_blueprints_tenant_id_blue~"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_question_collections_tenant_id_col~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_practice_sessions_tenant_id_practi~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_sessions_tenant_i~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSessionReport", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_session_reports_t~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_recent_practices_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_recent_practices_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("HandledBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_handled_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_reports_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_report_status_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.Report", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_reports_tenant_id_report_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_revenue_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_revenue_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Announcement", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_announcements_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.AuditLog", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_audit_logs_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_audit_logs_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Badge", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_badges_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Banner", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_banners_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_banners_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Faq", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_faqs_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_faqs_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantContentNotification", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_content_notifications_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReadBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_content_notifications_users_read_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_content_notifications_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "SourceQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_tenant_content_notifications_question_banks_tenant_id_sourc~"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantThemeConfig", b => - { - b.HasOne("Tiku.Domain.Operations.TenantThemeTemplate", null) - .WithMany() - .HasForeignKey("ActiveTemplateCode") - .HasPrincipalKey("Code") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_tenant_theme_templates_active_template~"); - - b.HasOne("Tiku.Domain.Operations.TenantThemeTemplate", null) - .WithMany() - .HasForeignKey("DraftTemplateCode") - .HasPrincipalKey("Code") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_tenant_theme_templates_draft_template_~"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("DraftUpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_users_draft_updated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("PublishedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_users_published_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_theme_configs_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserBadge", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("GrantedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_user_badges_users_granted_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_badges_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_user_badges_users_user_id"); - - b.HasOne("Tiku.Domain.Operations.Badge", null) - .WithMany() - .HasForeignKey("TenantId", "BadgeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_user_badges_badges_tenant_id_badge_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserNotification", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_user_notifications_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_notifications_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_notifications_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "PrimaryCollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_collections_tenant_id_primary_collection~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_banks_tenant_id_question_bank_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_subjects_tenant_id_subject_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "Id", "CurrentVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_versions_tenant_id_id_current_version_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_banks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_banks_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_versions_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_versions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_login_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_auth_login_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_send_rate_limits_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_verification_codes_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("OwnerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenants_users_owner_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_auth_providers_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantBranding", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_branding_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_classes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_classes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_domains_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantRoleTemplate", null) - .WithMany() - .HasForeignKey("TenantId", "RoleTemplateId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_memberships_tenant_role_templates_tenant_id_role_tem~"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_role_templates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantSettings", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_settings_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedToUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_assigned_to_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CompletedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_completed_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_updated_by"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725214512_AddOperationsContentAndAuditPersistence.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725214512_AddOperationsContentAndAuditPersistence.cs deleted file mode 100644 index 1b3ac3b..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725214512_AddOperationsContentAndAuditPersistence.cs +++ /dev/null @@ -1,619 +0,0 @@ -using System; -using System.Text.Json; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Tiku.Infrastructure.Persistence.Migrations -{ - /// - public partial class AddOperationsContentAndAuditPersistence : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "announcements", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - content = table.Column(type: "text", nullable: true), - link = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - background_color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_announcements", x => x.id); - table.UniqueConstraint("ak_announcements_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_announcements_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "audit_logs", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: true), - actor_user_id = table.Column(type: "uuid", nullable: true), - action = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - target_type = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - target_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - ip_address = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - user_agent = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: true), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_audit_logs", x => x.id); - table.ForeignKey( - name: "fk_audit_logs_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_audit_logs_users_actor_user_id", - column: x => x.actor_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "badges", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - description = table.Column(type: "text", nullable: true), - category = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - icon_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - level = table.Column(type: "integer", nullable: true), - unlock_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - condition_field = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - condition_operator = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - condition_value = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: true), - condition_extra = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_badges", x => x.id); - table.UniqueConstraint("ak_badges_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_badges_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "banners", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - title = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - subtitle = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - content = table.Column(type: "text", nullable: true), - button_text = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - button_link = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - background_color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - border_color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_banners", x => x.id); - table.UniqueConstraint("ak_banners_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_banners_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_banners_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "faqs", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - region_id = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - question = table.Column(type: "text", nullable: true), - answer = table.Column(type: "text", nullable: true), - sort_order = table.Column(type: "integer", nullable: false), - is_active = table.Column(type: "boolean", nullable: false), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_faqs", x => x.id); - table.UniqueConstraint("ak_faqs_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_faqs_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_faqs_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_content_notifications", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - adoption_id = table.Column(type: "uuid", nullable: true), - source_question_bank_id = table.Column(type: "uuid", nullable: true), - created_by = table.Column(type: "uuid", nullable: true), - read_by = table.Column(type: "uuid", nullable: true), - notification_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - title = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - message = table.Column(type: "text", nullable: false), - action_label = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - action_path = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - dedupe_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - read_at = table.Column(type: "timestamp with time zone", nullable: true), - resolved_at = table.Column(type: "timestamp with time zone", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_content_notifications", x => x.id); - table.UniqueConstraint("ak_tenant_content_notifications_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_tenant_content_notifications_question_banks_tenant_id_sourc~", - columns: x => new { x.tenant_id, x.source_question_bank_id }, - principalTable: "question_banks", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_content_notifications_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_content_notifications_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_tenant_content_notifications_users_read_by", - column: x => x.read_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "tenant_theme_templates", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - description = table.Column(type: "text", nullable: true), - preview_image_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - theme = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - public_assets = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - sort_order = table.Column(type: "integer", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_theme_templates", x => x.id); - table.UniqueConstraint("ak_tenant_theme_templates_code", x => x.code); - }); - - migrationBuilder.CreateTable( - name: "user_notifications", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: false), - source_id = table.Column(type: "uuid", nullable: true), - created_by = table.Column(type: "uuid", nullable: true), - notification_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - title = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - message = table.Column(type: "text", nullable: false), - action_label = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - action_path = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), - source_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - dedupe_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - read_at = table.Column(type: "timestamp with time zone", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_user_notifications", x => x.id); - table.UniqueConstraint("ak_user_notifications_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_user_notifications_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_user_notifications_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_user_notifications_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "user_badges", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: true), - badge_id = table.Column(type: "uuid", nullable: true), - granted_by = table.Column(type: "uuid", nullable: true), - legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), - note = table.Column(type: "text", nullable: true), - granted_at = table.Column(type: "timestamp with time zone", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_user_badges", x => x.id); - table.UniqueConstraint("ak_user_badges_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_user_badges_badges_tenant_id_badge_id", - columns: x => new { x.tenant_id, x.badge_id }, - principalTable: "badges", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_user_badges_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_user_badges_users_granted_by", - column: x => x.granted_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_user_badges_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_theme_configs", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - active_template_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - active_theme = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - active_public_assets = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - draft_template_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - draft_theme = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - draft_public_assets = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - published_at = table.Column(type: "timestamp with time zone", nullable: true), - published_by = table.Column(type: "uuid", nullable: true), - draft_updated_by = table.Column(type: "uuid", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_theme_configs", x => x.id); - table.UniqueConstraint("ak_tenant_theme_configs_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_tenant_theme_configs_tenant_theme_templates_active_template~", - column: x => x.active_template_code, - principalTable: "tenant_theme_templates", - principalColumn: "code", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_tenant_theme_configs_tenant_theme_templates_draft_template_~", - column: x => x.draft_template_code, - principalTable: "tenant_theme_templates", - principalColumn: "code", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_tenant_theme_configs_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_theme_configs_users_draft_updated_by", - column: x => x.draft_updated_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_tenant_theme_configs_users_published_by", - column: x => x.published_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateIndex( - name: "ix_announcements_tenant_id_is_active_sort_order", - table: "announcements", - columns: new[] { "tenant_id", "is_active", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_announcements_tenant_id_legacy_id", - table: "announcements", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_audit_logs_actor_user_id", - table: "audit_logs", - column: "actor_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_audit_logs_tenant_id_created_at", - table: "audit_logs", - columns: new[] { "tenant_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_audit_logs_tenant_id_target_type_target_id_created_at", - table: "audit_logs", - columns: new[] { "tenant_id", "target_type", "target_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_badges_tenant_id_category_is_active_sort_order", - table: "badges", - columns: new[] { "tenant_id", "category", "is_active", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_badges_tenant_id_legacy_id", - table: "badges", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_banners_tenant_id_legacy_id", - table: "banners", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_banners_tenant_id_region_id_is_active_sort_order", - table: "banners", - columns: new[] { "tenant_id", "region_id", "is_active", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_faqs_tenant_id_legacy_id", - table: "faqs", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_faqs_tenant_id_region_id_is_active_sort_order", - table: "faqs", - columns: new[] { "tenant_id", "region_id", "is_active", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_content_notifications_created_by", - table: "tenant_content_notifications", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_content_notifications_read_by", - table: "tenant_content_notifications", - column: "read_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_content_notifications_tenant_id_adoption_id_notifica~", - table: "tenant_content_notifications", - columns: new[] { "tenant_id", "adoption_id", "notification_type", "status" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_content_notifications_tenant_id_notification_type_de~", - table: "tenant_content_notifications", - columns: new[] { "tenant_id", "notification_type", "dedupe_key" }, - unique: true, - filter: "dedupe_key is not null"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_content_notifications_tenant_id_source_question_bank~", - table: "tenant_content_notifications", - columns: new[] { "tenant_id", "source_question_bank_id" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_content_notifications_tenant_id_status_created_at", - table: "tenant_content_notifications", - columns: new[] { "tenant_id", "status", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_theme_configs_active_template_code", - table: "tenant_theme_configs", - column: "active_template_code"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_theme_configs_draft_template_code", - table: "tenant_theme_configs", - column: "draft_template_code"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_theme_configs_draft_updated_by", - table: "tenant_theme_configs", - column: "draft_updated_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_theme_configs_published_by", - table: "tenant_theme_configs", - column: "published_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_theme_configs_tenant_id", - table: "tenant_theme_configs", - column: "tenant_id", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_theme_templates_code", - table: "tenant_theme_templates", - column: "code", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_theme_templates_status_sort_order_code", - table: "tenant_theme_templates", - columns: new[] { "status", "sort_order", "code" }); - - migrationBuilder.CreateIndex( - name: "ix_user_badges_granted_by", - table: "user_badges", - column: "granted_by"); - - migrationBuilder.CreateIndex( - name: "ix_user_badges_tenant_id_badge_id", - table: "user_badges", - columns: new[] { "tenant_id", "badge_id" }); - - migrationBuilder.CreateIndex( - name: "ix_user_badges_tenant_id_legacy_id", - table: "user_badges", - columns: new[] { "tenant_id", "legacy_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_user_badges_tenant_id_user_id_badge_id", - table: "user_badges", - columns: new[] { "tenant_id", "user_id", "badge_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_user_badges_user_id", - table: "user_badges", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_user_notifications_created_by", - table: "user_notifications", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_user_notifications_tenant_id_source_type_source_id", - table: "user_notifications", - columns: new[] { "tenant_id", "source_type", "source_id" }); - - migrationBuilder.CreateIndex( - name: "ix_user_notifications_tenant_id_user_id_notification_type_dedu~", - table: "user_notifications", - columns: new[] { "tenant_id", "user_id", "notification_type", "dedupe_key" }, - unique: true, - filter: "dedupe_key is not null"); - - migrationBuilder.CreateIndex( - name: "ix_user_notifications_tenant_id_user_id_status_created_at", - table: "user_notifications", - columns: new[] { "tenant_id", "user_id", "status", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_user_notifications_user_id", - table: "user_notifications", - column: "user_id"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "announcements"); - - migrationBuilder.DropTable( - name: "audit_logs"); - - migrationBuilder.DropTable( - name: "banners"); - - migrationBuilder.DropTable( - name: "faqs"); - - migrationBuilder.DropTable( - name: "tenant_content_notifications"); - - migrationBuilder.DropTable( - name: "tenant_theme_configs"); - - migrationBuilder.DropTable( - name: "user_badges"); - - migrationBuilder.DropTable( - name: "user_notifications"); - - migrationBuilder.DropTable( - name: "tenant_theme_templates"); - - migrationBuilder.DropTable( - name: "badges"); - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725215222_AddCommerceRefundAndReconciliationPersistence.Designer.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725215222_AddCommerceRefundAndReconciliationPersistence.Designer.cs deleted file mode 100644 index 690dc3d..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725215222_AddCommerceRefundAndReconciliationPersistence.Designer.cs +++ /dev/null @@ -1,13143 +0,0 @@ -// -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("20260725215222_AddCommerceRefundAndReconciliationPersistence")] - partial class AddCommerceRefundAndReconciliationPersistence - { - /// - 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.Commerce.ActivationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AgentUserId") - .HasColumnType("uuid") - .HasColumnName("agent_user_id"); - - b.Property("BatchId") - .HasColumnType("uuid") - .HasColumnName("batch_id"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CouponCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("coupon_code"); - - b.Property("CouponRedemptionId") - .HasColumnType("uuid") - .HasColumnName("coupon_redemption_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("IsUsed") - .HasColumnType("boolean") - .HasColumnName("is_used"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("SoldTo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("sold_to"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitPriceCents") - .HasColumnType("integer") - .HasColumnName("unit_price_cents"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("used_at"); - - b.Property("UsedBy") - .HasColumnType("uuid") - .HasColumnName("used_by"); - - b.Property("UsedRegionId") - .HasColumnType("uuid") - .HasColumnName("used_region_id"); - - b.HasKey("Id") - .HasName("pk_activation_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_activation_codes_tenant_id_id"); - - b.HasIndex("AgentUserId") - .HasDatabaseName("ix_activation_codes_agent_user_id"); - - b.HasIndex("UsedBy") - .HasDatabaseName("ix_activation_codes_used_by"); - - b.HasIndex("TenantId", "BatchId") - .HasDatabaseName("ix_activation_codes_tenant_id_batch_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_activation_codes_tenant_id_code"); - - b.HasIndex("TenantId", "CouponRedemptionId") - .HasDatabaseName("ix_activation_codes_tenant_id_coupon_redemption_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_activation_codes_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UsedRegionId") - .HasDatabaseName("ix_activation_codes_tenant_id_used_region_id"); - - b.ToTable("activation_codes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CodeBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CampaignName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("campaign_name"); - - b.Property("Channel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("channel"); - - b.Property("CommissionRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("commission_rate"); - - b.Property("CostPriceCents") - .HasColumnType("integer") - .HasColumnName("cost_price_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("DefaultUnitPriceCents") - .HasColumnType("integer") - .HasColumnName("default_unit_price_cents"); - - b.Property("IssuedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("issued_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - 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.HasKey("Id") - .HasName("pk_code_batches"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_code_batches_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_code_batches_tenant_id_legacy_id"); - - b.ToTable("code_batches", null, t => - { - t.HasCheckConstraint("ck_code_batches_amounts", "default_unit_price_cents >= 0 and cost_price_cents >= 0"); - - t.HasCheckConstraint("ck_code_batches_counts", "total_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("BillDate") - .HasColumnType("date") - .HasColumnName("bill_date"); - - b.Property("BillType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("bill_type"); - - b.Property("CompletedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("completed_at"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DuplicateCount") - .HasColumnType("integer") - .HasColumnName("duplicate_count"); - - b.Property("Error") - .HasColumnType("text") - .HasColumnName("error"); - - b.Property("FeeCents") - .HasColumnType("integer") - .HasColumnName("fee_cents"); - - b.Property("IgnoredCount") - .HasColumnType("integer") - .HasColumnName("ignored_count"); - - b.Property("MatchedCount") - .HasColumnType("integer") - .HasColumnName("matched_count"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("MismatchCount") - .HasColumnType("integer") - .HasColumnName("mismatch_count"); - - b.Property("MissingLocalCount") - .HasColumnType("integer") - .HasColumnName("missing_local_count"); - - b.Property("MissingProviderCount") - .HasColumnType("integer") - .HasColumnName("missing_provider_count"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("RefundAmountCents") - .HasColumnType("integer") - .HasColumnName("refund_amount_cents"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source"); - - b.Property("SourceHash") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("source_hash"); - - b.Property("SourceName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("source_name"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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.HasKey("Id") - .HasName("pk_commerce_reconciliation_batches"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_reconciliation_batches_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_commerce_reconciliation_batches_created_by"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_batches_tenant_id_status_created_at"); - - b.HasIndex("TenantId", "Provider", "BillDate", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_batches_tenant_id_provider_bill_dat~"); - - b.ToTable("commerce_reconciliation_batches", null, t => - { - t.HasCheckConstraint("ck_commerce_reconciliation_batches_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commerce_reconciliation_batches_counts", "total_count >= 0 and matched_count >= 0 and mismatch_count >= 0 and missing_local_count >= 0 and missing_provider_count >= 0 and duplicate_count >= 0 and ignored_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationIssue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("AssignedTo") - .HasColumnType("uuid") - .HasColumnName("assigned_to"); - - b.Property("BatchId") - .HasColumnType("uuid") - .HasColumnName("batch_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("DueAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("due_at"); - - b.Property("IssueCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("issue_code"); - - b.Property("IssueNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("issue_no"); - - b.Property("ItemId") - .HasColumnType("uuid") - .HasColumnName("item_id"); - - b.Property("MatchStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("match_status"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("OrderNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("order_no"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderRefundNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_refund_no"); - - b.Property("ProviderTradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_trade_no"); - - b.Property("RefundAmountCents") - .HasColumnType("integer") - .HasColumnName("refund_amount_cents"); - - b.Property("RefundNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("refund_no"); - - b.Property("RefundRequestId") - .HasColumnType("uuid") - .HasColumnName("refund_request_id"); - - b.Property("ResolutionNote") - .HasColumnType("text") - .HasColumnName("resolution_note"); - - b.Property("ResolutionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("resolution_type"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("ResolvedBy") - .HasColumnType("uuid") - .HasColumnName("resolved_by"); - - b.Property("Severity") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("severity"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("Summary") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("summary"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TransactionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("transaction_type"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_commerce_reconciliation_issues"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_reconciliation_issues_tenant_id_id"); - - b.HasIndex("AssignedTo") - .HasDatabaseName("ix_commerce_reconciliation_issues_assigned_to"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_commerce_reconciliation_issues_created_by"); - - b.HasIndex("ResolvedBy") - .HasDatabaseName("ix_commerce_reconciliation_issues_resolved_by"); - - b.HasIndex("TenantId", "IssueNo") - .IsUnique() - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_issue_no"); - - b.HasIndex("TenantId", "ItemId") - .IsUnique() - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_item_id") - .HasFilter("item_id is not null and status in ('open', 'investigating', 'escalated')"); - - b.HasIndex("TenantId", "OrderId") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_order_id"); - - b.HasIndex("TenantId", "RefundRequestId") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_refund_request_id"); - - b.HasIndex("TenantId", "OrderNo", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_order_no_created_at"); - - b.HasIndex("TenantId", "PaymentId", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_payment_id_created~"); - - b.HasIndex("TenantId", "AssignedTo", "Status", "DueAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_assigned_to_status~"); - - b.HasIndex("TenantId", "BatchId", "Status", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_batch_id_status_cr~"); - - b.HasIndex("TenantId", "Status", "Severity", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_status_severity_cr~"); - - b.ToTable("commerce_reconciliation_issues", null, t => - { - t.HasCheckConstraint("ck_commerce_reconciliation_issues_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationIssueEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - 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("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("IssueId") - .HasColumnType("uuid") - .HasColumnName("issue_id"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_commerce_reconciliation_issue_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_reconciliation_issue_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_commerce_reconciliation_issue_events_actor_user_id"); - - b.HasIndex("TenantId", "IssueId", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issue_events_tenant_id_issue_id_cre~"); - - b.ToTable("commerce_reconciliation_issue_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("BatchId") - .HasColumnType("uuid") - .HasColumnName("batch_id"); - - 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("FeeCents") - .HasColumnType("integer") - .HasColumnName("fee_cents"); - - b.Property("IssueCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("issue_code"); - - b.Property("LocalStatus") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("local_status"); - - b.Property("MatchStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("match_status"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("OrderNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("order_no"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderRefundNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_refund_no"); - - b.Property("ProviderStatus") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider_status"); - - b.Property("ProviderTradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_trade_no"); - - b.Property("RefundAmountCents") - .HasColumnType("integer") - .HasColumnName("refund_amount_cents"); - - b.Property("RefundNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("refund_no"); - - b.Property("RefundRequestId") - .HasColumnType("uuid") - .HasColumnName("refund_request_id"); - - b.Property("RefundedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("refunded_at"); - - 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("TransactionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("transaction_type"); - - b.HasKey("Id") - .HasName("pk_commerce_reconciliation_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_reconciliation_items_tenant_id_id"); - - b.HasIndex("BatchId", "RowNo") - .IsUnique() - .HasDatabaseName("ix_commerce_reconciliation_items_batch_id_row_no"); - - b.HasIndex("TenantId", "OrderId") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_order_id"); - - b.HasIndex("TenantId", "PaymentId") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_payment_id"); - - b.HasIndex("TenantId", "RefundRequestId") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_refund_request_id"); - - b.HasIndex("TenantId", "OrderNo", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_order_no_created_at"); - - b.HasIndex("TenantId", "BatchId", "MatchStatus", "RowNo") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_batch_id_match_stat~"); - - b.HasIndex("TenantId", "Provider", "ProviderTradeNo", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_provider_provider_t~"); - - b.HasIndex("TenantId", "RefundNo", "ProviderRefundNo", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_refund_no_provider_~"); - - b.ToTable("commerce_reconciliation_items", null, t => - { - t.HasCheckConstraint("ck_commerce_reconciliation_items_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commerce_reconciliation_items_row", "row_no > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceRefundEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - 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("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("RefundRequestId") - .HasColumnType("uuid") - .HasColumnName("refund_request_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_commerce_refund_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_refund_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_commerce_refund_events_actor_user_id"); - - b.HasIndex("TenantId", "RefundRequestId", "CreatedAt") - .HasDatabaseName("ix_commerce_refund_events_tenant_id_refund_request_id_created_~"); - - b.ToTable("commerce_refund_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceRefundRequest", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("CancelledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("cancelled_at"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EntitlementAction") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("entitlement_action"); - - b.Property("FailedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("failed_at"); - - b.Property("FailureReason") - .HasColumnType("text") - .HasColumnName("failure_reason"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("ProcessedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("processed_at"); - - b.Property("ProcessedBy") - .HasColumnType("uuid") - .HasColumnName("processed_by"); - - b.Property("Provider") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderRefundNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_refund_no"); - - b.Property("Reason") - .HasColumnType("text") - .HasColumnName("reason"); - - b.Property("RefundNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("refund_no"); - - b.Property("RequestedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("requested_at") - .HasDefaultValueSql("now()"); - - b.Property("RequestedBy") - .HasColumnType("uuid") - .HasColumnName("requested_by"); - - b.Property("ReviewedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("reviewed_at"); - - b.Property("ReviewedBy") - .HasColumnType("uuid") - .HasColumnName("reviewed_by"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SucceededAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("succeeded_at"); - - 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_commerce_refund_requests"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_refund_requests_tenant_id_id"); - - b.HasIndex("ProcessedBy") - .HasDatabaseName("ix_commerce_refund_requests_processed_by"); - - b.HasIndex("RequestedBy") - .HasDatabaseName("ix_commerce_refund_requests_requested_by"); - - b.HasIndex("ReviewedBy") - .HasDatabaseName("ix_commerce_refund_requests_reviewed_by"); - - b.HasIndex("TenantId", "PaymentId") - .HasDatabaseName("ix_commerce_refund_requests_tenant_id_payment_id"); - - b.HasIndex("TenantId", "RefundNo") - .IsUnique() - .HasDatabaseName("ix_commerce_refund_requests_tenant_id_refund_no"); - - b.HasIndex("TenantId", "OrderId", "CreatedAt") - .HasDatabaseName("ix_commerce_refund_requests_tenant_id_order_id_created_at"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_commerce_refund_requests_tenant_id_status_created_at"); - - b.ToTable("commerce_refund_requests", null, t => - { - t.HasCheckConstraint("ck_commerce_refund_requests_amount", "amount_cents > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Coupon", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DiscountType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("discount_type"); - - b.Property("DiscountValue") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("discount_value"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("MaxUses") - .HasColumnType("integer") - .HasColumnName("max_uses"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("Source") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("ValidFrom") - .HasColumnType("timestamp with time zone") - .HasColumnName("valid_from"); - - b.Property("ValidTo") - .HasColumnType("timestamp with time zone") - .HasColumnName("valid_to"); - - b.HasKey("Id") - .HasName("pk_coupons"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_coupons_tenant_id_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_coupons_tenant_id_code"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_coupons_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_coupons_tenant_id_plan_id"); - - b.ToTable("coupons", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CouponRedemption", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ClaimedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("claimed_at"); - - b.Property("CouponCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("coupon_code"); - - b.Property("CouponId") - .HasColumnType("uuid") - .HasColumnName("coupon_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DiscountAppliedCents") - .HasColumnType("integer") - .HasColumnName("discount_applied_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("Source") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("used_at"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_coupon_redemptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_coupon_redemptions_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_coupon_redemptions_user_id"); - - b.HasIndex("TenantId", "CouponId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_coupon_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_coupon_redemptions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_plan_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_region_id"); - - b.HasIndex("TenantId", "OrderId", "UserId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_order_id_user_id") - .HasFilter("order_id is not null"); - - b.HasIndex("TenantId", "UserId", "CouponId") - .IsUnique() - .HasDatabaseName("ix_coupon_redemptions_tenant_id_user_id_coupon_id") - .HasFilter("coupon_id is not null"); - - b.ToTable("coupon_redemptions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Entitlement", 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("EntitlementType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("entitlement_type"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("LegacySourceId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_source_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RevokedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("revoked_at"); - - b.Property("RevokedBy") - .HasColumnType("uuid") - .HasColumnName("revoked_by"); - - b.Property("RevokedReason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("revoked_reason"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("StartsAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at") - .HasDefaultValueSql("now()"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_entitlements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_entitlements_tenant_id_id"); - - b.HasIndex("RevokedBy") - .HasDatabaseName("ix_entitlements_revoked_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_entitlements_user_id"); - - b.HasIndex("TenantId", "UserId", "Status", "ExpiresAt") - .HasDatabaseName("ix_entitlements_tenant_id_user_id_status_expires_at"); - - b.ToTable("entitlements", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPlanId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_plan_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("OrderNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("order_no"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PayMethod") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("pay_method"); - - b.Property("PayProvider") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("pay_provider"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("ProductName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("product_name"); - - b.Property("ProductType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("product_type"); - - b.Property("RawPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RefundedAmountCents") - .HasColumnType("integer") - .HasColumnName("refunded_amount_cents"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("trade_no"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_orders"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_orders_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_orders_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_orders_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderNo") - .IsUnique() - .HasDatabaseName("ix_orders_tenant_id_order_no"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_orders_tenant_id_plan_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_orders_tenant_id_region_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_orders_tenant_id_user_id_created_at"); - - b.ToTable("orders", null, t => - { - t.HasCheckConstraint("ck_orders_amount", "amount_cents >= 0"); - - t.HasCheckConstraint("ck_orders_refunded_amount", "refunded_amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.OrderItem", 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("ItemId") - .HasColumnType("uuid") - .HasColumnName("item_id"); - - b.Property("ItemType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("item_type"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("Quantity") - .HasColumnType("integer") - .HasColumnName("quantity"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalAmountCents") - .HasColumnType("integer") - .HasColumnName("total_amount_cents"); - - b.Property("UnitAmountCents") - .HasColumnType("integer") - .HasColumnName("unit_amount_cents"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_order_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_order_items_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_order_items_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderId") - .HasDatabaseName("ix_order_items_tenant_id_order_id"); - - b.ToTable("order_items", null, t => - { - t.HasCheckConstraint("ck_order_items_amounts", "unit_amount_cents >= 0 and total_amount_cents >= 0"); - - t.HasCheckConstraint("ck_order_items_quantity", "quantity > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Payment", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - 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("LegacyOrderId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_order_id"); - - b.Property("Method") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("method"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderTradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_trade_no"); - - b.Property("RawPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RefundedAmountCents") - .HasColumnType("integer") - .HasColumnName("refunded_amount_cents"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_payments"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_payments_tenant_id_id"); - - b.HasIndex("Provider", "ProviderTradeNo") - .IsUnique() - .HasDatabaseName("ix_payments_provider_provider_trade_no") - .HasFilter("provider_trade_no is not null"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_payments_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderId", "UpdatedAt") - .HasDatabaseName("ix_payments_tenant_id_order_id_updated_at"); - - b.ToTable("payments", null, t => - { - t.HasCheckConstraint("ck_payments_amount", "amount_cents >= 0"); - - t.HasCheckConstraint("ck_payments_refunded_amount", "refunded_amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.PaymentEvent", 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("Error") - .HasColumnType("text") - .HasColumnName("error"); - - b.Property("EventId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("event_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("Payload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("ProcessedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("processed_at"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("SignatureValid") - .HasColumnType("boolean") - .HasColumnName("signature_valid"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_payment_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_payment_events_tenant_id_id"); - - b.HasIndex("Provider", "EventId") - .IsUnique() - .HasDatabaseName("ix_payment_events_provider_event_id"); - - b.HasIndex("TenantId", "PaymentId") - .HasDatabaseName("ix_payment_events_tenant_id_payment_id"); - - b.ToTable("payment_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Product", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Cover") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cover"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DetailImages") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("detail_images") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPriceText") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("legacy_price_text"); - - b.Property("Link") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("link"); - - b.Property("PreviewIframe") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("preview_iframe"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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_products"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_products_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_products_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "Type", "SortOrder") - .HasDatabaseName("ix_products_tenant_id_region_id_type_sort_order"); - - b.ToTable("products", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.SvipPlan", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Badge") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("badge"); - - b.Property("CouponOnly") - .HasColumnType("boolean") - .HasColumnName("coupon_only"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - 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(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OriginalPriceCents") - .HasColumnType("integer") - .HasColumnName("original_price_cents"); - - b.Property("PerDayLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("per_day_label"); - - b.Property("PriceCents") - .HasColumnType("integer") - .HasColumnName("price_cents"); - - b.Property("Recommended") - .HasColumnType("boolean") - .HasColumnName("recommended"); - - 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("VpEnabled") - .HasColumnType("boolean") - .HasColumnName("vp_enabled"); - - b.Property("VpProductId") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("vp_product_id"); - - b.HasKey("Id") - .HasName("pk_svip_plans"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_svip_plans_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_svip_plans_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_svip_plans_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("svip_plans", null, t => - { - t.HasCheckConstraint("ck_svip_plans_days", "days >= 0"); - - t.HasCheckConstraint("ck_svip_plans_price", "price_cents >= 0 and (original_price_cents is null or original_price_cents >= 0)"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantPaymentAccount", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ConfigPublic") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("config_public") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_payment_accounts"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_payment_accounts_tenant_id_id"); - - b.HasIndex("TenantId", "Provider") - .IsUnique() - .HasDatabaseName("ix_tenant_payment_accounts_tenant_id_provider"); - - b.ToTable("tenant_payment_accounts", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantSubscription", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("BillingCycle") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("billing_cycle"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PlanCode") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("plan_code"); - - b.Property("StartsAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_subscriptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_subscriptions_tenant_id_id"); - - b.HasIndex("TenantId", "Status", "ExpiresAt") - .HasDatabaseName("ix_tenant_subscriptions_tenant_id_status_expires_at"); - - b.ToTable("tenant_subscriptions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantUsageRecord", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("MetricKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("metric_key"); - - b.Property("MetricValue") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)") - .HasColumnName("metric_value"); - - b.Property("PeriodEnd") - .HasColumnType("date") - .HasColumnName("period_end"); - - b.Property("PeriodStart") - .HasColumnType("date") - .HasColumnName("period_start"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_tenant_usage_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_usage_records_tenant_id_id"); - - b.HasIndex("TenantId", "MetricKey", "PeriodStart", "PeriodEnd") - .HasDatabaseName("ix_tenant_usage_records_tenant_id_metric_key_period_start_peri~"); - - b.ToTable("tenant_usage_records", (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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_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_handbook_chapters"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_chapters_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_chapters_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_subject_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_chapters_tenant_id_entry_id_content_node_id_subjec~"); - - b.ToTable("handbook_chapters", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ChapterId") - .HasColumnType("uuid") - .HasColumnName("chapter_id"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Summary") - .HasColumnType("text") - .HasColumnName("summary"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_handbook_entries"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_entries_tenant_id_id"); - - b.HasIndex("TenantId", "ChapterId") - .HasDatabaseName("ix_handbook_entries_tenant_id_chapter_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_entries_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_entries_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "ChapterId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_entries_tenant_id_entry_id_content_node_id_chapter~"); - - b.ToTable("handbook_entries", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", 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("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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - 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_handbook_subjects"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_subjects_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_subjects_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "MajorId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_major_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_school_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_subjects_tenant_id_entry_id_content_node_id_region~"); - - b.ToTable("handbook_subjects", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("CdnUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cdn_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FileName") - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("file_name"); - - 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("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.HasKey("Id") - .HasName("pk_images"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_images_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_images_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "Category", "IsPublic") - .HasDatabaseName("ix_images_tenant_id_category_is_public"); - - b.ToTable("images", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", 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("AssemblyType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assembly_type"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_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("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PassScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("pass_score"); - - b.Property("QuestionLimit") - .HasColumnType("integer") - .HasColumnName("question_limit"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Rules") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("rules") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Sections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sections") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_practice_blueprints"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_blueprints_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_practice_blueprints_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_practice_blueprints_updated_by"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_collection_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_practice_blueprints_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_region_id"); - - b.HasIndex("TenantId", "NodeId", "CollectionId", "Mode", "Status", "SortOrder") - .HasDatabaseName("ix_practice_blueprints_tenant_id_node_id_collection_id_mode_st~"); - - b.ToTable("practice_blueprints", null, t => - { - t.HasCheckConstraint("ck_practice_blueprints_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_practice_blueprints_question_limit", "question_limit is null or question_limit > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", 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("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - b.Property("CollectionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("collection_type"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Filters") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("filters") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_question_collections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collections_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_collections_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_question_collections_updated_by"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_question_collections_tenant_id_category_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_question_collections_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_collections_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_question_collections_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_collections_tenant_id_region_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_question_collections_tenant_id_subject_id"); - - b.HasIndex("TenantId", "NodeId", "Status", "SortOrder") - .HasDatabaseName("ix_question_collections_tenant_id_node_id_status_sort_order"); - - b.ToTable("question_collections", null, t => - { - t.HasCheckConstraint("ck_question_collections_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_question_collections_question_count", "question_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Required") - .HasColumnType("boolean") - .HasColumnName("required"); - - b.Property("Score") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - 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_question_collection_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collection_items_tenant_id_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_question_collection_items_tenant_id_question_id"); - - b.HasIndex("TenantId", "CollectionId", "QuestionId") - .IsUnique() - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_question_~"); - - b.HasIndex("TenantId", "CollectionId", "SectionKey", "SortOrder") - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_section_k~"); - - b.ToTable("question_collection_items", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", 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("DisplayName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Types") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("types") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_question_type_groups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_type_groups_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_type_groups_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_question_type_groups_tenant_id_subject_id_is_active_sort_or~"); - - b.ToTable("question_type_groups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", 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("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("LegacyVideoId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_video_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_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("VideoId") - .HasColumnType("uuid") - .HasColumnName("video_id"); - - b.Property("VideoType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("video_type"); - - b.HasKey("Id") - .HasName("pk_question_videos"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_videos_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "VideoId") - .HasDatabaseName("ix_question_videos_tenant_id_video_id"); - - b.HasIndex("TenantId", "QuestionId", "VideoId", "VideoType") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_question_id_video_id_video_type"); - - b.ToTable("question_videos", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("SourceSubjectId") - .HasColumnType("uuid") - .HasColumnName("source_subject_id"); - - b.Property("TargetSubjectId") - .HasColumnType("uuid") - .HasColumnName("target_subject_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Id") - .HasColumnType("uuid") - .HasColumnName("id"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacySourceSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_source_subject_id"); - - b.Property("LegacyTargetSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_target_subject_id"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at"); - - b.HasKey("TenantId", "SourceSubjectId", "TargetSubjectId") - .HasName("pk_subject_shares"); - - b.HasIndex("TenantId", "TargetSubjectId") - .HasDatabaseName("ix_subject_shares_tenant_id_target_subject_id"); - - b.ToTable("subject_shares", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", 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("FavoritedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("favorited_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Note") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.HasKey("Id") - .HasName("pk_user_word_favorites"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_favorites_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_favorites_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_favorites_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_favorites_tenant_id_user_id_word_id"); - - b.ToTable("user_word_favorites", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CorrectStreak") - .HasColumnType("integer") - .HasColumnName("correct_streak"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DueLevel") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("due_level"); - - b.Property("EaseFactor") - .ValueGeneratedOnAdd() - .HasPrecision(4, 2) - .HasColumnType("numeric(4,2)") - .HasDefaultValue(2.50m) - .HasColumnName("ease_factor"); - - b.Property("LastResult") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("last_result"); - - b.Property("LastReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_review_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NextReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_review_at"); - - b.Property("ReviewCount") - .HasColumnType("integer") - .HasColumnName("review_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_user_word_progress"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_progress_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_progress_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_progress_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_word_id"); - - b.HasIndex("TenantId", "UserId", "NextReviewAt", "Status", "DueLevel") - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_next_review_at_status_~"); - - b.ToTable("user_word_progress", null, t => - { - t.HasCheckConstraint("ck_user_word_progress_correct_streak", "correct_streak >= 0"); - - t.HasCheckConstraint("ck_user_word_progress_ease_factor", "ease_factor >= 1.30 and ease_factor <= 3.00"); - - t.HasCheckConstraint("ck_user_word_progress_review_count", "review_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("IsGeneral") - .HasColumnType("boolean") - .HasColumnName("is_general"); - - b.Property("KnowledgeTags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("knowledge_tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ThumbnailUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("thumbnail_url"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VideoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("video_url"); - - b.HasKey("Id") - .HasName("pk_video_explanations"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_video_explanations_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_video_explanations_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SourceHash") - .HasDatabaseName("ix_video_explanations_tenant_id_source_hash") - .HasFilter("source_hash is not null"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_video_explanations_tenant_id_subject_id_is_active_sort_order"); - - b.ToTable("video_explanations", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WordCount") - .HasColumnType("integer") - .HasColumnName("word_count"); - - b.HasKey("Id") - .HasName("pk_vocabulary_units"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_units_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_units_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_region_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_units_tenant_id_entry_id_content_node_id_region_~"); - - b.ToTable("vocabulary_units", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Example") - .HasColumnType("text") - .HasColumnName("example"); - - b.Property("ExampleTranslation") - .HasColumnType("text") - .HasColumnName("example_translation"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Meaning") - .HasColumnType("text") - .HasColumnName("meaning"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phonetic") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("phonetic"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitId") - .HasColumnType("uuid") - .HasColumnName("unit_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Word") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("word"); - - b.HasKey("Id") - .HasName("pk_vocabulary_words"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_words_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_words_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_words_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UnitId", "IsActive", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_vocabulary_words_tenant_id_unit_id_is_active_sort_order_cre~"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "UnitId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_words_tenant_id_entry_id_content_node_id_unit_id~"); - - b.ToTable("vocabulary_words", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlement", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CommissionAmountCents") - .HasColumnType("integer") - .HasColumnName("commission_amount_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DefaultRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("default_rate"); - - b.Property("EffectiveRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("effective_rate"); - - b.Property("GeneratedBy") - .HasColumnType("uuid") - .HasColumnName("generated_by"); - - b.Property("GrossAmountCents") - .HasColumnType("integer") - .HasColumnName("gross_amount_cents"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PaidBy") - .HasColumnType("uuid") - .HasColumnName("paid_by"); - - b.Property("PaidUserCount") - .HasColumnType("integer") - .HasColumnName("paid_user_count"); - - b.Property("PaymentAccount") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("payment_account"); - - b.Property("PaymentMethod") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("payment_method"); - - b.Property("PeriodEnd") - .HasColumnType("date") - .HasColumnName("period_end"); - - b.Property("PeriodStart") - .HasColumnType("date") - .HasColumnName("period_start"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("ReviewedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("reviewed_at"); - - b.Property("ReviewedBy") - .HasColumnType("uuid") - .HasColumnName("reviewed_by"); - - b.Property("SettlementNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("settlement_no"); - - b.Property("SourceCount") - .HasColumnType("integer") - .HasColumnName("source_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_commission_settlements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commission_settlements_tenant_id_id"); - - b.HasIndex("GeneratedBy") - .HasDatabaseName("ix_commission_settlements_generated_by"); - - b.HasIndex("PaidBy") - .HasDatabaseName("ix_commission_settlements_paid_by"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_commission_settlements_referrer_user_id"); - - b.HasIndex("ReviewedBy") - .HasDatabaseName("ix_commission_settlements_reviewed_by"); - - b.HasIndex("TenantId", "SettlementNo") - .IsUnique() - .HasDatabaseName("ix_commission_settlements_tenant_id_settlement_no"); - - b.HasIndex("TenantId", "ReferrerUserId", "PeriodStart") - .HasDatabaseName("ix_commission_settlements_referrer_start"); - - b.HasIndex("TenantId", "ReferrerUserId", "PeriodStart", "PeriodEnd") - .IsUnique() - .HasDatabaseName("ux_commission_settlements_referrer_period"); - - b.ToTable("commission_settlements", null, t => - { - t.HasCheckConstraint("ck_commission_settlements_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commission_settlements_counts", "source_count >= 0 and paid_user_count >= 0"); - - t.HasCheckConstraint("ck_commission_settlements_period", "period_end >= period_start"); - - t.HasCheckConstraint("ck_commission_settlements_rates", "default_rate >= 0 and default_rate <= 1 and (effective_rate is null or (effective_rate >= 0 and effective_rate <= 1))"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlementItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AttributionType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("attribution_type"); - - b.Property("CommissionAmountCents") - .HasColumnType("integer") - .HasColumnName("commission_amount_cents"); - - b.Property("CommissionRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("commission_rate"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("GrossAmountCents") - .HasColumnType("integer") - .HasColumnName("gross_amount_cents"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RateSource") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("rate_source"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("SettlementId") - .HasColumnType("uuid") - .HasColumnName("settlement_id"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_no"); - - b.Property("SourcePaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("source_paid_at"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_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_commission_settlement_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commission_settlement_items_tenant_id_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_commission_settlement_items_referrer_user_id"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_commission_settlement_items_student_user_id"); - - b.HasIndex("TenantId", "SettlementId") - .HasDatabaseName("ix_commission_settlement_items_tenant_id_settlement_id"); - - b.HasIndex("TenantId", "ReferrerUserId", "SourcePaidAt") - .HasDatabaseName("ix_commission_settlement_items_tenant_id_referrer_user_id_sour~"); - - b.HasIndex("TenantId", "SourceType", "SourceId") - .IsUnique() - .HasDatabaseName("ix_commission_settlement_items_tenant_id_source_type_source_id"); - - b.ToTable("commission_settlement_items", null, t => - { - t.HasCheckConstraint("ck_commission_settlement_items_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commission_settlement_items_rate", "commission_rate >= 0 and commission_rate <= 1"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignmentConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("assignment_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("AssignmentCursor") - .HasColumnType("integer") - .HasColumnName("assignment_cursor"); - - b.Property("AssignmentMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assignment_mode"); - - b.Property("AssignmentPool") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("assignment_pool") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DelaySeconds") - .HasColumnType("integer") - .HasColumnName("delay_seconds"); - - b.Property("Enabled") - .HasColumnType("boolean") - .HasColumnName("enabled"); - - b.Property("ExamType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("exam_type"); - - b.Property("FormName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("form_name"); - - b.Property("SecretRef") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("secret_ref"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TimeoutSeconds") - .HasColumnType("integer") - .HasColumnName("timeout_seconds"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Url") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("url"); - - b.HasKey("Id") - .HasName("pk_crm_config"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_config_tenant_id_id"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_crm_config_tenant_id"); - - b.HasIndex("TenantId", "AssignmentMode") - .HasDatabaseName("ix_crm_config_tenant_id_assignment_mode"); - - b.ToTable("crm_config", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempt") - .HasColumnType("integer") - .HasColumnName("attempt"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ErrorMessage") - .HasColumnType("text") - .HasColumnName("error_message"); - - b.Property("HttpCode") - .HasColumnType("integer") - .HasColumnName("http_code"); - - b.Property("LeadId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Outcome") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("outcome"); - - b.Property("RecordId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("record_id"); - - b.Property("RequestBody") - .HasColumnType("text") - .HasColumnName("request_body"); - - b.Property("RequestPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("request_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ResponseSummary") - .HasMaxLength(2000) - .HasColumnType("character varying(2000)") - .HasColumnName("response_summary"); - - b.Property("SignedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("signed_at"); - - 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_crm_webhook_log"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_webhook_log_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_log_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RecordId", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_log_tenant_id_record_id_created_at"); - - b.ToTable("crm_webhook_log", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookQueueItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempts") - .HasColumnType("integer") - .HasColumnName("attempts"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IdempotencyKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("idempotency_key"); - - b.Property("LastAttemptAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_attempt_at"); - - b.Property("LastError") - .HasColumnType("text") - .HasColumnName("last_error"); - - b.Property("LastHttpCode") - .HasColumnType("integer") - .HasColumnName("last_http_code"); - - b.Property("LastResponseSummary") - .HasColumnType("text") - .HasColumnName("last_response_summary"); - - b.Property("LeadId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("NextAttemptAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_attempt_at"); - - b.Property("Payload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("RecordId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("record_id"); - - b.Property("ScheduledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("scheduled_at"); - - b.Property("SentAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("sent_at"); - - b.Property("Source") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TargetUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("target_url"); - - 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_crm_webhook_queue"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_webhook_queue_tenant_id_id"); - - b.HasIndex("TenantId", "IdempotencyKey") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_idempotency_key") - .HasFilter("idempotency_key is not null"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RecordId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_record_id") - .HasFilter("record_id is not null"); - - b.HasIndex("TenantId", "RecordId", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_record_id_created_at") - .HasFilter("record_id is not null"); - - b.HasIndex("TenantId", "Source", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_source_created_at") - .HasFilter("source = 'tenant.student.crm_push'"); - - b.HasIndex("TenantId", "Status", "ScheduledAt", "NextAttemptAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_status_scheduled_at_next_attemp~"); - - b.ToTable("crm_webhook_queue", null, t => - { - t.HasCheckConstraint("ck_crm_webhook_queue_attempts", "attempts >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Channel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("channel"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("LandingPath") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("landing_path"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_referral_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_codes_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_referral_codes_user_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_referral_codes_tenant_id_code"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_referral_codes_tenant_id_user_id"); - - b.HasIndex("TenantId", "Code", "Status") - .HasDatabaseName("ix_referral_codes_tenant_id_code_status"); - - b.ToTable("referral_codes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralLead", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("assigned_at"); - - b.Property("AssignedBy") - .HasColumnType("uuid") - .HasColumnName("assigned_by"); - - b.Property("AssignedToUserId") - .HasColumnType("uuid") - .HasColumnName("assigned_to_user_id"); - - b.Property("AssignmentMode") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assignment_mode"); - - b.Property("BindType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("bind_type"); - - b.Property("BoundAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("bound_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FirstTrackId") - .HasColumnType("uuid") - .HasColumnName("first_track_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ProtectedUntil") - .HasColumnType("timestamp with time zone") - .HasColumnName("protected_until"); - - b.Property("RefCode") - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Source") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_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_referral_leads"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_leads_tenant_id_id"); - - b.HasIndex("AssignedBy") - .HasDatabaseName("ix_referral_leads_assigned_by"); - - b.HasIndex("AssignedToUserId") - .HasDatabaseName("ix_referral_leads_assigned_to_user_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_referral_leads_referrer_user_id"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_referral_leads_student_user_id"); - - b.HasIndex("TenantId", "FirstTrackId") - .HasDatabaseName("ix_referral_leads_tenant_id_first_track_id"); - - b.HasIndex("TenantId", "StudentUserId") - .IsUnique() - .HasDatabaseName("ix_referral_leads_tenant_id_student_user_id"); - - b.HasIndex("TenantId", "ReferrerUserId", "BoundAt") - .HasDatabaseName("ix_referral_leads_tenant_id_referrer_user_id_bound_at"); - - b.HasIndex("TenantId", "AssignedToUserId", "Status", "BoundAt") - .HasDatabaseName("ix_referral_leads_tenant_id_assigned_to_user_id_status_bound_at"); - - b.ToTable("referral_leads", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralQrcode", 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("ErrorMessage") - .HasColumnType("text") - .HasColumnName("error_message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Page") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("page"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("QrcodeUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("qrcode_url"); - - b.Property("RefCode") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("Scene") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("scene"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_referral_qrcodes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_qrcodes_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_referral_qrcodes_user_id"); - - b.HasIndex("TenantId", "RefCode", "Status") - .HasDatabaseName("ix_referral_qrcodes_tenant_id_ref_code_status"); - - b.HasIndex("TenantId", "Provider", "Scene", "Page") - .IsUnique() - .HasDatabaseName("ix_referral_qrcodes_tenant_id_provider_scene_page"); - - b.ToTable("referral_qrcodes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTeamEdge", 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("LeaderUserId") - .HasColumnType("uuid") - .HasColumnName("leader_user_id"); - - b.Property("MemberUserId") - .HasColumnType("uuid") - .HasColumnName("member_user_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RelationType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("relation_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_referral_team_edges"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_team_edges_tenant_id_id"); - - b.HasIndex("LeaderUserId") - .HasDatabaseName("ix_referral_team_edges_leader_user_id"); - - b.HasIndex("MemberUserId") - .HasDatabaseName("ix_referral_team_edges_member_user_id"); - - b.HasIndex("TenantId", "LeaderUserId", "Status") - .HasDatabaseName("ix_referral_team_edges_tenant_id_leader_user_id_status"); - - b.HasIndex("TenantId", "MemberUserId", "RelationType") - .IsUnique() - .HasDatabaseName("ix_referral_team_edges_tenant_id_member_user_id_relation_type"); - - b.ToTable("referral_team_edges", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTrack", 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("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("IpAddress") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("ip_address"); - - b.Property("LeadId") - .HasColumnType("uuid") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RefCode") - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Source") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source"); - - b.Property("TargetUserId") - .HasColumnType("uuid") - .HasColumnName("target_user_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserAgent") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_referral_tracks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_tracks_tenant_id_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_referral_tracks_referrer_user_id"); - - b.HasIndex("TargetUserId") - .HasDatabaseName("ix_referral_tracks_target_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_referral_tracks_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "LeadId", "CreatedAt") - .HasDatabaseName("ix_referral_tracks_tenant_id_lead_id_created_at"); - - b.HasIndex("TenantId", "RefCode", "EventType", "CreatedAt") - .HasDatabaseName("ix_referral_tracks_tenant_id_ref_code_event_type_created_at"); - - b.ToTable("referral_tracks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.TenantCommissionSetting", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - 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("DefaultRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("default_rate"); - - b.Property("MinSettlementCents") - .HasColumnType("integer") - .HasColumnName("min_settlement_cents"); - - b.Property("SettlementCycle") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("settlement_cycle"); - - 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_tenant_commission_settings"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_commission_settings_tenant_id_id"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_tenant_commission_settings_tenant_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_commission_settings_updated_by"); - - b.ToTable("tenant_commission_settings", null, t => - { - t.HasCheckConstraint("ck_tenant_commission_settings_default_rate", "default_rate >= 0 and default_rate <= 1"); - - t.HasCheckConstraint("ck_tenant_commission_settings_min_settlement", "min_settlement_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", 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("LastCheckInDate") - .HasColumnType("date") - .HasColumnName("last_check_in_date"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("MasteredWordsCount") - .HasColumnType("integer") - .HasColumnName("mastered_words_count"); - - b.Property("ModuleSelections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_selections") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Progress") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("progress") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionsAnsweredToday") - .HasColumnType("integer") - .HasColumnName("questions_answered_today"); - - b.Property("RecentActivities") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("recent_activities") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SelectedMajorId") - .HasColumnType("uuid") - .HasColumnName("selected_major_id"); - - b.Property("SelectedSchoolId") - .HasColumnType("uuid") - .HasColumnName("selected_school_id"); - - b.Property("Stats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("stats") - .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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_student_profiles"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_student_profiles_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_student_profiles_user_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_student_profiles_tenant_id_region_id"); - - b.HasIndex("TenantId", "SelectedMajorId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_major_id"); - - b.HasIndex("TenantId", "SelectedSchoolId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_school_id"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_student_profiles_tenant_id_user_id"); - - b.ToTable("student_profiles", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AvatarUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("avatar_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("LastSeenAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_seen_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPasswordHash") - .HasMaxLength(512) - .HasColumnType("character varying(512)") - .HasColumnName("legacy_password_hash"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PasswordMigrationRequired") - .HasColumnType("boolean") - .HasColumnName("password_migration_required"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("PrimaryRole") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("primary_role"); - - b.Property("RawProfile") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_profile") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Score") - .HasColumnType("integer") - .HasColumnName("score"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Username") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("username"); - - b.HasKey("Id") - .HasName("pk_users"); - - b.HasIndex("Email") - .IsUnique() - .HasDatabaseName("ix_users_email"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_users_legacy_id"); - - b.HasIndex("Phone") - .IsUnique() - .HasDatabaseName("ix_users_phone"); - - b.HasIndex("Username") - .IsUnique() - .HasDatabaseName("ix_users_username"); - - b.ToTable("users", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", 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("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("OpenId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("open_id"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderSubject") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("provider_subject"); - - b.Property("SecretPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("secret_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UnionId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("union_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_identities"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_identities_user_id"); - - b.HasIndex("Provider", "ProviderSubject") - .IsUnique() - .HasDatabaseName("ix_user_identities_provider_provider_subject"); - - b.ToTable("user_identities", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("AnsweredAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("answered_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IsCorrect") - .HasColumnType("boolean") - .HasColumnName("is_correct"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("QuestionVersionId") - .HasColumnType("uuid") - .HasColumnName("question_version_id"); - - b.Property("SelectedOptions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("selected_options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_answer_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_answer_records_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_answer_records_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_answer_records_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id"); - - b.HasIndex("TenantId", "QuestionId", "QuestionVersionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id_question_version_id"); - - b.HasIndex("TenantId", "UserId", "PracticeSessionId") - .HasDatabaseName("ix_answer_records_tenant_id_user_id_practice_session_id"); - - b.ToTable("answer_records", null, t => - { - t.HasCheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActiveUsers") - .HasColumnType("integer") - .HasColumnName("active_users"); - - 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("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("NewOrders") - .HasColumnType("integer") - .HasColumnName("new_orders"); - - b.Property("NewQuestions") - .HasColumnType("integer") - .HasColumnName("new_questions"); - - b.Property("NewRevenueCents") - .HasColumnType("integer") - .HasColumnName("new_revenue_cents"); - - b.Property("NewUsers") - .HasColumnType("integer") - .HasColumnName("new_users"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_dashboard_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_dashboard_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_stat_date_region_id"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId"), false); - - b.ToTable("dashboard_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", 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("ExamAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("exam_at"); - - b.Property("ExamName") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("exam_name"); - - b.Property("ExamType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("exam_type"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("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_exam_dates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_exam_dates_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_exam_dates_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_exam_dates_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId", "ExamAt") - .HasDatabaseName("ix_exam_dates_tenant_id_school_id_exam_at"); - - b.ToTable("exam_dates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_favorite_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_favorite_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_favorite_questions_tenant_id_question_id"); - - b.ToTable("favorite_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("access_mode"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EntitlementId") - .HasColumnType("uuid") - .HasColumnName("entitlement_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("GrantedCount") - .HasColumnType("integer") - .HasColumnName("granted_count"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("Reason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("reason"); - - b.Property("RequestedCount") - .HasColumnType("integer") - .HasColumnName("requested_count"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_access_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_access_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_access_events_user_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_access_events_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_practice_access_events_tenant_id_user_id_created_at"); - - b.ToTable("practice_access_events", null, t => - { - t.HasCheckConstraint("ck_practice_access_events_consumed_free_quota", "consumed_free_quota >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_granted_count", "granted_count >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_requested_count", "requested_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", 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("FreeLimit") - .HasColumnType("integer") - .HasColumnName("free_limit"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsageDate") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasColumnName("usage_date") - .HasDefaultValueSql("current_date"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_daily_usage"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_daily_usage_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_daily_usage_user_id"); - - b.HasIndex("TenantId", "UserId", "UsageDate") - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date"); - - b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId") - .IsUnique() - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date_scope_typ~"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId"), false); - - b.ToTable("practice_daily_usage", null, t => - { - t.HasCheckConstraint("ck_practice_daily_usage_free_limit", "free_limit >= 0"); - - t.HasCheckConstraint("ck_practice_daily_usage_used_count", "used_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessEntitlementId") - .HasColumnType("uuid") - .HasColumnName("access_entitlement_id"); - - b.Property("AccessMode") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasDefaultValue("free") - .HasColumnName("access_mode"); - - b.Property("AccessSnapshot") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("access_snapshot") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("ContentNodeId") - .HasColumnType("uuid") - .HasColumnName("content_node_id"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("FinishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("finished_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at") - .HasDefaultValueSql("now()"); - - b.Property("TargetId") - .HasColumnType("uuid") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_sessions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "UserId", "Id") - .HasName("ak_practice_sessions_tenant_id_user_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_sessions_user_id"); - - b.HasIndex("TenantId", "BlueprintId") - .HasDatabaseName("ix_practice_sessions_tenant_id_blueprint_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_sessions_tenant_id_collection_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_practice_sessions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_sessions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "UserId", "StartedAt") - .HasDatabaseName("ix_practice_sessions_tenant_id_user_id_started_at"); - - b.ToTable("practice_sessions", null, t => - { - t.HasCheckConstraint("ck_practice_sessions_consumed_free_quota", "consumed_free_quota >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionResults") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_results") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionStats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("section_stats") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at"); - - b.Property("SubmittedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("submitted_at") - .HasDefaultValueSql("now()"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalQuestions") - .HasColumnType("integer") - .HasColumnName("total_questions"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.Property("WrongQuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("wrong_question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.HasKey("Id") - .HasName("pk_practice_session_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_reports_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_session_reports_user_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_session_reports_tenant_id_collection_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .IsUnique() - .HasDatabaseName("ix_practice_session_reports_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "BlueprintId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_blueprint_id_submitted_at") - .HasFilter("blueprint_id is not null"); - - b.HasIndex("TenantId", "UserId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_user_id_submitted_at"); - - b.ToTable("practice_session_reports", null, t => - { - t.HasCheckConstraint("ck_practice_session_reports_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_reports_counts", "total_questions >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_duration", "duration_seconds >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("question_type"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - b.Property("SectionName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("section_name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_practice_session_report_sections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_report_sections_tenant_id_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_practice_session~"); - - b.HasIndex("TenantId", "ReportId", "SectionKey") - .IsUnique() - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sectio~"); - - b.HasIndex("TenantId", "ReportId", "SortOrder") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sort_o~"); - - b.ToTable("practice_session_report_sections", null, t => - { - t.HasCheckConstraint("ck_practice_session_report_sections_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_report_sections_counts", "question_count >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_report_sections_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", 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("LastAccessAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_access_at"); - - b.Property("LastPracticeAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_practice_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("practice_type"); - - b.Property("Progress") - .HasColumnType("integer") - .HasColumnName("progress"); - - b.Property("TargetLegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("target_legacy_id"); - - b.Property("TargetName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("target_name"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_recent_practices"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_recent_practices_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_recent_practices_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_recent_practices_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "LastAccessAt") - .HasDatabaseName("ix_recent_practices_tenant_id_user_id_last_access_at"); - - b.ToTable("recent_practices", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attachments") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("attachments") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("Contact") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("contact"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("HandledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("handled_at"); - - b.Property("HandledBy") - .HasColumnType("uuid") - .HasColumnName("handled_by"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Resolution") - .HasColumnType("text") - .HasColumnName("resolution"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_reports_tenant_id_id"); - - b.HasIndex("HandledBy") - .HasDatabaseName("ix_reports_handled_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_reports_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_reports_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_question_id_created_at") - .HasFilter("question_id is not null"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_status_created_at"); - - b.ToTable("reports", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_report_status_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_report_status_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_report_status_events_actor_user_id"); - - b.HasIndex("TenantId", "ReportId", "CreatedAt") - .HasDatabaseName("ix_report_status_events_tenant_id_report_id_created_at"); - - b.ToTable("report_status_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CodeCount") - .HasColumnType("integer") - .HasColumnName("code_count"); - - b.Property("CodeEstimated") - .HasColumnType("integer") - .HasColumnName("code_estimated"); - - b.Property("CodeUsed") - .HasColumnType("integer") - .HasColumnName("code_used"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EstimatedRevenueCents") - .HasColumnType("integer") - .HasColumnName("estimated_revenue_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("OrderCount") - .HasColumnType("integer") - .HasColumnName("order_count"); - - b.Property("RealRevenueCents") - .HasColumnType("integer") - .HasColumnName("real_revenue_cents"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_revenue_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_revenue_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_stat_date_region_id_sale_type"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType"), false); - - b.ToTable("revenue_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BalanceAfter") - .HasColumnType("integer") - .HasColumnName("balance_after"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("IdempotencyKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("idempotency_key"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Points") - .HasColumnType("integer") - .HasColumnName("points"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_score_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_score_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_score_events_user_id"); - - b.HasIndex("TenantId", "IdempotencyKey") - .IsUnique() - .HasDatabaseName("ix_user_score_events_tenant_id_idempotency_key"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_user_score_events_tenant_id_user_id_created_at"); - - b.ToTable("user_score_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("LastWrongAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("last_wrong_at") - .HasDefaultValueSql("now()"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("WrongCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(1) - .HasColumnName("wrong_count"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_wrong_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_wrong_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_wrong_questions_tenant_id_question_id"); - - b.ToTable("wrong_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Announcement", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BackgroundColor") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("background_color"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("Link") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("link"); - - 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_announcements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_announcements_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_announcements_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "IsActive", "SortOrder") - .HasDatabaseName("ix_announcements_tenant_id_is_active_sort_order"); - - b.ToTable("announcements", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.AuditLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Action") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("action"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - 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("IpAddress") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("ip_address"); - - b.Property("TargetId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_audit_logs"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_audit_logs_actor_user_id"); - - b.HasIndex("TenantId", "CreatedAt") - .HasDatabaseName("ix_audit_logs_tenant_id_created_at"); - - b.HasIndex("TenantId", "TargetType", "TargetId", "CreatedAt") - .HasDatabaseName("ix_audit_logs_tenant_id_target_type_target_id_created_at"); - - b.ToTable("audit_logs", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Badge", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("ConditionExtra") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("condition_extra") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ConditionField") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("condition_field"); - - b.Property("ConditionOperator") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("condition_operator"); - - b.Property("ConditionValue") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)") - .HasColumnName("condition_value"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("IconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("icon_url"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Level") - .HasColumnType("integer") - .HasColumnName("level"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnlockType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("unlock_type"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_badges"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_badges_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_badges_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "Category", "IsActive", "SortOrder") - .HasDatabaseName("ix_badges_tenant_id_category_is_active_sort_order"); - - b.ToTable("badges", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Banner", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BackgroundColor") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("background_color"); - - b.Property("BorderColor") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("border_color"); - - b.Property("ButtonLink") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("button_link"); - - b.Property("ButtonText") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("button_text"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Subtitle") - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("subtitle"); - - 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.HasKey("Id") - .HasName("pk_banners"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_banners_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_banners_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_banners_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("banners", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Faq", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Answer") - .HasColumnType("text") - .HasColumnName("answer"); - - 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("Question") - .HasColumnType("text") - .HasColumnName("question"); - - 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.HasKey("Id") - .HasName("pk_faqs"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_faqs_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_faqs_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_faqs_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("faqs", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantContentNotification", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActionLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("action_label"); - - b.Property("ActionPath") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("action_path"); - - b.Property("AdoptionId") - .HasColumnType("uuid") - .HasColumnName("adoption_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("DedupeKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("dedupe_key"); - - b.Property("Message") - .IsRequired() - .HasColumnType("text") - .HasColumnName("message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NotificationType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("notification_type"); - - b.Property("ReadAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("read_at"); - - b.Property("ReadBy") - .HasColumnType("uuid") - .HasColumnName("read_by"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("Severity") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("severity"); - - b.Property("SourceQuestionBankId") - .HasColumnType("uuid") - .HasColumnName("source_question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenant_content_notifications"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_content_notifications_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_content_notifications_created_by"); - - b.HasIndex("ReadBy") - .HasDatabaseName("ix_tenant_content_notifications_read_by"); - - b.HasIndex("TenantId", "SourceQuestionBankId") - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_source_question_bank~"); - - b.HasIndex("TenantId", "NotificationType", "DedupeKey") - .IsUnique() - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_notification_type_de~") - .HasFilter("dedupe_key is not null"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_status_created_at"); - - b.HasIndex("TenantId", "AdoptionId", "NotificationType", "Status") - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_adoption_id_notifica~"); - - b.ToTable("tenant_content_notifications", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantThemeConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActivePublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("active_public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ActiveTemplateCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("active_template_code"); - - b.Property("ActiveTheme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("active_theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DraftPublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("draft_public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("DraftTemplateCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("draft_template_code"); - - b.Property("DraftTheme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("draft_theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("DraftUpdatedBy") - .HasColumnType("uuid") - .HasColumnName("draft_updated_by"); - - b.Property("PublishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("published_at"); - - b.Property("PublishedBy") - .HasColumnType("uuid") - .HasColumnName("published_by"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_theme_configs"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_theme_configs_tenant_id_id"); - - b.HasIndex("ActiveTemplateCode") - .HasDatabaseName("ix_tenant_theme_configs_active_template_code"); - - b.HasIndex("DraftTemplateCode") - .HasDatabaseName("ix_tenant_theme_configs_draft_template_code"); - - b.HasIndex("DraftUpdatedBy") - .HasDatabaseName("ix_tenant_theme_configs_draft_updated_by"); - - b.HasIndex("PublishedBy") - .HasDatabaseName("ix_tenant_theme_configs_published_by"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_tenant_theme_configs_tenant_id"); - - b.ToTable("tenant_theme_configs", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantThemeTemplate", 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("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PreviewImageUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("preview_image_url"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenant_theme_templates"); - - b.HasAlternateKey("Code") - .HasName("ak_tenant_theme_templates_code"); - - b.HasIndex("Code") - .IsUnique() - .HasDatabaseName("ix_tenant_theme_templates_code"); - - b.HasIndex("Status", "SortOrder", "Code") - .HasDatabaseName("ix_tenant_theme_templates_status_sort_order_code"); - - b.ToTable("tenant_theme_templates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserBadge", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BadgeId") - .HasColumnType("uuid") - .HasColumnName("badge_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("GrantedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("granted_at"); - - b.Property("GrantedBy") - .HasColumnType("uuid") - .HasColumnName("granted_by"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_badges"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_badges_tenant_id_id"); - - b.HasIndex("GrantedBy") - .HasDatabaseName("ix_user_badges_granted_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_badges_user_id"); - - b.HasIndex("TenantId", "BadgeId") - .HasDatabaseName("ix_user_badges_tenant_id_badge_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_user_badges_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "BadgeId") - .IsUnique() - .HasDatabaseName("ix_user_badges_tenant_id_user_id_badge_id"); - - b.ToTable("user_badges", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserNotification", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActionLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("action_label"); - - b.Property("ActionPath") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("action_path"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DedupeKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("dedupe_key"); - - b.Property("Message") - .IsRequired() - .HasColumnType("text") - .HasColumnName("message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NotificationType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("notification_type"); - - b.Property("ReadAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("read_at"); - - b.Property("Severity") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("severity"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_notifications"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_notifications_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_user_notifications_created_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_notifications_user_id"); - - b.HasIndex("TenantId", "SourceType", "SourceId") - .HasDatabaseName("ix_user_notifications_tenant_id_source_type_source_id"); - - b.HasIndex("TenantId", "UserId", "NotificationType", "DedupeKey") - .IsUnique() - .HasDatabaseName("ix_user_notifications_tenant_id_user_id_notification_type_dedu~") - .HasFilter("dedupe_key is not null"); - - b.HasIndex("TenantId", "UserId", "Status", "CreatedAt") - .HasDatabaseName("ix_user_notifications_tenant_id_user_id_status_created_at"); - - b.ToTable("user_notifications", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - 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("CurrentVersionId") - .HasColumnType("uuid") - .HasColumnName("current_version_id"); - - b.Property("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExamMarkers") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("exam_markers") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("HasVideoExplanation") - .HasColumnType("boolean") - .HasColumnName("has_video_explanation"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyNodeId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_node_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("MediaUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("media_url"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PrimaryCollectionId") - .HasColumnType("uuid") - .HasColumnName("primary_collection_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Type") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("type"); - - b.Property("TypeLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("type_label"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_questions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_questions_tenant_id_id"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_questions_tenant_id_category_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_questions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_questions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_questions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "NodeId") - .HasDatabaseName("ix_questions_tenant_id_node_id"); - - b.HasIndex("TenantId", "PrimaryCollectionId") - .HasDatabaseName("ix_questions_tenant_id_primary_collection_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_questions_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_questions_tenant_id_subject_id"); - - b.HasIndex("TenantId", "Id", "CurrentVersionId") - .HasDatabaseName("ix_questions_tenant_id_id_current_version_id"); - - b.ToTable("questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SourceScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_scope"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_banks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_banks_tenant_id_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_banks_tenant_id_region_id"); - - b.ToTable("question_banks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("CodeLang") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("code_lang"); - - b.Property("CodeTemplate") - .HasColumnType("text") - .HasColumnName("code_template"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CorrectOptionIndex") - .HasColumnType("integer") - .HasColumnName("correct_option_index"); - - b.Property("CorrectOptionIndices") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("correct_option_indices") - .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("Explanation") - .HasColumnType("text") - .HasColumnName("explanation"); - - b.Property("Options") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubQuestions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sub_questions") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("VersionNo") - .HasColumnType("integer") - .HasColumnName("version_no"); - - b.HasKey("Id") - .HasName("pk_question_versions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_versions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "QuestionId", "Id") - .HasName("ak_question_versions_tenant_id_question_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_versions_created_by"); - - b.HasIndex("QuestionId", "VersionNo") - .IsUnique() - .HasDatabaseName("ix_question_versions_question_id_version_no"); - - b.ToTable("question_versions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", 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("FailureCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("failure_code"); - - b.Property("Identifier") - .HasMaxLength(320) - .HasColumnType("character varying(320)") - .HasColumnName("identifier"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Result") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("result"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_login_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_login_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_login_events_user_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_auth_login_events_tenant_id_user_id_created_at"); - - b.ToTable("auth_login_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", 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("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("RevokedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("revoked_at"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TokenHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("token_hash"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_sessions_tenant_id_id"); - - b.HasIndex("TokenHash") - .IsUnique() - .HasDatabaseName("ix_auth_sessions_token_hash"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_sessions_user_id"); - - b.HasIndex("TenantId", "UserId", "ExpiresAt") - .HasDatabaseName("ix_auth_sessions_tenant_id_user_id_expires_at") - .HasFilter("revoked_at is null"); - - b.ToTable("auth_sessions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Dimension") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("dimension"); - - b.Property("ScopeHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("scope_hash"); - - b.Property("BucketStart") - .HasColumnType("timestamp with time zone") - .HasColumnName("bucket_start"); - - b.Property("RequestCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0) - .HasColumnName("request_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId", "Dimension", "ScopeHash", "BucketStart") - .HasName("pk_sms_send_rate_limits"); - - b.HasIndex("UpdatedAt") - .HasDatabaseName("ix_sms_send_rate_limits_updated_at"); - - b.ToTable("sms_send_rate_limits", null, t => - { - t.HasCheckConstraint("ck_sms_send_rate_limits_request_count", "request_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempts") - .HasColumnType("integer") - .HasColumnName("attempts"); - - b.Property("CodeHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("code_hash"); - - b.Property("ConsumedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("consumed_at"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phone") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Purpose") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("purpose"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_sms_verification_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_sms_verification_codes_tenant_id_id"); - - b.HasIndex("TenantId", "Phone", "Purpose") - .IsUnique() - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "CreatedAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_created_at") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "ExpiresAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_expires_at"); - - b.ToTable("sms_verification_codes", null, t => - { - t.HasCheckConstraint("ck_sms_verification_codes_attempts", "attempts >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BillingStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("billing_status"); - - 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("LegalName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("legal_name"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OwnerUserId") - .HasColumnType("uuid") - .HasColumnName("owner_user_id"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("slug"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenants"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenants_legacy_id"); - - b.HasIndex("OwnerUserId") - .HasDatabaseName("ix_tenants_owner_user_id"); - - b.HasIndex("Slug") - .IsUnique() - .HasDatabaseName("ix_tenants_slug"); - - b.ToTable("tenants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ConfigPublic") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("config_public") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_auth_providers"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_auth_providers_tenant_id_id"); - - b.HasIndex("TenantId", "Provider") - .IsUnique() - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider"); - - b.HasIndex("TenantId", "Provider", "Status") - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider_status"); - - b.ToTable("tenant_auth_providers", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("BrandName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("brand_name"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FaviconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("favicon_url"); - - b.Property("LogoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("logo_url"); - - b.Property("OrganizationName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("organization_name"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ServiceAccountName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("service_account_name"); - - b.Property("ServiceWechat") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("service_wechat"); - - b.Property("ShortName") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("short_name"); - - b.Property("Slogan") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("slogan"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_branding"); - - b.ToTable("tenant_branding", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Code") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("code"); - - 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("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_classes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_classes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_classes_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_classes_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_code") - .HasFilter("code is not null and code <> ''"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_tenant_classes_tenant_id_region_id") - .HasFilter("region_id is not null"); - - b.HasIndex("TenantId", "Status", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_tenant_classes_tenant_id_status_sort_order_created_at"); - - b.ToTable("tenant_classes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_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("JoinedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("joined_at") - .HasDefaultValueSql("now()"); - - b.Property("LeftAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("left_at"); - - b.Property("MemberType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("member_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_class_members"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_class_members_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_class_members_user_id"); - - b.HasIndex("TenantId", "ClassId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_status_member_type"); - - b.HasIndex("TenantId", "ClassId", "UserId", "MemberType") - .IsUnique() - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_user_id_member_type"); - - b.HasIndex("TenantId", "UserId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_user_id_status_member_type"); - - b.ToTable("tenant_class_members", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", 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("DomainType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("domain_type"); - - b.Property("Host") - .IsRequired() - .HasMaxLength(253) - .HasColumnType("citext") - .HasColumnName("host"); - - b.Property("IsPrimary") - .HasColumnType("boolean") - .HasColumnName("is_primary"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VerificationToken") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("verification_token"); - - b.Property("VerifiedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("verified_at"); - - b.HasKey("Id") - .HasName("pk_tenant_domains"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_domains_tenant_id_id"); - - b.HasIndex("Host") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_host"); - - b.HasIndex("TenantId", "IsPrimary") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_tenant_id_is_primary") - .HasFilter("is_primary"); - - b.ToTable("tenant_domains", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", 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("LegacyRole") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("legacy_role"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Role") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("role"); - - b.Property("RoleTemplateId") - .HasColumnType("uuid") - .HasColumnName("role_template_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_memberships"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_memberships_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_memberships_user_id"); - - b.HasIndex("TenantId", "RoleTemplateId") - .HasDatabaseName("ix_tenant_memberships_tenant_id_role_template_id"); - - b.HasIndex("TenantId", "UserId", "Role") - .IsUnique() - .HasDatabaseName("ix_tenant_memberships_tenant_id_user_id_role"); - - b.ToTable("tenant_memberships", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BaseRole") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("base_role"); - - 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("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DataScope") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("data_scope") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("FieldPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("field_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("IsSystem") - .HasColumnType("boolean") - .HasColumnName("is_system"); - - b.Property("MenuPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("menu_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ModulePermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_role_templates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_role_templates_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_role_templates_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_role_templates_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_role_templates_tenant_id_code"); - - b.HasIndex("TenantId", "Status", "SortOrder") - .HasDatabaseName("ix_tenant_role_templates_tenant_id_status_sort_order"); - - b.ToTable("tenant_role_templates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("AdminFeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("admin_feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PublicConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_settings"); - - b.ToTable("tenant_settings", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignedToUserId") - .HasColumnType("uuid") - .HasColumnName("assigned_to_user_id"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_id"); - - b.Property("CompletedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("completed_at"); - - b.Property("CompletedBy") - .HasColumnType("uuid") - .HasColumnName("completed_by"); - - 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("DueAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("due_at"); - - b.Property("FollowupType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("followup_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .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.HasKey("Id") - .HasName("pk_tenant_student_followups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_followups_tenant_id_id"); - - b.HasIndex("AssignedToUserId") - .HasDatabaseName("ix_tenant_student_followups_assigned_to_user_id"); - - b.HasIndex("CompletedBy") - .HasDatabaseName("ix_tenant_student_followups_completed_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_followups_student_user_id"); - - b.HasIndex("TenantId", "AssignedToUserId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_assigned_to_user_id_stat~") - .HasFilter("assigned_to_user_id is not null"); - - b.HasIndex("TenantId", "ClassId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_class_id_status_due_at") - .HasFilter("class_id is not null"); - - b.HasIndex("TenantId", "StudentUserId", "Status", "DueAt", "CreatedAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_student_user_id_status_d~"); - - b.ToTable("tenant_student_followups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Content") - .IsRequired() - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("IsPinned") - .HasColumnType("boolean") - .HasColumnName("is_pinned"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NoteType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("note_type"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - 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_tenant_student_notes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_notes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_student_notes_created_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_notes_student_user_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_student_notes_updated_by"); - - b.HasIndex("TenantId", "CreatedBy", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_created_by_created_at") - .HasFilter("created_by is not null"); - - b.HasIndex("TenantId", "StudentUserId", "IsPinned", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_student_user_id_is_pinned_cr~"); - - b.ToTable("tenant_student_notes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Category", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_categories_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Major", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_majors_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.ModuleNode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_module_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_module_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Region", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_regions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.RegionModule", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_region_modules_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_region_modules_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.School", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_schools_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Subject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.ActivationCode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AgentUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_users_agent_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_activation_codes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UsedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_users_used_by"); - - b.HasOne("Tiku.Domain.Commerce.CodeBatch", null) - .WithMany() - .HasForeignKey("TenantId", "BatchId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_code_batches_tenant_id_batch_id"); - - b.HasOne("Tiku.Domain.Commerce.CouponRedemption", null) - .WithMany() - .HasForeignKey("TenantId", "CouponRedemptionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_coupon_redemptions_tenant_id_coupon_redemp~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "UsedRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_regions_tenant_id_used_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CodeBatch", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_code_batches_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationBatch", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_batches_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_batches_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationIssue", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedTo") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_issues_users_assigned_to"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_issues_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ResolvedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_issues_users_resolved_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_issues_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceReconciliationBatch", null) - .WithMany() - .HasForeignKey("TenantId", "BatchId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_commerce_reconciliation_batc~"); - - b.HasOne("Tiku.Domain.Commerce.CommerceReconciliationItem", null) - .WithMany() - .HasForeignKey("TenantId", "ItemId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_commerce_reconciliation_item~"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_payments_tenant_id_payment_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceRefundRequest", null) - .WithMany() - .HasForeignKey("TenantId", "RefundRequestId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_commerce_refund_requests_ten~"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationIssueEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_issue_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_issue_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceReconciliationIssue", null) - .WithMany() - .HasForeignKey("TenantId", "IssueId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_issue_events_commerce_reconciliatio~"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceReconciliationBatch", null) - .WithMany() - .HasForeignKey("TenantId", "BatchId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_items_commerce_reconciliation_batch~"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_items_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_items_payments_tenant_id_payment_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceRefundRequest", null) - .WithMany() - .HasForeignKey("TenantId", "RefundRequestId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_items_commerce_refund_requests_tena~"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceRefundEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_refund_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_refund_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceRefundRequest", null) - .WithMany() - .HasForeignKey("TenantId", "RefundRequestId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_refund_events_commerce_refund_requests_tenant_id_r~"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceRefundRequest", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ProcessedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_refund_requests_users_processed_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("RequestedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_refund_requests_users_requested_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReviewedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_refund_requests_users_reviewed_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_refund_requests_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_refund_requests_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_refund_requests_payments_tenant_id_payment_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Coupon", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_coupons_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_coupons_svip_plans_tenant_id_plan_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CouponRedemption", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_coupon_redemptions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_users_user_id"); - - b.HasOne("Tiku.Domain.Commerce.Coupon", null) - .WithMany() - .HasForeignKey("TenantId", "CouponId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_coupons_tenant_id_coupon_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_svip_plans_tenant_id_plan_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Entitlement", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("RevokedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_entitlements_users_revoked_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_entitlements_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_entitlements_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Order", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_orders_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_orders_users_user_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_orders_svip_plans_tenant_id_plan_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_orders_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.OrderItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_order_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_order_items_orders_tenant_id_order_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Payment", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payments_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payments_orders_tenant_id_order_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.PaymentEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payment_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_payment_events_payments_tenant_id_payment_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Product", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_products_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_products_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.SvipPlan", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_svip_plans_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_svip_plans_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantPaymentAccount", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_payment_accounts_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantSubscription", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_subscriptions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantUsageRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_usage_records_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.AppAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_app_assets_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAsset", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_assets_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_updated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("VerifiedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_verified_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentEntry", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_entries_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportIssue", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportItem", null) - .WithMany() - .HasForeignKey("TenantId", "ItemId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_import_issues_content_import_items_tenant_id_item_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportJob", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_import_jobs_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_jobs_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "TargetCategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_categories_tenant_id_target_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "TargetContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_content_nodes_tenant_id_target_content_~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "TargetQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_question_banks_tenant_id_target_questio~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "TargetRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_regions_tenant_id_target_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentNode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_nodes_content_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookChapter", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_chapters_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.HandbookSubject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_chapters_handbook_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.HandbookChapter", null) - .WithMany() - .HasForeignKey("TenantId", "ChapterId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_entries_handbook_chapters_tenant_id_chapter_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_images_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_blueprints_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_question_collections_tenant_id_collecti~"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_question_banks_tenant_id_question_bank~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_question_collections_tenant_id_co~"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_type_groups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_type_groups_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_videos_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.Content.VideoExplanation", null) - .WithMany() - .HasForeignKey("TenantId", "VideoId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_video_explanations_tenant_id_video_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SourceSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_source_subject_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_video_explanations_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_video_explanations_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_units_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_words_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyUnit", null) - .WithMany() - .HasForeignKey("TenantId", "UnitId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_vocabulary_units_tenant_id_unit_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlement", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("GeneratedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_generated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("PaidBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_paid_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlements_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReviewedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_reviewed_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlements_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlementItem", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlement_items_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlement_items_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlement_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.CommissionSettlement", null) - .WithMany() - .HasForeignKey("TenantId", "SettlementId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlement_items_commission_settlements_tenant_i~"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmConfig", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_config_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookLog", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_webhook_log_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookQueueItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_webhook_queue_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralCode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_codes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_codes_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralLead", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_assigned_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedToUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_assigned_to_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_leads_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_leads_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.ReferralTrack", null) - .WithMany() - .HasForeignKey("TenantId", "FirstTrackId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_referral_tracks_tenant_id_first_track_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralQrcode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_qrcodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_qrcodes_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTeamEdge", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("LeaderUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_team_edges_users_leader_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("MemberUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_team_edges_users_member_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_team_edges_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTrack", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("TargetUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_users_target_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_tracks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.ReferralLead", null) - .WithMany() - .HasForeignKey("TenantId", "LeadId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_referral_leads_tenant_id_lead_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.TenantCommissionSetting", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_commission_settings_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_commission_settings_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedMajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_majors_tenant_id_selected_major_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedSchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_schools_tenant_id_selected_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_identities_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId", "QuestionVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_question_versions_tenant_id_question_id_ques~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "UserId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "UserId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_practice_sessions_tenant_id_user_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_dashboard_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_dashboard_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_exam_dates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_access_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_users_user_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_practice_sessions_tenant_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_question_collections_tenant_id_collection~"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_practice_blueprints_tenant_id_blue~"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_question_collections_tenant_id_col~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_practice_sessions_tenant_id_practi~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_sessions_tenant_i~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSessionReport", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_session_reports_t~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_recent_practices_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_recent_practices_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("HandledBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_handled_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_reports_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_report_status_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.Report", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_reports_tenant_id_report_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_revenue_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_revenue_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Announcement", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_announcements_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.AuditLog", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_audit_logs_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_audit_logs_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Badge", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_badges_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Banner", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_banners_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_banners_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Faq", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_faqs_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_faqs_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantContentNotification", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_content_notifications_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReadBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_content_notifications_users_read_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_content_notifications_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "SourceQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_tenant_content_notifications_question_banks_tenant_id_sourc~"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantThemeConfig", b => - { - b.HasOne("Tiku.Domain.Operations.TenantThemeTemplate", null) - .WithMany() - .HasForeignKey("ActiveTemplateCode") - .HasPrincipalKey("Code") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_tenant_theme_templates_active_template~"); - - b.HasOne("Tiku.Domain.Operations.TenantThemeTemplate", null) - .WithMany() - .HasForeignKey("DraftTemplateCode") - .HasPrincipalKey("Code") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_tenant_theme_templates_draft_template_~"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("DraftUpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_users_draft_updated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("PublishedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_users_published_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_theme_configs_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserBadge", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("GrantedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_user_badges_users_granted_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_badges_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_user_badges_users_user_id"); - - b.HasOne("Tiku.Domain.Operations.Badge", null) - .WithMany() - .HasForeignKey("TenantId", "BadgeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_user_badges_badges_tenant_id_badge_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserNotification", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_user_notifications_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_notifications_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_notifications_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "PrimaryCollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_collections_tenant_id_primary_collection~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_banks_tenant_id_question_bank_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_subjects_tenant_id_subject_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "Id", "CurrentVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_versions_tenant_id_id_current_version_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_banks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_banks_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_versions_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_versions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_login_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_auth_login_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_send_rate_limits_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_verification_codes_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("OwnerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenants_users_owner_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_auth_providers_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantBranding", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_branding_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_classes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_classes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_domains_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantRoleTemplate", null) - .WithMany() - .HasForeignKey("TenantId", "RoleTemplateId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_memberships_tenant_role_templates_tenant_id_role_tem~"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_role_templates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantSettings", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_settings_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedToUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_assigned_to_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CompletedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_completed_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_updated_by"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725215222_AddCommerceRefundAndReconciliationPersistence.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725215222_AddCommerceRefundAndReconciliationPersistence.cs deleted file mode 100644 index bf42c68..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725215222_AddCommerceRefundAndReconciliationPersistence.cs +++ /dev/null @@ -1,669 +0,0 @@ -using System; -using System.Text.Json; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Tiku.Infrastructure.Persistence.Migrations -{ - /// - public partial class AddCommerceRefundAndReconciliationPersistence : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "refunded_amount_cents", - table: "payments", - type: "integer", - nullable: false, - defaultValue: 0); - - migrationBuilder.AddColumn( - name: "refunded_amount_cents", - table: "orders", - type: "integer", - nullable: false, - defaultValue: 0); - - migrationBuilder.AddColumn( - name: "revoked_at", - table: "entitlements", - type: "timestamp with time zone", - nullable: true); - - migrationBuilder.AddColumn( - name: "revoked_by", - table: "entitlements", - type: "uuid", - nullable: true); - - migrationBuilder.AddColumn( - name: "revoked_reason", - table: "entitlements", - type: "character varying(1000)", - maxLength: 1000, - nullable: true); - - migrationBuilder.CreateTable( - name: "commerce_reconciliation_batches", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - created_by = table.Column(type: "uuid", nullable: true), - provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - bill_date = table.Column(type: "date", nullable: false), - bill_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - source = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - source_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - source_hash = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - total_count = table.Column(type: "integer", nullable: false), - matched_count = table.Column(type: "integer", nullable: false), - mismatch_count = table.Column(type: "integer", nullable: false), - missing_local_count = table.Column(type: "integer", nullable: false), - missing_provider_count = table.Column(type: "integer", nullable: false), - duplicate_count = table.Column(type: "integer", nullable: false), - ignored_count = table.Column(type: "integer", nullable: false), - amount_cents = table.Column(type: "integer", nullable: false), - refund_amount_cents = table.Column(type: "integer", nullable: false), - fee_cents = table.Column(type: "integer", nullable: false), - completed_at = table.Column(type: "timestamp with time zone", nullable: true), - error = table.Column(type: "text", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_commerce_reconciliation_batches", x => x.id); - table.UniqueConstraint("ak_commerce_reconciliation_batches_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_commerce_reconciliation_batches_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); - table.CheckConstraint("ck_commerce_reconciliation_batches_counts", "total_count >= 0 and matched_count >= 0 and mismatch_count >= 0 and missing_local_count >= 0 and missing_provider_count >= 0 and duplicate_count >= 0 and ignored_count >= 0"); - table.ForeignKey( - name: "fk_commerce_reconciliation_batches_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_commerce_reconciliation_batches_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "commerce_refund_requests", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - order_id = table.Column(type: "uuid", nullable: false), - payment_id = table.Column(type: "uuid", nullable: true), - requested_by = table.Column(type: "uuid", nullable: true), - reviewed_by = table.Column(type: "uuid", nullable: true), - processed_by = table.Column(type: "uuid", nullable: true), - refund_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - provider_refund_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - amount_cents = table.Column(type: "integer", nullable: false), - reason = table.Column(type: "text", nullable: true), - entitlement_action = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - requested_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - reviewed_at = table.Column(type: "timestamp with time zone", nullable: true), - processed_at = table.Column(type: "timestamp with time zone", nullable: true), - succeeded_at = table.Column(type: "timestamp with time zone", nullable: true), - failed_at = table.Column(type: "timestamp with time zone", nullable: true), - cancelled_at = table.Column(type: "timestamp with time zone", nullable: true), - failure_reason = table.Column(type: "text", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_commerce_refund_requests", x => x.id); - table.UniqueConstraint("ak_commerce_refund_requests_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_commerce_refund_requests_amount", "amount_cents > 0"); - table.ForeignKey( - name: "fk_commerce_refund_requests_orders_tenant_id_order_id", - columns: x => new { x.tenant_id, x.order_id }, - principalTable: "orders", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_commerce_refund_requests_payments_tenant_id_payment_id", - columns: x => new { x.tenant_id, x.payment_id }, - principalTable: "payments", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_commerce_refund_requests_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_commerce_refund_requests_users_processed_by", - column: x => x.processed_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_commerce_refund_requests_users_requested_by", - column: x => x.requested_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_commerce_refund_requests_users_reviewed_by", - column: x => x.reviewed_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "commerce_reconciliation_items", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - batch_id = table.Column(type: "uuid", nullable: false), - order_id = table.Column(type: "uuid", nullable: true), - payment_id = table.Column(type: "uuid", nullable: true), - refund_request_id = table.Column(type: "uuid", nullable: true), - row_no = table.Column(type: "integer", nullable: false), - provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - transaction_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - provider_trade_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - provider_refund_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - order_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - refund_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - amount_cents = table.Column(type: "integer", nullable: false), - refund_amount_cents = table.Column(type: "integer", nullable: false), - fee_cents = table.Column(type: "integer", nullable: false), - paid_at = table.Column(type: "timestamp with time zone", nullable: true), - refunded_at = table.Column(type: "timestamp with time zone", nullable: true), - provider_status = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - local_status = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - match_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - issue_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_commerce_reconciliation_items", x => x.id); - table.UniqueConstraint("ak_commerce_reconciliation_items_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_commerce_reconciliation_items_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); - table.CheckConstraint("ck_commerce_reconciliation_items_row", "row_no > 0"); - table.ForeignKey( - name: "fk_commerce_reconciliation_items_commerce_reconciliation_batch~", - columns: x => new { x.tenant_id, x.batch_id }, - principalTable: "commerce_reconciliation_batches", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_commerce_reconciliation_items_commerce_refund_requests_tena~", - columns: x => new { x.tenant_id, x.refund_request_id }, - principalTable: "commerce_refund_requests", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_commerce_reconciliation_items_orders_tenant_id_order_id", - columns: x => new { x.tenant_id, x.order_id }, - principalTable: "orders", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_commerce_reconciliation_items_payments_tenant_id_payment_id", - columns: x => new { x.tenant_id, x.payment_id }, - principalTable: "payments", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_commerce_reconciliation_items_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "commerce_refund_events", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - refund_request_id = table.Column(type: "uuid", nullable: false), - from_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - to_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - event_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - actor_user_id = table.Column(type: "uuid", nullable: true), - details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_commerce_refund_events", x => x.id); - table.UniqueConstraint("ak_commerce_refund_events_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_commerce_refund_events_commerce_refund_requests_tenant_id_r~", - columns: x => new { x.tenant_id, x.refund_request_id }, - principalTable: "commerce_refund_requests", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_commerce_refund_events_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_commerce_refund_events_users_actor_user_id", - column: x => x.actor_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "commerce_reconciliation_issues", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - batch_id = table.Column(type: "uuid", nullable: true), - item_id = table.Column(type: "uuid", nullable: true), - order_id = table.Column(type: "uuid", nullable: true), - payment_id = table.Column(type: "uuid", nullable: true), - refund_request_id = table.Column(type: "uuid", nullable: true), - assigned_to = table.Column(type: "uuid", nullable: true), - created_by = table.Column(type: "uuid", nullable: true), - resolved_by = table.Column(type: "uuid", nullable: true), - issue_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - transaction_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - issue_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - match_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - resolution_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - order_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - refund_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - provider_trade_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - provider_refund_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - amount_cents = table.Column(type: "integer", nullable: false), - refund_amount_cents = table.Column(type: "integer", nullable: false), - resolved_at = table.Column(type: "timestamp with time zone", nullable: true), - due_at = table.Column(type: "timestamp with time zone", nullable: true), - summary = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), - resolution_note = table.Column(type: "text", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_commerce_reconciliation_issues", x => x.id); - table.UniqueConstraint("ak_commerce_reconciliation_issues_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_commerce_reconciliation_issues_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); - table.ForeignKey( - name: "fk_commerce_reconciliation_issues_commerce_reconciliation_batc~", - columns: x => new { x.tenant_id, x.batch_id }, - principalTable: "commerce_reconciliation_batches", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_commerce_reconciliation_issues_commerce_reconciliation_item~", - columns: x => new { x.tenant_id, x.item_id }, - principalTable: "commerce_reconciliation_items", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_commerce_reconciliation_issues_commerce_refund_requests_ten~", - columns: x => new { x.tenant_id, x.refund_request_id }, - principalTable: "commerce_refund_requests", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_commerce_reconciliation_issues_orders_tenant_id_order_id", - columns: x => new { x.tenant_id, x.order_id }, - principalTable: "orders", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_commerce_reconciliation_issues_payments_tenant_id_payment_id", - columns: x => new { x.tenant_id, x.payment_id }, - principalTable: "payments", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_commerce_reconciliation_issues_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_commerce_reconciliation_issues_users_assigned_to", - column: x => x.assigned_to, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_commerce_reconciliation_issues_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_commerce_reconciliation_issues_users_resolved_by", - column: x => x.resolved_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "commerce_reconciliation_issue_events", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - issue_id = table.Column(type: "uuid", nullable: false), - from_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - to_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - event_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - actor_user_id = table.Column(type: "uuid", nullable: true), - note = table.Column(type: "text", nullable: true), - details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_commerce_reconciliation_issue_events", x => x.id); - table.UniqueConstraint("ak_commerce_reconciliation_issue_events_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_commerce_reconciliation_issue_events_commerce_reconciliatio~", - columns: x => new { x.tenant_id, x.issue_id }, - principalTable: "commerce_reconciliation_issues", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_commerce_reconciliation_issue_events_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_commerce_reconciliation_issue_events_users_actor_user_id", - column: x => x.actor_user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.AddCheckConstraint( - name: "ck_payments_refunded_amount", - table: "payments", - sql: "refunded_amount_cents >= 0"); - - migrationBuilder.AddCheckConstraint( - name: "ck_orders_refunded_amount", - table: "orders", - sql: "refunded_amount_cents >= 0"); - - migrationBuilder.CreateIndex( - name: "ix_entitlements_revoked_by", - table: "entitlements", - column: "revoked_by"); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_batches_created_by", - table: "commerce_reconciliation_batches", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_batches_tenant_id_provider_bill_dat~", - table: "commerce_reconciliation_batches", - columns: new[] { "tenant_id", "provider", "bill_date", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_batches_tenant_id_status_created_at", - table: "commerce_reconciliation_batches", - columns: new[] { "tenant_id", "status", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issue_events_actor_user_id", - table: "commerce_reconciliation_issue_events", - column: "actor_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issue_events_tenant_id_issue_id_cre~", - table: "commerce_reconciliation_issue_events", - columns: new[] { "tenant_id", "issue_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issues_assigned_to", - table: "commerce_reconciliation_issues", - column: "assigned_to"); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issues_created_by", - table: "commerce_reconciliation_issues", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issues_resolved_by", - table: "commerce_reconciliation_issues", - column: "resolved_by"); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issues_tenant_id_assigned_to_status~", - table: "commerce_reconciliation_issues", - columns: new[] { "tenant_id", "assigned_to", "status", "due_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issues_tenant_id_batch_id_status_cr~", - table: "commerce_reconciliation_issues", - columns: new[] { "tenant_id", "batch_id", "status", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issues_tenant_id_issue_no", - table: "commerce_reconciliation_issues", - columns: new[] { "tenant_id", "issue_no" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issues_tenant_id_item_id", - table: "commerce_reconciliation_issues", - columns: new[] { "tenant_id", "item_id" }, - unique: true, - filter: "item_id is not null and status in ('open', 'investigating', 'escalated')"); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issues_tenant_id_order_id", - table: "commerce_reconciliation_issues", - columns: new[] { "tenant_id", "order_id" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issues_tenant_id_order_no_created_at", - table: "commerce_reconciliation_issues", - columns: new[] { "tenant_id", "order_no", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issues_tenant_id_payment_id_created~", - table: "commerce_reconciliation_issues", - columns: new[] { "tenant_id", "payment_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issues_tenant_id_refund_request_id", - table: "commerce_reconciliation_issues", - columns: new[] { "tenant_id", "refund_request_id" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_issues_tenant_id_status_severity_cr~", - table: "commerce_reconciliation_issues", - columns: new[] { "tenant_id", "status", "severity", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_items_batch_id_row_no", - table: "commerce_reconciliation_items", - columns: new[] { "batch_id", "row_no" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_items_tenant_id_batch_id_match_stat~", - table: "commerce_reconciliation_items", - columns: new[] { "tenant_id", "batch_id", "match_status", "row_no" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_items_tenant_id_order_id", - table: "commerce_reconciliation_items", - columns: new[] { "tenant_id", "order_id" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_items_tenant_id_order_no_created_at", - table: "commerce_reconciliation_items", - columns: new[] { "tenant_id", "order_no", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_items_tenant_id_payment_id", - table: "commerce_reconciliation_items", - columns: new[] { "tenant_id", "payment_id" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_items_tenant_id_provider_provider_t~", - table: "commerce_reconciliation_items", - columns: new[] { "tenant_id", "provider", "provider_trade_no", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_items_tenant_id_refund_no_provider_~", - table: "commerce_reconciliation_items", - columns: new[] { "tenant_id", "refund_no", "provider_refund_no", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_reconciliation_items_tenant_id_refund_request_id", - table: "commerce_reconciliation_items", - columns: new[] { "tenant_id", "refund_request_id" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_refund_events_actor_user_id", - table: "commerce_refund_events", - column: "actor_user_id"); - - migrationBuilder.CreateIndex( - name: "ix_commerce_refund_events_tenant_id_refund_request_id_created_~", - table: "commerce_refund_events", - columns: new[] { "tenant_id", "refund_request_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_refund_requests_processed_by", - table: "commerce_refund_requests", - column: "processed_by"); - - migrationBuilder.CreateIndex( - name: "ix_commerce_refund_requests_requested_by", - table: "commerce_refund_requests", - column: "requested_by"); - - migrationBuilder.CreateIndex( - name: "ix_commerce_refund_requests_reviewed_by", - table: "commerce_refund_requests", - column: "reviewed_by"); - - migrationBuilder.CreateIndex( - name: "ix_commerce_refund_requests_tenant_id_order_id_created_at", - table: "commerce_refund_requests", - columns: new[] { "tenant_id", "order_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_refund_requests_tenant_id_payment_id", - table: "commerce_refund_requests", - columns: new[] { "tenant_id", "payment_id" }); - - migrationBuilder.CreateIndex( - name: "ix_commerce_refund_requests_tenant_id_refund_no", - table: "commerce_refund_requests", - columns: new[] { "tenant_id", "refund_no" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_commerce_refund_requests_tenant_id_status_created_at", - table: "commerce_refund_requests", - columns: new[] { "tenant_id", "status", "created_at" }); - - migrationBuilder.AddForeignKey( - name: "fk_entitlements_users_revoked_by", - table: "entitlements", - column: "revoked_by", - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "fk_entitlements_users_revoked_by", - table: "entitlements"); - - migrationBuilder.DropTable( - name: "commerce_reconciliation_issue_events"); - - migrationBuilder.DropTable( - name: "commerce_refund_events"); - - migrationBuilder.DropTable( - name: "commerce_reconciliation_issues"); - - migrationBuilder.DropTable( - name: "commerce_reconciliation_items"); - - migrationBuilder.DropTable( - name: "commerce_reconciliation_batches"); - - migrationBuilder.DropTable( - name: "commerce_refund_requests"); - - migrationBuilder.DropCheckConstraint( - name: "ck_payments_refunded_amount", - table: "payments"); - - migrationBuilder.DropCheckConstraint( - name: "ck_orders_refunded_amount", - table: "orders"); - - migrationBuilder.DropIndex( - name: "ix_entitlements_revoked_by", - table: "entitlements"); - - migrationBuilder.DropColumn( - name: "refunded_amount_cents", - table: "payments"); - - migrationBuilder.DropColumn( - name: "refunded_amount_cents", - table: "orders"); - - migrationBuilder.DropColumn( - name: "revoked_at", - table: "entitlements"); - - migrationBuilder.DropColumn( - name: "revoked_by", - table: "entitlements"); - - migrationBuilder.DropColumn( - name: "revoked_reason", - table: "entitlements"); - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725215750_AddContentPlatformOperationsPersistence.Designer.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725215750_AddContentPlatformOperationsPersistence.Designer.cs deleted file mode 100644 index 838715f..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725215750_AddContentPlatformOperationsPersistence.Designer.cs +++ /dev/null @@ -1,13838 +0,0 @@ -// -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("20260725215750_AddContentPlatformOperationsPersistence")] - partial class AddContentPlatformOperationsPersistence - { - /// - 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.Commerce.ActivationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AgentUserId") - .HasColumnType("uuid") - .HasColumnName("agent_user_id"); - - b.Property("BatchId") - .HasColumnType("uuid") - .HasColumnName("batch_id"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CouponCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("coupon_code"); - - b.Property("CouponRedemptionId") - .HasColumnType("uuid") - .HasColumnName("coupon_redemption_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("IsUsed") - .HasColumnType("boolean") - .HasColumnName("is_used"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("SoldTo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("sold_to"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitPriceCents") - .HasColumnType("integer") - .HasColumnName("unit_price_cents"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("used_at"); - - b.Property("UsedBy") - .HasColumnType("uuid") - .HasColumnName("used_by"); - - b.Property("UsedRegionId") - .HasColumnType("uuid") - .HasColumnName("used_region_id"); - - b.HasKey("Id") - .HasName("pk_activation_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_activation_codes_tenant_id_id"); - - b.HasIndex("AgentUserId") - .HasDatabaseName("ix_activation_codes_agent_user_id"); - - b.HasIndex("UsedBy") - .HasDatabaseName("ix_activation_codes_used_by"); - - b.HasIndex("TenantId", "BatchId") - .HasDatabaseName("ix_activation_codes_tenant_id_batch_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_activation_codes_tenant_id_code"); - - b.HasIndex("TenantId", "CouponRedemptionId") - .HasDatabaseName("ix_activation_codes_tenant_id_coupon_redemption_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_activation_codes_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UsedRegionId") - .HasDatabaseName("ix_activation_codes_tenant_id_used_region_id"); - - b.ToTable("activation_codes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CodeBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CampaignName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("campaign_name"); - - b.Property("Channel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("channel"); - - b.Property("CommissionRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("commission_rate"); - - b.Property("CostPriceCents") - .HasColumnType("integer") - .HasColumnName("cost_price_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("DefaultUnitPriceCents") - .HasColumnType("integer") - .HasColumnName("default_unit_price_cents"); - - b.Property("IssuedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("issued_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - 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.HasKey("Id") - .HasName("pk_code_batches"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_code_batches_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_code_batches_tenant_id_legacy_id"); - - b.ToTable("code_batches", null, t => - { - t.HasCheckConstraint("ck_code_batches_amounts", "default_unit_price_cents >= 0 and cost_price_cents >= 0"); - - t.HasCheckConstraint("ck_code_batches_counts", "total_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("BillDate") - .HasColumnType("date") - .HasColumnName("bill_date"); - - b.Property("BillType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("bill_type"); - - b.Property("CompletedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("completed_at"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DuplicateCount") - .HasColumnType("integer") - .HasColumnName("duplicate_count"); - - b.Property("Error") - .HasColumnType("text") - .HasColumnName("error"); - - b.Property("FeeCents") - .HasColumnType("integer") - .HasColumnName("fee_cents"); - - b.Property("IgnoredCount") - .HasColumnType("integer") - .HasColumnName("ignored_count"); - - b.Property("MatchedCount") - .HasColumnType("integer") - .HasColumnName("matched_count"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("MismatchCount") - .HasColumnType("integer") - .HasColumnName("mismatch_count"); - - b.Property("MissingLocalCount") - .HasColumnType("integer") - .HasColumnName("missing_local_count"); - - b.Property("MissingProviderCount") - .HasColumnType("integer") - .HasColumnName("missing_provider_count"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("RefundAmountCents") - .HasColumnType("integer") - .HasColumnName("refund_amount_cents"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source"); - - b.Property("SourceHash") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("source_hash"); - - b.Property("SourceName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("source_name"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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.HasKey("Id") - .HasName("pk_commerce_reconciliation_batches"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_reconciliation_batches_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_commerce_reconciliation_batches_created_by"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_batches_tenant_id_status_created_at"); - - b.HasIndex("TenantId", "Provider", "BillDate", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_batches_tenant_id_provider_bill_dat~"); - - b.ToTable("commerce_reconciliation_batches", null, t => - { - t.HasCheckConstraint("ck_commerce_reconciliation_batches_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commerce_reconciliation_batches_counts", "total_count >= 0 and matched_count >= 0 and mismatch_count >= 0 and missing_local_count >= 0 and missing_provider_count >= 0 and duplicate_count >= 0 and ignored_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationIssue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("AssignedTo") - .HasColumnType("uuid") - .HasColumnName("assigned_to"); - - b.Property("BatchId") - .HasColumnType("uuid") - .HasColumnName("batch_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("DueAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("due_at"); - - b.Property("IssueCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("issue_code"); - - b.Property("IssueNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("issue_no"); - - b.Property("ItemId") - .HasColumnType("uuid") - .HasColumnName("item_id"); - - b.Property("MatchStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("match_status"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("OrderNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("order_no"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderRefundNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_refund_no"); - - b.Property("ProviderTradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_trade_no"); - - b.Property("RefundAmountCents") - .HasColumnType("integer") - .HasColumnName("refund_amount_cents"); - - b.Property("RefundNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("refund_no"); - - b.Property("RefundRequestId") - .HasColumnType("uuid") - .HasColumnName("refund_request_id"); - - b.Property("ResolutionNote") - .HasColumnType("text") - .HasColumnName("resolution_note"); - - b.Property("ResolutionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("resolution_type"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("ResolvedBy") - .HasColumnType("uuid") - .HasColumnName("resolved_by"); - - b.Property("Severity") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("severity"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("Summary") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("summary"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TransactionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("transaction_type"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_commerce_reconciliation_issues"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_reconciliation_issues_tenant_id_id"); - - b.HasIndex("AssignedTo") - .HasDatabaseName("ix_commerce_reconciliation_issues_assigned_to"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_commerce_reconciliation_issues_created_by"); - - b.HasIndex("ResolvedBy") - .HasDatabaseName("ix_commerce_reconciliation_issues_resolved_by"); - - b.HasIndex("TenantId", "IssueNo") - .IsUnique() - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_issue_no"); - - b.HasIndex("TenantId", "ItemId") - .IsUnique() - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_item_id") - .HasFilter("item_id is not null and status in ('open', 'investigating', 'escalated')"); - - b.HasIndex("TenantId", "OrderId") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_order_id"); - - b.HasIndex("TenantId", "RefundRequestId") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_refund_request_id"); - - b.HasIndex("TenantId", "OrderNo", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_order_no_created_at"); - - b.HasIndex("TenantId", "PaymentId", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_payment_id_created~"); - - b.HasIndex("TenantId", "AssignedTo", "Status", "DueAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_assigned_to_status~"); - - b.HasIndex("TenantId", "BatchId", "Status", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_batch_id_status_cr~"); - - b.HasIndex("TenantId", "Status", "Severity", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_status_severity_cr~"); - - b.ToTable("commerce_reconciliation_issues", null, t => - { - t.HasCheckConstraint("ck_commerce_reconciliation_issues_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationIssueEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - 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("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("IssueId") - .HasColumnType("uuid") - .HasColumnName("issue_id"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_commerce_reconciliation_issue_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_reconciliation_issue_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_commerce_reconciliation_issue_events_actor_user_id"); - - b.HasIndex("TenantId", "IssueId", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issue_events_tenant_id_issue_id_cre~"); - - b.ToTable("commerce_reconciliation_issue_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("BatchId") - .HasColumnType("uuid") - .HasColumnName("batch_id"); - - 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("FeeCents") - .HasColumnType("integer") - .HasColumnName("fee_cents"); - - b.Property("IssueCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("issue_code"); - - b.Property("LocalStatus") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("local_status"); - - b.Property("MatchStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("match_status"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("OrderNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("order_no"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderRefundNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_refund_no"); - - b.Property("ProviderStatus") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider_status"); - - b.Property("ProviderTradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_trade_no"); - - b.Property("RefundAmountCents") - .HasColumnType("integer") - .HasColumnName("refund_amount_cents"); - - b.Property("RefundNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("refund_no"); - - b.Property("RefundRequestId") - .HasColumnType("uuid") - .HasColumnName("refund_request_id"); - - b.Property("RefundedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("refunded_at"); - - 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("TransactionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("transaction_type"); - - b.HasKey("Id") - .HasName("pk_commerce_reconciliation_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_reconciliation_items_tenant_id_id"); - - b.HasIndex("BatchId", "RowNo") - .IsUnique() - .HasDatabaseName("ix_commerce_reconciliation_items_batch_id_row_no"); - - b.HasIndex("TenantId", "OrderId") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_order_id"); - - b.HasIndex("TenantId", "PaymentId") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_payment_id"); - - b.HasIndex("TenantId", "RefundRequestId") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_refund_request_id"); - - b.HasIndex("TenantId", "OrderNo", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_order_no_created_at"); - - b.HasIndex("TenantId", "BatchId", "MatchStatus", "RowNo") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_batch_id_match_stat~"); - - b.HasIndex("TenantId", "Provider", "ProviderTradeNo", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_provider_provider_t~"); - - b.HasIndex("TenantId", "RefundNo", "ProviderRefundNo", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_refund_no_provider_~"); - - b.ToTable("commerce_reconciliation_items", null, t => - { - t.HasCheckConstraint("ck_commerce_reconciliation_items_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commerce_reconciliation_items_row", "row_no > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceRefundEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - 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("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("RefundRequestId") - .HasColumnType("uuid") - .HasColumnName("refund_request_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_commerce_refund_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_refund_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_commerce_refund_events_actor_user_id"); - - b.HasIndex("TenantId", "RefundRequestId", "CreatedAt") - .HasDatabaseName("ix_commerce_refund_events_tenant_id_refund_request_id_created_~"); - - b.ToTable("commerce_refund_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceRefundRequest", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("CancelledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("cancelled_at"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EntitlementAction") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("entitlement_action"); - - b.Property("FailedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("failed_at"); - - b.Property("FailureReason") - .HasColumnType("text") - .HasColumnName("failure_reason"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("ProcessedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("processed_at"); - - b.Property("ProcessedBy") - .HasColumnType("uuid") - .HasColumnName("processed_by"); - - b.Property("Provider") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderRefundNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_refund_no"); - - b.Property("Reason") - .HasColumnType("text") - .HasColumnName("reason"); - - b.Property("RefundNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("refund_no"); - - b.Property("RequestedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("requested_at") - .HasDefaultValueSql("now()"); - - b.Property("RequestedBy") - .HasColumnType("uuid") - .HasColumnName("requested_by"); - - b.Property("ReviewedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("reviewed_at"); - - b.Property("ReviewedBy") - .HasColumnType("uuid") - .HasColumnName("reviewed_by"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SucceededAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("succeeded_at"); - - 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_commerce_refund_requests"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_refund_requests_tenant_id_id"); - - b.HasIndex("ProcessedBy") - .HasDatabaseName("ix_commerce_refund_requests_processed_by"); - - b.HasIndex("RequestedBy") - .HasDatabaseName("ix_commerce_refund_requests_requested_by"); - - b.HasIndex("ReviewedBy") - .HasDatabaseName("ix_commerce_refund_requests_reviewed_by"); - - b.HasIndex("TenantId", "PaymentId") - .HasDatabaseName("ix_commerce_refund_requests_tenant_id_payment_id"); - - b.HasIndex("TenantId", "RefundNo") - .IsUnique() - .HasDatabaseName("ix_commerce_refund_requests_tenant_id_refund_no"); - - b.HasIndex("TenantId", "OrderId", "CreatedAt") - .HasDatabaseName("ix_commerce_refund_requests_tenant_id_order_id_created_at"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_commerce_refund_requests_tenant_id_status_created_at"); - - b.ToTable("commerce_refund_requests", null, t => - { - t.HasCheckConstraint("ck_commerce_refund_requests_amount", "amount_cents > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Coupon", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DiscountType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("discount_type"); - - b.Property("DiscountValue") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("discount_value"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("MaxUses") - .HasColumnType("integer") - .HasColumnName("max_uses"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("Source") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("ValidFrom") - .HasColumnType("timestamp with time zone") - .HasColumnName("valid_from"); - - b.Property("ValidTo") - .HasColumnType("timestamp with time zone") - .HasColumnName("valid_to"); - - b.HasKey("Id") - .HasName("pk_coupons"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_coupons_tenant_id_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_coupons_tenant_id_code"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_coupons_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_coupons_tenant_id_plan_id"); - - b.ToTable("coupons", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CouponRedemption", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ClaimedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("claimed_at"); - - b.Property("CouponCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("coupon_code"); - - b.Property("CouponId") - .HasColumnType("uuid") - .HasColumnName("coupon_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DiscountAppliedCents") - .HasColumnType("integer") - .HasColumnName("discount_applied_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("Source") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("used_at"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_coupon_redemptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_coupon_redemptions_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_coupon_redemptions_user_id"); - - b.HasIndex("TenantId", "CouponId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_coupon_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_coupon_redemptions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_plan_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_region_id"); - - b.HasIndex("TenantId", "OrderId", "UserId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_order_id_user_id") - .HasFilter("order_id is not null"); - - b.HasIndex("TenantId", "UserId", "CouponId") - .IsUnique() - .HasDatabaseName("ix_coupon_redemptions_tenant_id_user_id_coupon_id") - .HasFilter("coupon_id is not null"); - - b.ToTable("coupon_redemptions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Entitlement", 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("EntitlementType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("entitlement_type"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("LegacySourceId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_source_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RevokedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("revoked_at"); - - b.Property("RevokedBy") - .HasColumnType("uuid") - .HasColumnName("revoked_by"); - - b.Property("RevokedReason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("revoked_reason"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("StartsAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at") - .HasDefaultValueSql("now()"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_entitlements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_entitlements_tenant_id_id"); - - b.HasIndex("RevokedBy") - .HasDatabaseName("ix_entitlements_revoked_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_entitlements_user_id"); - - b.HasIndex("TenantId", "UserId", "Status", "ExpiresAt") - .HasDatabaseName("ix_entitlements_tenant_id_user_id_status_expires_at"); - - b.ToTable("entitlements", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPlanId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_plan_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("OrderNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("order_no"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PayMethod") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("pay_method"); - - b.Property("PayProvider") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("pay_provider"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("ProductName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("product_name"); - - b.Property("ProductType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("product_type"); - - b.Property("RawPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RefundedAmountCents") - .HasColumnType("integer") - .HasColumnName("refunded_amount_cents"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("trade_no"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_orders"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_orders_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_orders_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_orders_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderNo") - .IsUnique() - .HasDatabaseName("ix_orders_tenant_id_order_no"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_orders_tenant_id_plan_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_orders_tenant_id_region_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_orders_tenant_id_user_id_created_at"); - - b.ToTable("orders", null, t => - { - t.HasCheckConstraint("ck_orders_amount", "amount_cents >= 0"); - - t.HasCheckConstraint("ck_orders_refunded_amount", "refunded_amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.OrderItem", 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("ItemId") - .HasColumnType("uuid") - .HasColumnName("item_id"); - - b.Property("ItemType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("item_type"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("Quantity") - .HasColumnType("integer") - .HasColumnName("quantity"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalAmountCents") - .HasColumnType("integer") - .HasColumnName("total_amount_cents"); - - b.Property("UnitAmountCents") - .HasColumnType("integer") - .HasColumnName("unit_amount_cents"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_order_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_order_items_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_order_items_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderId") - .HasDatabaseName("ix_order_items_tenant_id_order_id"); - - b.ToTable("order_items", null, t => - { - t.HasCheckConstraint("ck_order_items_amounts", "unit_amount_cents >= 0 and total_amount_cents >= 0"); - - t.HasCheckConstraint("ck_order_items_quantity", "quantity > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Payment", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - 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("LegacyOrderId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_order_id"); - - b.Property("Method") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("method"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderTradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_trade_no"); - - b.Property("RawPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RefundedAmountCents") - .HasColumnType("integer") - .HasColumnName("refunded_amount_cents"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_payments"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_payments_tenant_id_id"); - - b.HasIndex("Provider", "ProviderTradeNo") - .IsUnique() - .HasDatabaseName("ix_payments_provider_provider_trade_no") - .HasFilter("provider_trade_no is not null"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_payments_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderId", "UpdatedAt") - .HasDatabaseName("ix_payments_tenant_id_order_id_updated_at"); - - b.ToTable("payments", null, t => - { - t.HasCheckConstraint("ck_payments_amount", "amount_cents >= 0"); - - t.HasCheckConstraint("ck_payments_refunded_amount", "refunded_amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.PaymentEvent", 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("Error") - .HasColumnType("text") - .HasColumnName("error"); - - b.Property("EventId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("event_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("Payload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("ProcessedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("processed_at"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("SignatureValid") - .HasColumnType("boolean") - .HasColumnName("signature_valid"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_payment_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_payment_events_tenant_id_id"); - - b.HasIndex("Provider", "EventId") - .IsUnique() - .HasDatabaseName("ix_payment_events_provider_event_id"); - - b.HasIndex("TenantId", "PaymentId") - .HasDatabaseName("ix_payment_events_tenant_id_payment_id"); - - b.ToTable("payment_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Product", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Cover") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cover"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DetailImages") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("detail_images") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPriceText") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("legacy_price_text"); - - b.Property("Link") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("link"); - - b.Property("PreviewIframe") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("preview_iframe"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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_products"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_products_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_products_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "Type", "SortOrder") - .HasDatabaseName("ix_products_tenant_id_region_id_type_sort_order"); - - b.ToTable("products", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.SvipPlan", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Badge") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("badge"); - - b.Property("CouponOnly") - .HasColumnType("boolean") - .HasColumnName("coupon_only"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - 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(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OriginalPriceCents") - .HasColumnType("integer") - .HasColumnName("original_price_cents"); - - b.Property("PerDayLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("per_day_label"); - - b.Property("PriceCents") - .HasColumnType("integer") - .HasColumnName("price_cents"); - - b.Property("Recommended") - .HasColumnType("boolean") - .HasColumnName("recommended"); - - 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("VpEnabled") - .HasColumnType("boolean") - .HasColumnName("vp_enabled"); - - b.Property("VpProductId") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("vp_product_id"); - - b.HasKey("Id") - .HasName("pk_svip_plans"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_svip_plans_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_svip_plans_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_svip_plans_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("svip_plans", null, t => - { - t.HasCheckConstraint("ck_svip_plans_days", "days >= 0"); - - t.HasCheckConstraint("ck_svip_plans_price", "price_cents >= 0 and (original_price_cents is null or original_price_cents >= 0)"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantPaymentAccount", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ConfigPublic") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("config_public") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_payment_accounts"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_payment_accounts_tenant_id_id"); - - b.HasIndex("TenantId", "Provider") - .IsUnique() - .HasDatabaseName("ix_tenant_payment_accounts_tenant_id_provider"); - - b.ToTable("tenant_payment_accounts", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantSubscription", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("BillingCycle") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("billing_cycle"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PlanCode") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("plan_code"); - - b.Property("StartsAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_subscriptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_subscriptions_tenant_id_id"); - - b.HasIndex("TenantId", "Status", "ExpiresAt") - .HasDatabaseName("ix_tenant_subscriptions_tenant_id_status_expires_at"); - - b.ToTable("tenant_subscriptions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantUsageRecord", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("MetricKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("metric_key"); - - b.Property("MetricValue") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)") - .HasColumnName("metric_value"); - - b.Property("PeriodEnd") - .HasColumnType("date") - .HasColumnName("period_end"); - - b.Property("PeriodStart") - .HasColumnType("date") - .HasColumnName("period_start"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_tenant_usage_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_usage_records_tenant_id_id"); - - b.HasIndex("TenantId", "MetricKey", "PeriodStart", "PeriodEnd") - .HasDatabaseName("ix_tenant_usage_records_tenant_id_metric_key_period_start_peri~"); - - b.ToTable("tenant_usage_records", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.AiRecommendationReport", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ContextPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("context_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ErrorMessage") - .HasColumnType("text") - .HasColumnName("error_message"); - - b.Property("GeneratedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("generated_at"); - - b.Property("InputPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("input_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Model") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("model"); - - b.Property("PromptVersion") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("prompt_version"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("ResultPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("result_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_ai_recommendation_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_ai_recommendation_reports_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_ai_recommendation_reports_user_id"); - - b.HasIndex("TenantId", "RegionId", "CreatedAt") - .HasDatabaseName("ix_ai_recommendation_reports_tenant_id_region_id_created_at"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_ai_recommendation_reports_tenant_id_user_id_created_at"); - - b.ToTable("ai_recommendation_reports", (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("SecurityScanProvider") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("security_scan_provider"); - - b.Property("SecurityScanStatus") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasDefaultValue("not_required") - .HasColumnName("security_scan_status"); - - b.Property("SecurityScanSummary") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("security_scan_summary") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SecurityScannedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("security_scanned_at"); - - 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", "SecurityScanStatus", "UploadStatus", "Status", "UpdatedAt") - .HasDatabaseName("ix_content_assets_tenant_id_security_scan_status_upload_status~"); - - 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.ContentAssetAccessEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("access_type"); - - b.Property("ActorRole") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("actor_role"); - - b.Property("AssetId") - .HasColumnType("uuid") - .HasColumnName("asset_id"); - - b.Property("AssetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("asset_type"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DenyCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("deny_code"); - - b.Property("Disposition") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("disposition"); - - b.Property("ExpiresInSeconds") - .HasColumnType("integer") - .HasColumnName("expires_in_seconds"); - - b.Property("IpAddress") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Result") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("result"); - - b.Property("SignatureMode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("signature_mode"); - - b.Property("StorageProvider") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("storage_provider"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("Visibility") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("visibility"); - - b.HasKey("Id") - .HasName("pk_content_asset_access_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_content_asset_access_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_content_asset_access_events_user_id"); - - b.HasIndex("TenantId", "AssetId", "CreatedAt") - .HasDatabaseName("ix_content_asset_access_events_tenant_id_asset_id_created_at"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_content_asset_access_events_tenant_id_user_id_created_at") - .HasFilter("user_id is not null"); - - b.HasIndex("TenantId", "AccessType", "Result", "CreatedAt") - .HasDatabaseName("ix_content_asset_access_events_tenant_id_access_type_result_cr~"); - - b.ToTable("content_asset_access_events", null, t => - { - t.HasCheckConstraint("ck_content_asset_access_events_expiry", "expires_in_seconds is null or expires_in_seconds > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAssetSecurityScanEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssetId") - .HasColumnType("uuid") - .HasColumnName("asset_id"); - - 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.PrimitiveCollection("IssueCodes") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("text[]") - .HasColumnName("issue_codes") - .HasDefaultValueSql("'{}'::text[]"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("RiskLevel") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("risk_level"); - - b.Property("ScanStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scan_status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_content_asset_security_scan_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_content_asset_security_scan_events_tenant_id_id"); - - b.HasIndex("TenantId", "AssetId", "CreatedAt") - .HasDatabaseName("ix_content_asset_security_scan_events_tenant_id_asset_id_creat~"); - - b.HasIndex("TenantId", "ScanStatus", "RiskLevel", "CreatedAt") - .HasDatabaseName("ix_content_asset_security_scan_events_tenant_id_scan_status_ri~"); - - b.ToTable("content_asset_security_scan_events", (string)null); - }); - - 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_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_handbook_chapters"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_chapters_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_chapters_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_subject_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_chapters_tenant_id_entry_id_content_node_id_subjec~"); - - b.ToTable("handbook_chapters", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ChapterId") - .HasColumnType("uuid") - .HasColumnName("chapter_id"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Summary") - .HasColumnType("text") - .HasColumnName("summary"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_handbook_entries"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_entries_tenant_id_id"); - - b.HasIndex("TenantId", "ChapterId") - .HasDatabaseName("ix_handbook_entries_tenant_id_chapter_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_entries_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_entries_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "ChapterId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_entries_tenant_id_entry_id_content_node_id_chapter~"); - - b.ToTable("handbook_entries", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", 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("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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - 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_handbook_subjects"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_subjects_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_subjects_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "MajorId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_major_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_school_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_subjects_tenant_id_entry_id_content_node_id_region~"); - - b.ToTable("handbook_subjects", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("CdnUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cdn_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FileName") - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("file_name"); - - 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("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.HasKey("Id") - .HasName("pk_images"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_images_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_images_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "Category", "IsPublic") - .HasDatabaseName("ix_images_tenant_id_category_is_public"); - - b.ToTable("images", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", 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("AssemblyType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assembly_type"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_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("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PassScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("pass_score"); - - b.Property("QuestionLimit") - .HasColumnType("integer") - .HasColumnName("question_limit"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Rules") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("rules") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Sections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sections") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_practice_blueprints"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_blueprints_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_practice_blueprints_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_practice_blueprints_updated_by"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_collection_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_practice_blueprints_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_region_id"); - - b.HasIndex("TenantId", "NodeId", "CollectionId", "Mode", "Status", "SortOrder") - .HasDatabaseName("ix_practice_blueprints_tenant_id_node_id_collection_id_mode_st~"); - - b.ToTable("practice_blueprints", null, t => - { - t.HasCheckConstraint("ck_practice_blueprints_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_practice_blueprints_question_limit", "question_limit is null or question_limit > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionBankGrant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.PrimitiveCollection("AllowedPlanCodes") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("text[]") - .HasColumnName("allowed_plan_codes") - .HasDefaultValueSql("'{}'::text[]"); - - b.PrimitiveCollection("AllowedRegionIds") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("uuid[]") - .HasColumnName("allowed_region_ids") - .HasDefaultValueSql("'{}'::uuid[]"); - - b.PrimitiveCollection("AllowedSubjectIds") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("uuid[]") - .HasColumnName("allowed_subject_ids") - .HasDefaultValueSql("'{}'::uuid[]"); - - b.PrimitiveCollection("AllowedTenantIds") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("uuid[]") - .HasColumnName("allowed_tenant_ids") - .HasDefaultValueSql("'{}'::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("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("GrantScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("grant_scope"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SourceQuestionBankId") - .HasColumnType("uuid") - .HasColumnName("source_question_bank_id"); - - b.Property("StartsAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_bank_grants"); - - b.HasIndex("AllowedPlanCodes") - .HasDatabaseName("ix_question_bank_grants_allowed_plan_codes"); - - NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("AllowedPlanCodes"), "gin"); - - b.HasIndex("AllowedTenantIds") - .HasDatabaseName("ix_question_bank_grants_allowed_tenant_ids"); - - NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("AllowedTenantIds"), "gin"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_bank_grants_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_question_bank_grants_updated_by"); - - b.HasIndex("SourceQuestionBankId", "Status", "StartsAt", "ExpiresAt") - .HasDatabaseName("ix_question_bank_grants_source_question_bank_id_status_starts_~"); - - b.ToTable("question_bank_grants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", 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("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - b.Property("CollectionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("collection_type"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Filters") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("filters") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_question_collections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collections_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_collections_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_question_collections_updated_by"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_question_collections_tenant_id_category_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_question_collections_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_collections_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_question_collections_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_collections_tenant_id_region_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_question_collections_tenant_id_subject_id"); - - b.HasIndex("TenantId", "NodeId", "Status", "SortOrder") - .HasDatabaseName("ix_question_collections_tenant_id_node_id_status_sort_order"); - - b.ToTable("question_collections", null, t => - { - t.HasCheckConstraint("ck_question_collections_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_question_collections_question_count", "question_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Required") - .HasColumnType("boolean") - .HasColumnName("required"); - - b.Property("Score") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - 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_question_collection_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collection_items_tenant_id_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_question_collection_items_tenant_id_question_id"); - - b.HasIndex("TenantId", "CollectionId", "QuestionId") - .IsUnique() - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_question_~"); - - b.HasIndex("TenantId", "CollectionId", "SectionKey", "SortOrder") - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_section_k~"); - - b.ToTable("question_collection_items", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", 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("DisplayName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Types") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("types") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_question_type_groups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_type_groups_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_type_groups_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_question_type_groups_tenant_id_subject_id_is_active_sort_or~"); - - b.ToTable("question_type_groups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", 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("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("LegacyVideoId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_video_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_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("VideoId") - .HasColumnType("uuid") - .HasColumnName("video_id"); - - b.Property("VideoType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("video_type"); - - b.HasKey("Id") - .HasName("pk_question_videos"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_videos_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "VideoId") - .HasDatabaseName("ix_question_videos_tenant_id_video_id"); - - b.HasIndex("TenantId", "QuestionId", "VideoId", "VideoType") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_question_id_video_id_video_type"); - - b.ToTable("question_videos", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("SourceSubjectId") - .HasColumnType("uuid") - .HasColumnName("source_subject_id"); - - b.Property("TargetSubjectId") - .HasColumnType("uuid") - .HasColumnName("target_subject_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Id") - .HasColumnType("uuid") - .HasColumnName("id"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacySourceSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_source_subject_id"); - - b.Property("LegacyTargetSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_target_subject_id"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at"); - - b.HasKey("TenantId", "SourceSubjectId", "TargetSubjectId") - .HasName("pk_subject_shares"); - - b.HasIndex("TenantId", "TargetSubjectId") - .HasDatabaseName("ix_subject_shares_tenant_id_target_subject_id"); - - b.ToTable("subject_shares", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.TenantQuestionBankAdoption", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AdoptionMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("adoption_mode"); - - b.Property("CopiedQuestionCount") - .HasColumnType("integer") - .HasColumnName("copied_question_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("GrantId") - .HasColumnType("uuid") - .HasColumnName("grant_id"); - - b.Property("LastSyncedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_synced_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SourceQuestionBankId") - .HasColumnType("uuid") - .HasColumnName("source_question_bank_id"); - - b.Property("SourceSnapshot") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("source_snapshot") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SyncStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("sync_status"); - - b.Property("TargetCollectionId") - .HasColumnType("uuid") - .HasColumnName("target_collection_id"); - - b.Property("TargetEntryId") - .HasColumnType("uuid") - .HasColumnName("target_entry_id"); - - b.Property("TargetQuestionBankId") - .HasColumnType("uuid") - .HasColumnName("target_question_bank_id"); - - 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_tenant_question_bank_adoptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_question_bank_adoptions_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_question_bank_adoptions_created_by"); - - b.HasIndex("GrantId") - .HasDatabaseName("ix_tenant_question_bank_adoptions_grant_id"); - - b.HasIndex("SourceQuestionBankId") - .HasDatabaseName("ix_tenant_question_bank_adoptions_source_question_bank_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_question_bank_adoptions_updated_by"); - - b.HasIndex("TenantId", "SourceQuestionBankId") - .IsUnique() - .HasDatabaseName("ix_tenant_question_bank_adoptions_tenant_id_source_question_ba~"); - - b.HasIndex("TenantId", "TargetCollectionId") - .HasDatabaseName("ix_tenant_question_bank_adoptions_tenant_id_target_collection_~"); - - b.HasIndex("TenantId", "TargetEntryId") - .HasDatabaseName("ix_tenant_question_bank_adoptions_tenant_id_target_entry_id"); - - b.HasIndex("TenantId", "TargetQuestionBankId") - .HasDatabaseName("ix_tenant_question_bank_adoptions_tenant_id_target_question_ba~"); - - b.HasIndex("TenantId", "Status", "UpdatedAt") - .HasDatabaseName("ix_tenant_question_bank_adoptions_tenant_id_status_updated_at"); - - b.ToTable("tenant_question_bank_adoptions", null, t => - { - t.HasCheckConstraint("ck_tenant_question_bank_adoptions_copied_count", "copied_question_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", 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("FavoritedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("favorited_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Note") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.HasKey("Id") - .HasName("pk_user_word_favorites"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_favorites_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_favorites_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_favorites_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_favorites_tenant_id_user_id_word_id"); - - b.ToTable("user_word_favorites", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CorrectStreak") - .HasColumnType("integer") - .HasColumnName("correct_streak"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DueLevel") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("due_level"); - - b.Property("EaseFactor") - .ValueGeneratedOnAdd() - .HasPrecision(4, 2) - .HasColumnType("numeric(4,2)") - .HasDefaultValue(2.50m) - .HasColumnName("ease_factor"); - - b.Property("LastResult") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("last_result"); - - b.Property("LastReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_review_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NextReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_review_at"); - - b.Property("ReviewCount") - .HasColumnType("integer") - .HasColumnName("review_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_user_word_progress"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_progress_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_progress_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_progress_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_word_id"); - - b.HasIndex("TenantId", "UserId", "NextReviewAt", "Status", "DueLevel") - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_next_review_at_status_~"); - - b.ToTable("user_word_progress", null, t => - { - t.HasCheckConstraint("ck_user_word_progress_correct_streak", "correct_streak >= 0"); - - t.HasCheckConstraint("ck_user_word_progress_ease_factor", "ease_factor >= 1.30 and ease_factor <= 3.00"); - - t.HasCheckConstraint("ck_user_word_progress_review_count", "review_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("IsGeneral") - .HasColumnType("boolean") - .HasColumnName("is_general"); - - b.Property("KnowledgeTags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("knowledge_tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ThumbnailUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("thumbnail_url"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VideoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("video_url"); - - b.HasKey("Id") - .HasName("pk_video_explanations"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_video_explanations_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_video_explanations_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SourceHash") - .HasDatabaseName("ix_video_explanations_tenant_id_source_hash") - .HasFilter("source_hash is not null"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_video_explanations_tenant_id_subject_id_is_active_sort_order"); - - b.ToTable("video_explanations", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WordCount") - .HasColumnType("integer") - .HasColumnName("word_count"); - - b.HasKey("Id") - .HasName("pk_vocabulary_units"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_units_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_units_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_region_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_units_tenant_id_entry_id_content_node_id_region_~"); - - b.ToTable("vocabulary_units", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Example") - .HasColumnType("text") - .HasColumnName("example"); - - b.Property("ExampleTranslation") - .HasColumnType("text") - .HasColumnName("example_translation"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Meaning") - .HasColumnType("text") - .HasColumnName("meaning"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phonetic") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("phonetic"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitId") - .HasColumnType("uuid") - .HasColumnName("unit_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Word") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("word"); - - b.HasKey("Id") - .HasName("pk_vocabulary_words"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_words_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_words_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_words_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UnitId", "IsActive", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_vocabulary_words_tenant_id_unit_id_is_active_sort_order_cre~"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "UnitId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_words_tenant_id_entry_id_content_node_id_unit_id~"); - - b.ToTable("vocabulary_words", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlement", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CommissionAmountCents") - .HasColumnType("integer") - .HasColumnName("commission_amount_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DefaultRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("default_rate"); - - b.Property("EffectiveRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("effective_rate"); - - b.Property("GeneratedBy") - .HasColumnType("uuid") - .HasColumnName("generated_by"); - - b.Property("GrossAmountCents") - .HasColumnType("integer") - .HasColumnName("gross_amount_cents"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PaidBy") - .HasColumnType("uuid") - .HasColumnName("paid_by"); - - b.Property("PaidUserCount") - .HasColumnType("integer") - .HasColumnName("paid_user_count"); - - b.Property("PaymentAccount") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("payment_account"); - - b.Property("PaymentMethod") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("payment_method"); - - b.Property("PeriodEnd") - .HasColumnType("date") - .HasColumnName("period_end"); - - b.Property("PeriodStart") - .HasColumnType("date") - .HasColumnName("period_start"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("ReviewedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("reviewed_at"); - - b.Property("ReviewedBy") - .HasColumnType("uuid") - .HasColumnName("reviewed_by"); - - b.Property("SettlementNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("settlement_no"); - - b.Property("SourceCount") - .HasColumnType("integer") - .HasColumnName("source_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_commission_settlements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commission_settlements_tenant_id_id"); - - b.HasIndex("GeneratedBy") - .HasDatabaseName("ix_commission_settlements_generated_by"); - - b.HasIndex("PaidBy") - .HasDatabaseName("ix_commission_settlements_paid_by"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_commission_settlements_referrer_user_id"); - - b.HasIndex("ReviewedBy") - .HasDatabaseName("ix_commission_settlements_reviewed_by"); - - b.HasIndex("TenantId", "SettlementNo") - .IsUnique() - .HasDatabaseName("ix_commission_settlements_tenant_id_settlement_no"); - - b.HasIndex("TenantId", "ReferrerUserId", "PeriodStart") - .HasDatabaseName("ix_commission_settlements_referrer_start"); - - b.HasIndex("TenantId", "ReferrerUserId", "PeriodStart", "PeriodEnd") - .IsUnique() - .HasDatabaseName("ux_commission_settlements_referrer_period"); - - b.ToTable("commission_settlements", null, t => - { - t.HasCheckConstraint("ck_commission_settlements_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commission_settlements_counts", "source_count >= 0 and paid_user_count >= 0"); - - t.HasCheckConstraint("ck_commission_settlements_period", "period_end >= period_start"); - - t.HasCheckConstraint("ck_commission_settlements_rates", "default_rate >= 0 and default_rate <= 1 and (effective_rate is null or (effective_rate >= 0 and effective_rate <= 1))"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlementItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AttributionType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("attribution_type"); - - b.Property("CommissionAmountCents") - .HasColumnType("integer") - .HasColumnName("commission_amount_cents"); - - b.Property("CommissionRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("commission_rate"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("GrossAmountCents") - .HasColumnType("integer") - .HasColumnName("gross_amount_cents"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RateSource") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("rate_source"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("SettlementId") - .HasColumnType("uuid") - .HasColumnName("settlement_id"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_no"); - - b.Property("SourcePaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("source_paid_at"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_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_commission_settlement_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commission_settlement_items_tenant_id_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_commission_settlement_items_referrer_user_id"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_commission_settlement_items_student_user_id"); - - b.HasIndex("TenantId", "SettlementId") - .HasDatabaseName("ix_commission_settlement_items_tenant_id_settlement_id"); - - b.HasIndex("TenantId", "ReferrerUserId", "SourcePaidAt") - .HasDatabaseName("ix_commission_settlement_items_tenant_id_referrer_user_id_sour~"); - - b.HasIndex("TenantId", "SourceType", "SourceId") - .IsUnique() - .HasDatabaseName("ix_commission_settlement_items_tenant_id_source_type_source_id"); - - b.ToTable("commission_settlement_items", null, t => - { - t.HasCheckConstraint("ck_commission_settlement_items_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commission_settlement_items_rate", "commission_rate >= 0 and commission_rate <= 1"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignmentConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("assignment_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("AssignmentCursor") - .HasColumnType("integer") - .HasColumnName("assignment_cursor"); - - b.Property("AssignmentMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assignment_mode"); - - b.Property("AssignmentPool") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("assignment_pool") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DelaySeconds") - .HasColumnType("integer") - .HasColumnName("delay_seconds"); - - b.Property("Enabled") - .HasColumnType("boolean") - .HasColumnName("enabled"); - - b.Property("ExamType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("exam_type"); - - b.Property("FormName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("form_name"); - - b.Property("SecretRef") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("secret_ref"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TimeoutSeconds") - .HasColumnType("integer") - .HasColumnName("timeout_seconds"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Url") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("url"); - - b.HasKey("Id") - .HasName("pk_crm_config"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_config_tenant_id_id"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_crm_config_tenant_id"); - - b.HasIndex("TenantId", "AssignmentMode") - .HasDatabaseName("ix_crm_config_tenant_id_assignment_mode"); - - b.ToTable("crm_config", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempt") - .HasColumnType("integer") - .HasColumnName("attempt"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ErrorMessage") - .HasColumnType("text") - .HasColumnName("error_message"); - - b.Property("HttpCode") - .HasColumnType("integer") - .HasColumnName("http_code"); - - b.Property("LeadId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Outcome") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("outcome"); - - b.Property("RecordId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("record_id"); - - b.Property("RequestBody") - .HasColumnType("text") - .HasColumnName("request_body"); - - b.Property("RequestPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("request_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ResponseSummary") - .HasMaxLength(2000) - .HasColumnType("character varying(2000)") - .HasColumnName("response_summary"); - - b.Property("SignedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("signed_at"); - - 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_crm_webhook_log"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_webhook_log_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_log_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RecordId", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_log_tenant_id_record_id_created_at"); - - b.ToTable("crm_webhook_log", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookQueueItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempts") - .HasColumnType("integer") - .HasColumnName("attempts"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IdempotencyKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("idempotency_key"); - - b.Property("LastAttemptAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_attempt_at"); - - b.Property("LastError") - .HasColumnType("text") - .HasColumnName("last_error"); - - b.Property("LastHttpCode") - .HasColumnType("integer") - .HasColumnName("last_http_code"); - - b.Property("LastResponseSummary") - .HasColumnType("text") - .HasColumnName("last_response_summary"); - - b.Property("LeadId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("NextAttemptAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_attempt_at"); - - b.Property("Payload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("RecordId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("record_id"); - - b.Property("ScheduledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("scheduled_at"); - - b.Property("SentAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("sent_at"); - - b.Property("Source") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TargetUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("target_url"); - - 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_crm_webhook_queue"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_webhook_queue_tenant_id_id"); - - b.HasIndex("TenantId", "IdempotencyKey") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_idempotency_key") - .HasFilter("idempotency_key is not null"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RecordId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_record_id") - .HasFilter("record_id is not null"); - - b.HasIndex("TenantId", "RecordId", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_record_id_created_at") - .HasFilter("record_id is not null"); - - b.HasIndex("TenantId", "Source", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_source_created_at") - .HasFilter("source = 'tenant.student.crm_push'"); - - b.HasIndex("TenantId", "Status", "ScheduledAt", "NextAttemptAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_status_scheduled_at_next_attemp~"); - - b.ToTable("crm_webhook_queue", null, t => - { - t.HasCheckConstraint("ck_crm_webhook_queue_attempts", "attempts >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Channel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("channel"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("LandingPath") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("landing_path"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_referral_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_codes_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_referral_codes_user_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_referral_codes_tenant_id_code"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_referral_codes_tenant_id_user_id"); - - b.HasIndex("TenantId", "Code", "Status") - .HasDatabaseName("ix_referral_codes_tenant_id_code_status"); - - b.ToTable("referral_codes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralLead", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("assigned_at"); - - b.Property("AssignedBy") - .HasColumnType("uuid") - .HasColumnName("assigned_by"); - - b.Property("AssignedToUserId") - .HasColumnType("uuid") - .HasColumnName("assigned_to_user_id"); - - b.Property("AssignmentMode") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assignment_mode"); - - b.Property("BindType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("bind_type"); - - b.Property("BoundAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("bound_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FirstTrackId") - .HasColumnType("uuid") - .HasColumnName("first_track_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ProtectedUntil") - .HasColumnType("timestamp with time zone") - .HasColumnName("protected_until"); - - b.Property("RefCode") - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Source") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_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_referral_leads"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_leads_tenant_id_id"); - - b.HasIndex("AssignedBy") - .HasDatabaseName("ix_referral_leads_assigned_by"); - - b.HasIndex("AssignedToUserId") - .HasDatabaseName("ix_referral_leads_assigned_to_user_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_referral_leads_referrer_user_id"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_referral_leads_student_user_id"); - - b.HasIndex("TenantId", "FirstTrackId") - .HasDatabaseName("ix_referral_leads_tenant_id_first_track_id"); - - b.HasIndex("TenantId", "StudentUserId") - .IsUnique() - .HasDatabaseName("ix_referral_leads_tenant_id_student_user_id"); - - b.HasIndex("TenantId", "ReferrerUserId", "BoundAt") - .HasDatabaseName("ix_referral_leads_tenant_id_referrer_user_id_bound_at"); - - b.HasIndex("TenantId", "AssignedToUserId", "Status", "BoundAt") - .HasDatabaseName("ix_referral_leads_tenant_id_assigned_to_user_id_status_bound_at"); - - b.ToTable("referral_leads", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralQrcode", 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("ErrorMessage") - .HasColumnType("text") - .HasColumnName("error_message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Page") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("page"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("QrcodeUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("qrcode_url"); - - b.Property("RefCode") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("Scene") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("scene"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_referral_qrcodes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_qrcodes_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_referral_qrcodes_user_id"); - - b.HasIndex("TenantId", "RefCode", "Status") - .HasDatabaseName("ix_referral_qrcodes_tenant_id_ref_code_status"); - - b.HasIndex("TenantId", "Provider", "Scene", "Page") - .IsUnique() - .HasDatabaseName("ix_referral_qrcodes_tenant_id_provider_scene_page"); - - b.ToTable("referral_qrcodes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTeamEdge", 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("LeaderUserId") - .HasColumnType("uuid") - .HasColumnName("leader_user_id"); - - b.Property("MemberUserId") - .HasColumnType("uuid") - .HasColumnName("member_user_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RelationType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("relation_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_referral_team_edges"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_team_edges_tenant_id_id"); - - b.HasIndex("LeaderUserId") - .HasDatabaseName("ix_referral_team_edges_leader_user_id"); - - b.HasIndex("MemberUserId") - .HasDatabaseName("ix_referral_team_edges_member_user_id"); - - b.HasIndex("TenantId", "LeaderUserId", "Status") - .HasDatabaseName("ix_referral_team_edges_tenant_id_leader_user_id_status"); - - b.HasIndex("TenantId", "MemberUserId", "RelationType") - .IsUnique() - .HasDatabaseName("ix_referral_team_edges_tenant_id_member_user_id_relation_type"); - - b.ToTable("referral_team_edges", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTrack", 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("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("IpAddress") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("ip_address"); - - b.Property("LeadId") - .HasColumnType("uuid") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RefCode") - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Source") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source"); - - b.Property("TargetUserId") - .HasColumnType("uuid") - .HasColumnName("target_user_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserAgent") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_referral_tracks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_tracks_tenant_id_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_referral_tracks_referrer_user_id"); - - b.HasIndex("TargetUserId") - .HasDatabaseName("ix_referral_tracks_target_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_referral_tracks_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "LeadId", "CreatedAt") - .HasDatabaseName("ix_referral_tracks_tenant_id_lead_id_created_at"); - - b.HasIndex("TenantId", "RefCode", "EventType", "CreatedAt") - .HasDatabaseName("ix_referral_tracks_tenant_id_ref_code_event_type_created_at"); - - b.ToTable("referral_tracks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.TenantCommissionSetting", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - 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("DefaultRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("default_rate"); - - b.Property("MinSettlementCents") - .HasColumnType("integer") - .HasColumnName("min_settlement_cents"); - - b.Property("SettlementCycle") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("settlement_cycle"); - - 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_tenant_commission_settings"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_commission_settings_tenant_id_id"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_tenant_commission_settings_tenant_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_commission_settings_updated_by"); - - b.ToTable("tenant_commission_settings", null, t => - { - t.HasCheckConstraint("ck_tenant_commission_settings_default_rate", "default_rate >= 0 and default_rate <= 1"); - - t.HasCheckConstraint("ck_tenant_commission_settings_min_settlement", "min_settlement_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", 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("LastCheckInDate") - .HasColumnType("date") - .HasColumnName("last_check_in_date"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("MasteredWordsCount") - .HasColumnType("integer") - .HasColumnName("mastered_words_count"); - - b.Property("ModuleSelections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_selections") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Progress") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("progress") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionsAnsweredToday") - .HasColumnType("integer") - .HasColumnName("questions_answered_today"); - - b.Property("RecentActivities") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("recent_activities") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SelectedMajorId") - .HasColumnType("uuid") - .HasColumnName("selected_major_id"); - - b.Property("SelectedSchoolId") - .HasColumnType("uuid") - .HasColumnName("selected_school_id"); - - b.Property("Stats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("stats") - .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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_student_profiles"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_student_profiles_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_student_profiles_user_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_student_profiles_tenant_id_region_id"); - - b.HasIndex("TenantId", "SelectedMajorId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_major_id"); - - b.HasIndex("TenantId", "SelectedSchoolId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_school_id"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_student_profiles_tenant_id_user_id"); - - b.ToTable("student_profiles", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AvatarUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("avatar_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("LastSeenAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_seen_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPasswordHash") - .HasMaxLength(512) - .HasColumnType("character varying(512)") - .HasColumnName("legacy_password_hash"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PasswordMigrationRequired") - .HasColumnType("boolean") - .HasColumnName("password_migration_required"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("PrimaryRole") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("primary_role"); - - b.Property("RawProfile") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_profile") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Score") - .HasColumnType("integer") - .HasColumnName("score"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Username") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("username"); - - b.HasKey("Id") - .HasName("pk_users"); - - b.HasIndex("Email") - .IsUnique() - .HasDatabaseName("ix_users_email"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_users_legacy_id"); - - b.HasIndex("Phone") - .IsUnique() - .HasDatabaseName("ix_users_phone"); - - b.HasIndex("Username") - .IsUnique() - .HasDatabaseName("ix_users_username"); - - b.ToTable("users", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", 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("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("OpenId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("open_id"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderSubject") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("provider_subject"); - - b.Property("SecretPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("secret_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UnionId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("union_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_identities"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_identities_user_id"); - - b.HasIndex("Provider", "ProviderSubject") - .IsUnique() - .HasDatabaseName("ix_user_identities_provider_provider_subject"); - - b.ToTable("user_identities", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("AnsweredAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("answered_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IsCorrect") - .HasColumnType("boolean") - .HasColumnName("is_correct"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("QuestionVersionId") - .HasColumnType("uuid") - .HasColumnName("question_version_id"); - - b.Property("SelectedOptions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("selected_options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_answer_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_answer_records_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_answer_records_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_answer_records_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id"); - - b.HasIndex("TenantId", "QuestionId", "QuestionVersionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id_question_version_id"); - - b.HasIndex("TenantId", "UserId", "PracticeSessionId") - .HasDatabaseName("ix_answer_records_tenant_id_user_id_practice_session_id"); - - b.ToTable("answer_records", null, t => - { - t.HasCheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActiveUsers") - .HasColumnType("integer") - .HasColumnName("active_users"); - - 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("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("NewOrders") - .HasColumnType("integer") - .HasColumnName("new_orders"); - - b.Property("NewQuestions") - .HasColumnType("integer") - .HasColumnName("new_questions"); - - b.Property("NewRevenueCents") - .HasColumnType("integer") - .HasColumnName("new_revenue_cents"); - - b.Property("NewUsers") - .HasColumnType("integer") - .HasColumnName("new_users"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_dashboard_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_dashboard_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_stat_date_region_id"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId"), false); - - b.ToTable("dashboard_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", 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("ExamAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("exam_at"); - - b.Property("ExamName") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("exam_name"); - - b.Property("ExamType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("exam_type"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("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_exam_dates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_exam_dates_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_exam_dates_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_exam_dates_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId", "ExamAt") - .HasDatabaseName("ix_exam_dates_tenant_id_school_id_exam_at"); - - b.ToTable("exam_dates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_favorite_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_favorite_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_favorite_questions_tenant_id_question_id"); - - b.ToTable("favorite_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("access_mode"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EntitlementId") - .HasColumnType("uuid") - .HasColumnName("entitlement_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("GrantedCount") - .HasColumnType("integer") - .HasColumnName("granted_count"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("Reason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("reason"); - - b.Property("RequestedCount") - .HasColumnType("integer") - .HasColumnName("requested_count"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_access_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_access_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_access_events_user_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_access_events_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_practice_access_events_tenant_id_user_id_created_at"); - - b.ToTable("practice_access_events", null, t => - { - t.HasCheckConstraint("ck_practice_access_events_consumed_free_quota", "consumed_free_quota >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_granted_count", "granted_count >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_requested_count", "requested_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", 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("FreeLimit") - .HasColumnType("integer") - .HasColumnName("free_limit"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsageDate") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasColumnName("usage_date") - .HasDefaultValueSql("current_date"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_daily_usage"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_daily_usage_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_daily_usage_user_id"); - - b.HasIndex("TenantId", "UserId", "UsageDate") - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date"); - - b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId") - .IsUnique() - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date_scope_typ~"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId"), false); - - b.ToTable("practice_daily_usage", null, t => - { - t.HasCheckConstraint("ck_practice_daily_usage_free_limit", "free_limit >= 0"); - - t.HasCheckConstraint("ck_practice_daily_usage_used_count", "used_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessEntitlementId") - .HasColumnType("uuid") - .HasColumnName("access_entitlement_id"); - - b.Property("AccessMode") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasDefaultValue("free") - .HasColumnName("access_mode"); - - b.Property("AccessSnapshot") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("access_snapshot") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("ContentNodeId") - .HasColumnType("uuid") - .HasColumnName("content_node_id"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("FinishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("finished_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at") - .HasDefaultValueSql("now()"); - - b.Property("TargetId") - .HasColumnType("uuid") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_sessions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "UserId", "Id") - .HasName("ak_practice_sessions_tenant_id_user_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_sessions_user_id"); - - b.HasIndex("TenantId", "BlueprintId") - .HasDatabaseName("ix_practice_sessions_tenant_id_blueprint_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_sessions_tenant_id_collection_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_practice_sessions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_sessions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "UserId", "StartedAt") - .HasDatabaseName("ix_practice_sessions_tenant_id_user_id_started_at"); - - b.ToTable("practice_sessions", null, t => - { - t.HasCheckConstraint("ck_practice_sessions_consumed_free_quota", "consumed_free_quota >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionResults") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_results") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionStats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("section_stats") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at"); - - b.Property("SubmittedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("submitted_at") - .HasDefaultValueSql("now()"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalQuestions") - .HasColumnType("integer") - .HasColumnName("total_questions"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.Property("WrongQuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("wrong_question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.HasKey("Id") - .HasName("pk_practice_session_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_reports_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_session_reports_user_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_session_reports_tenant_id_collection_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .IsUnique() - .HasDatabaseName("ix_practice_session_reports_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "BlueprintId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_blueprint_id_submitted_at") - .HasFilter("blueprint_id is not null"); - - b.HasIndex("TenantId", "UserId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_user_id_submitted_at"); - - b.ToTable("practice_session_reports", null, t => - { - t.HasCheckConstraint("ck_practice_session_reports_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_reports_counts", "total_questions >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_duration", "duration_seconds >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("question_type"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - b.Property("SectionName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("section_name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_practice_session_report_sections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_report_sections_tenant_id_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_practice_session~"); - - b.HasIndex("TenantId", "ReportId", "SectionKey") - .IsUnique() - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sectio~"); - - b.HasIndex("TenantId", "ReportId", "SortOrder") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sort_o~"); - - b.ToTable("practice_session_report_sections", null, t => - { - t.HasCheckConstraint("ck_practice_session_report_sections_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_report_sections_counts", "question_count >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_report_sections_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", 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("LastAccessAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_access_at"); - - b.Property("LastPracticeAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_practice_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("practice_type"); - - b.Property("Progress") - .HasColumnType("integer") - .HasColumnName("progress"); - - b.Property("TargetLegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("target_legacy_id"); - - b.Property("TargetName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("target_name"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_recent_practices"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_recent_practices_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_recent_practices_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_recent_practices_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "LastAccessAt") - .HasDatabaseName("ix_recent_practices_tenant_id_user_id_last_access_at"); - - b.ToTable("recent_practices", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attachments") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("attachments") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("Contact") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("contact"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("HandledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("handled_at"); - - b.Property("HandledBy") - .HasColumnType("uuid") - .HasColumnName("handled_by"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Resolution") - .HasColumnType("text") - .HasColumnName("resolution"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_reports_tenant_id_id"); - - b.HasIndex("HandledBy") - .HasDatabaseName("ix_reports_handled_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_reports_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_reports_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_question_id_created_at") - .HasFilter("question_id is not null"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_status_created_at"); - - b.ToTable("reports", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_report_status_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_report_status_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_report_status_events_actor_user_id"); - - b.HasIndex("TenantId", "ReportId", "CreatedAt") - .HasDatabaseName("ix_report_status_events_tenant_id_report_id_created_at"); - - b.ToTable("report_status_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CodeCount") - .HasColumnType("integer") - .HasColumnName("code_count"); - - b.Property("CodeEstimated") - .HasColumnType("integer") - .HasColumnName("code_estimated"); - - b.Property("CodeUsed") - .HasColumnType("integer") - .HasColumnName("code_used"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EstimatedRevenueCents") - .HasColumnType("integer") - .HasColumnName("estimated_revenue_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("OrderCount") - .HasColumnType("integer") - .HasColumnName("order_count"); - - b.Property("RealRevenueCents") - .HasColumnType("integer") - .HasColumnName("real_revenue_cents"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_revenue_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_revenue_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_stat_date_region_id_sale_type"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType"), false); - - b.ToTable("revenue_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BalanceAfter") - .HasColumnType("integer") - .HasColumnName("balance_after"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("IdempotencyKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("idempotency_key"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Points") - .HasColumnType("integer") - .HasColumnName("points"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_score_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_score_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_score_events_user_id"); - - b.HasIndex("TenantId", "IdempotencyKey") - .IsUnique() - .HasDatabaseName("ix_user_score_events_tenant_id_idempotency_key"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_user_score_events_tenant_id_user_id_created_at"); - - b.ToTable("user_score_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("LastWrongAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("last_wrong_at") - .HasDefaultValueSql("now()"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("WrongCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(1) - .HasColumnName("wrong_count"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_wrong_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_wrong_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_wrong_questions_tenant_id_question_id"); - - b.ToTable("wrong_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Announcement", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BackgroundColor") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("background_color"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("Link") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("link"); - - 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_announcements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_announcements_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_announcements_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "IsActive", "SortOrder") - .HasDatabaseName("ix_announcements_tenant_id_is_active_sort_order"); - - b.ToTable("announcements", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.AuditLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Action") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("action"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - 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("IpAddress") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("ip_address"); - - b.Property("TargetId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_audit_logs"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_audit_logs_actor_user_id"); - - b.HasIndex("TenantId", "CreatedAt") - .HasDatabaseName("ix_audit_logs_tenant_id_created_at"); - - b.HasIndex("TenantId", "TargetType", "TargetId", "CreatedAt") - .HasDatabaseName("ix_audit_logs_tenant_id_target_type_target_id_created_at"); - - b.ToTable("audit_logs", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Badge", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("ConditionExtra") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("condition_extra") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ConditionField") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("condition_field"); - - b.Property("ConditionOperator") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("condition_operator"); - - b.Property("ConditionValue") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)") - .HasColumnName("condition_value"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("IconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("icon_url"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Level") - .HasColumnType("integer") - .HasColumnName("level"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnlockType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("unlock_type"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_badges"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_badges_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_badges_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "Category", "IsActive", "SortOrder") - .HasDatabaseName("ix_badges_tenant_id_category_is_active_sort_order"); - - b.ToTable("badges", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Banner", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BackgroundColor") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("background_color"); - - b.Property("BorderColor") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("border_color"); - - b.Property("ButtonLink") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("button_link"); - - b.Property("ButtonText") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("button_text"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Subtitle") - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("subtitle"); - - 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.HasKey("Id") - .HasName("pk_banners"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_banners_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_banners_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_banners_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("banners", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Faq", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Answer") - .HasColumnType("text") - .HasColumnName("answer"); - - 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("Question") - .HasColumnType("text") - .HasColumnName("question"); - - 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.HasKey("Id") - .HasName("pk_faqs"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_faqs_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_faqs_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_faqs_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("faqs", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantContentNotification", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActionLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("action_label"); - - b.Property("ActionPath") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("action_path"); - - b.Property("AdoptionId") - .HasColumnType("uuid") - .HasColumnName("adoption_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("DedupeKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("dedupe_key"); - - b.Property("Message") - .IsRequired() - .HasColumnType("text") - .HasColumnName("message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NotificationType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("notification_type"); - - b.Property("ReadAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("read_at"); - - b.Property("ReadBy") - .HasColumnType("uuid") - .HasColumnName("read_by"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("Severity") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("severity"); - - b.Property("SourceQuestionBankId") - .HasColumnType("uuid") - .HasColumnName("source_question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenant_content_notifications"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_content_notifications_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_content_notifications_created_by"); - - b.HasIndex("ReadBy") - .HasDatabaseName("ix_tenant_content_notifications_read_by"); - - b.HasIndex("TenantId", "SourceQuestionBankId") - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_source_question_bank~"); - - b.HasIndex("TenantId", "NotificationType", "DedupeKey") - .IsUnique() - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_notification_type_de~") - .HasFilter("dedupe_key is not null"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_status_created_at"); - - b.HasIndex("TenantId", "AdoptionId", "NotificationType", "Status") - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_adoption_id_notifica~"); - - b.ToTable("tenant_content_notifications", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantThemeConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActivePublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("active_public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ActiveTemplateCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("active_template_code"); - - b.Property("ActiveTheme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("active_theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DraftPublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("draft_public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("DraftTemplateCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("draft_template_code"); - - b.Property("DraftTheme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("draft_theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("DraftUpdatedBy") - .HasColumnType("uuid") - .HasColumnName("draft_updated_by"); - - b.Property("PublishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("published_at"); - - b.Property("PublishedBy") - .HasColumnType("uuid") - .HasColumnName("published_by"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_theme_configs"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_theme_configs_tenant_id_id"); - - b.HasIndex("ActiveTemplateCode") - .HasDatabaseName("ix_tenant_theme_configs_active_template_code"); - - b.HasIndex("DraftTemplateCode") - .HasDatabaseName("ix_tenant_theme_configs_draft_template_code"); - - b.HasIndex("DraftUpdatedBy") - .HasDatabaseName("ix_tenant_theme_configs_draft_updated_by"); - - b.HasIndex("PublishedBy") - .HasDatabaseName("ix_tenant_theme_configs_published_by"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_tenant_theme_configs_tenant_id"); - - b.ToTable("tenant_theme_configs", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantThemeTemplate", 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("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PreviewImageUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("preview_image_url"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenant_theme_templates"); - - b.HasAlternateKey("Code") - .HasName("ak_tenant_theme_templates_code"); - - b.HasIndex("Code") - .IsUnique() - .HasDatabaseName("ix_tenant_theme_templates_code"); - - b.HasIndex("Status", "SortOrder", "Code") - .HasDatabaseName("ix_tenant_theme_templates_status_sort_order_code"); - - b.ToTable("tenant_theme_templates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserBadge", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BadgeId") - .HasColumnType("uuid") - .HasColumnName("badge_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("GrantedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("granted_at"); - - b.Property("GrantedBy") - .HasColumnType("uuid") - .HasColumnName("granted_by"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_badges"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_badges_tenant_id_id"); - - b.HasIndex("GrantedBy") - .HasDatabaseName("ix_user_badges_granted_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_badges_user_id"); - - b.HasIndex("TenantId", "BadgeId") - .HasDatabaseName("ix_user_badges_tenant_id_badge_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_user_badges_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "BadgeId") - .IsUnique() - .HasDatabaseName("ix_user_badges_tenant_id_user_id_badge_id"); - - b.ToTable("user_badges", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserNotification", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActionLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("action_label"); - - b.Property("ActionPath") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("action_path"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DedupeKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("dedupe_key"); - - b.Property("Message") - .IsRequired() - .HasColumnType("text") - .HasColumnName("message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NotificationType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("notification_type"); - - b.Property("ReadAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("read_at"); - - b.Property("Severity") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("severity"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_notifications"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_notifications_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_user_notifications_created_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_notifications_user_id"); - - b.HasIndex("TenantId", "SourceType", "SourceId") - .HasDatabaseName("ix_user_notifications_tenant_id_source_type_source_id"); - - b.HasIndex("TenantId", "UserId", "NotificationType", "DedupeKey") - .IsUnique() - .HasDatabaseName("ix_user_notifications_tenant_id_user_id_notification_type_dedu~") - .HasFilter("dedupe_key is not null"); - - b.HasIndex("TenantId", "UserId", "Status", "CreatedAt") - .HasDatabaseName("ix_user_notifications_tenant_id_user_id_status_created_at"); - - b.ToTable("user_notifications", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - 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("CurrentVersionId") - .HasColumnType("uuid") - .HasColumnName("current_version_id"); - - b.Property("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExamMarkers") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("exam_markers") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("HasVideoExplanation") - .HasColumnType("boolean") - .HasColumnName("has_video_explanation"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyNodeId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_node_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("MediaUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("media_url"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PrimaryCollectionId") - .HasColumnType("uuid") - .HasColumnName("primary_collection_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Type") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("type"); - - b.Property("TypeLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("type_label"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_questions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_questions_tenant_id_id"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_questions_tenant_id_category_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_questions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_questions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_questions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "NodeId") - .HasDatabaseName("ix_questions_tenant_id_node_id"); - - b.HasIndex("TenantId", "PrimaryCollectionId") - .HasDatabaseName("ix_questions_tenant_id_primary_collection_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_questions_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_questions_tenant_id_subject_id"); - - b.HasIndex("TenantId", "Id", "CurrentVersionId") - .HasDatabaseName("ix_questions_tenant_id_id_current_version_id"); - - b.ToTable("questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SourceScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_scope"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_banks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_banks_tenant_id_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_banks_tenant_id_region_id"); - - b.ToTable("question_banks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("CodeLang") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("code_lang"); - - b.Property("CodeTemplate") - .HasColumnType("text") - .HasColumnName("code_template"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CorrectOptionIndex") - .HasColumnType("integer") - .HasColumnName("correct_option_index"); - - b.Property("CorrectOptionIndices") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("correct_option_indices") - .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("Explanation") - .HasColumnType("text") - .HasColumnName("explanation"); - - b.Property("Options") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubQuestions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sub_questions") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("VersionNo") - .HasColumnType("integer") - .HasColumnName("version_no"); - - b.HasKey("Id") - .HasName("pk_question_versions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_versions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "QuestionId", "Id") - .HasName("ak_question_versions_tenant_id_question_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_versions_created_by"); - - b.HasIndex("QuestionId", "VersionNo") - .IsUnique() - .HasDatabaseName("ix_question_versions_question_id_version_no"); - - b.ToTable("question_versions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", 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("FailureCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("failure_code"); - - b.Property("Identifier") - .HasMaxLength(320) - .HasColumnType("character varying(320)") - .HasColumnName("identifier"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Result") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("result"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_login_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_login_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_login_events_user_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_auth_login_events_tenant_id_user_id_created_at"); - - b.ToTable("auth_login_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", 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("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("RevokedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("revoked_at"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TokenHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("token_hash"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_sessions_tenant_id_id"); - - b.HasIndex("TokenHash") - .IsUnique() - .HasDatabaseName("ix_auth_sessions_token_hash"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_sessions_user_id"); - - b.HasIndex("TenantId", "UserId", "ExpiresAt") - .HasDatabaseName("ix_auth_sessions_tenant_id_user_id_expires_at") - .HasFilter("revoked_at is null"); - - b.ToTable("auth_sessions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Dimension") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("dimension"); - - b.Property("ScopeHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("scope_hash"); - - b.Property("BucketStart") - .HasColumnType("timestamp with time zone") - .HasColumnName("bucket_start"); - - b.Property("RequestCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0) - .HasColumnName("request_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId", "Dimension", "ScopeHash", "BucketStart") - .HasName("pk_sms_send_rate_limits"); - - b.HasIndex("UpdatedAt") - .HasDatabaseName("ix_sms_send_rate_limits_updated_at"); - - b.ToTable("sms_send_rate_limits", null, t => - { - t.HasCheckConstraint("ck_sms_send_rate_limits_request_count", "request_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempts") - .HasColumnType("integer") - .HasColumnName("attempts"); - - b.Property("CodeHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("code_hash"); - - b.Property("ConsumedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("consumed_at"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phone") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Purpose") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("purpose"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_sms_verification_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_sms_verification_codes_tenant_id_id"); - - b.HasIndex("TenantId", "Phone", "Purpose") - .IsUnique() - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "CreatedAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_created_at") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "ExpiresAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_expires_at"); - - b.ToTable("sms_verification_codes", null, t => - { - t.HasCheckConstraint("ck_sms_verification_codes_attempts", "attempts >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BillingStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("billing_status"); - - 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("LegalName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("legal_name"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OwnerUserId") - .HasColumnType("uuid") - .HasColumnName("owner_user_id"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("slug"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenants"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenants_legacy_id"); - - b.HasIndex("OwnerUserId") - .HasDatabaseName("ix_tenants_owner_user_id"); - - b.HasIndex("Slug") - .IsUnique() - .HasDatabaseName("ix_tenants_slug"); - - b.ToTable("tenants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ConfigPublic") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("config_public") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_auth_providers"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_auth_providers_tenant_id_id"); - - b.HasIndex("TenantId", "Provider") - .IsUnique() - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider"); - - b.HasIndex("TenantId", "Provider", "Status") - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider_status"); - - b.ToTable("tenant_auth_providers", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("BrandName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("brand_name"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FaviconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("favicon_url"); - - b.Property("LogoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("logo_url"); - - b.Property("OrganizationName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("organization_name"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ServiceAccountName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("service_account_name"); - - b.Property("ServiceWechat") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("service_wechat"); - - b.Property("ShortName") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("short_name"); - - b.Property("Slogan") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("slogan"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_branding"); - - b.ToTable("tenant_branding", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Code") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("code"); - - 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("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_classes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_classes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_classes_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_classes_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_code") - .HasFilter("code is not null and code <> ''"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_tenant_classes_tenant_id_region_id") - .HasFilter("region_id is not null"); - - b.HasIndex("TenantId", "Status", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_tenant_classes_tenant_id_status_sort_order_created_at"); - - b.ToTable("tenant_classes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_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("JoinedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("joined_at") - .HasDefaultValueSql("now()"); - - b.Property("LeftAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("left_at"); - - b.Property("MemberType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("member_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_class_members"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_class_members_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_class_members_user_id"); - - b.HasIndex("TenantId", "ClassId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_status_member_type"); - - b.HasIndex("TenantId", "ClassId", "UserId", "MemberType") - .IsUnique() - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_user_id_member_type"); - - b.HasIndex("TenantId", "UserId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_user_id_status_member_type"); - - b.ToTable("tenant_class_members", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", 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("DomainType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("domain_type"); - - b.Property("Host") - .IsRequired() - .HasMaxLength(253) - .HasColumnType("citext") - .HasColumnName("host"); - - b.Property("IsPrimary") - .HasColumnType("boolean") - .HasColumnName("is_primary"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VerificationToken") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("verification_token"); - - b.Property("VerifiedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("verified_at"); - - b.HasKey("Id") - .HasName("pk_tenant_domains"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_domains_tenant_id_id"); - - b.HasIndex("Host") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_host"); - - b.HasIndex("TenantId", "IsPrimary") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_tenant_id_is_primary") - .HasFilter("is_primary"); - - b.ToTable("tenant_domains", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", 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("LegacyRole") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("legacy_role"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Role") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("role"); - - b.Property("RoleTemplateId") - .HasColumnType("uuid") - .HasColumnName("role_template_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_memberships"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_memberships_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_memberships_user_id"); - - b.HasIndex("TenantId", "RoleTemplateId") - .HasDatabaseName("ix_tenant_memberships_tenant_id_role_template_id"); - - b.HasIndex("TenantId", "UserId", "Role") - .IsUnique() - .HasDatabaseName("ix_tenant_memberships_tenant_id_user_id_role"); - - b.ToTable("tenant_memberships", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BaseRole") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("base_role"); - - 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("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DataScope") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("data_scope") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("FieldPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("field_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("IsSystem") - .HasColumnType("boolean") - .HasColumnName("is_system"); - - b.Property("MenuPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("menu_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ModulePermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_role_templates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_role_templates_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_role_templates_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_role_templates_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_role_templates_tenant_id_code"); - - b.HasIndex("TenantId", "Status", "SortOrder") - .HasDatabaseName("ix_tenant_role_templates_tenant_id_status_sort_order"); - - b.ToTable("tenant_role_templates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("AdminFeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("admin_feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PublicConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_settings"); - - b.ToTable("tenant_settings", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignedToUserId") - .HasColumnType("uuid") - .HasColumnName("assigned_to_user_id"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_id"); - - b.Property("CompletedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("completed_at"); - - b.Property("CompletedBy") - .HasColumnType("uuid") - .HasColumnName("completed_by"); - - 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("DueAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("due_at"); - - b.Property("FollowupType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("followup_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .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.HasKey("Id") - .HasName("pk_tenant_student_followups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_followups_tenant_id_id"); - - b.HasIndex("AssignedToUserId") - .HasDatabaseName("ix_tenant_student_followups_assigned_to_user_id"); - - b.HasIndex("CompletedBy") - .HasDatabaseName("ix_tenant_student_followups_completed_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_followups_student_user_id"); - - b.HasIndex("TenantId", "AssignedToUserId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_assigned_to_user_id_stat~") - .HasFilter("assigned_to_user_id is not null"); - - b.HasIndex("TenantId", "ClassId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_class_id_status_due_at") - .HasFilter("class_id is not null"); - - b.HasIndex("TenantId", "StudentUserId", "Status", "DueAt", "CreatedAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_student_user_id_status_d~"); - - b.ToTable("tenant_student_followups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Content") - .IsRequired() - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("IsPinned") - .HasColumnType("boolean") - .HasColumnName("is_pinned"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NoteType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("note_type"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - 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_tenant_student_notes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_notes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_student_notes_created_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_notes_student_user_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_student_notes_updated_by"); - - b.HasIndex("TenantId", "CreatedBy", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_created_by_created_at") - .HasFilter("created_by is not null"); - - b.HasIndex("TenantId", "StudentUserId", "IsPinned", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_student_user_id_is_pinned_cr~"); - - b.ToTable("tenant_student_notes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Category", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_categories_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Major", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_majors_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.ModuleNode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_module_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_module_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Region", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_regions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.RegionModule", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_region_modules_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_region_modules_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.School", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_schools_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Subject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.ActivationCode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AgentUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_users_agent_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_activation_codes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UsedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_users_used_by"); - - b.HasOne("Tiku.Domain.Commerce.CodeBatch", null) - .WithMany() - .HasForeignKey("TenantId", "BatchId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_code_batches_tenant_id_batch_id"); - - b.HasOne("Tiku.Domain.Commerce.CouponRedemption", null) - .WithMany() - .HasForeignKey("TenantId", "CouponRedemptionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_coupon_redemptions_tenant_id_coupon_redemp~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "UsedRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_regions_tenant_id_used_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CodeBatch", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_code_batches_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationBatch", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_batches_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_batches_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationIssue", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedTo") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_issues_users_assigned_to"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_issues_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ResolvedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_issues_users_resolved_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_issues_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceReconciliationBatch", null) - .WithMany() - .HasForeignKey("TenantId", "BatchId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_commerce_reconciliation_batc~"); - - b.HasOne("Tiku.Domain.Commerce.CommerceReconciliationItem", null) - .WithMany() - .HasForeignKey("TenantId", "ItemId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_commerce_reconciliation_item~"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_payments_tenant_id_payment_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceRefundRequest", null) - .WithMany() - .HasForeignKey("TenantId", "RefundRequestId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_commerce_refund_requests_ten~"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationIssueEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_issue_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_issue_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceReconciliationIssue", null) - .WithMany() - .HasForeignKey("TenantId", "IssueId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_issue_events_commerce_reconciliatio~"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceReconciliationBatch", null) - .WithMany() - .HasForeignKey("TenantId", "BatchId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_items_commerce_reconciliation_batch~"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_items_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_items_payments_tenant_id_payment_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceRefundRequest", null) - .WithMany() - .HasForeignKey("TenantId", "RefundRequestId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_items_commerce_refund_requests_tena~"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceRefundEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_refund_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_refund_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceRefundRequest", null) - .WithMany() - .HasForeignKey("TenantId", "RefundRequestId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_refund_events_commerce_refund_requests_tenant_id_r~"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceRefundRequest", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ProcessedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_refund_requests_users_processed_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("RequestedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_refund_requests_users_requested_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReviewedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_refund_requests_users_reviewed_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_refund_requests_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_refund_requests_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_refund_requests_payments_tenant_id_payment_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Coupon", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_coupons_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_coupons_svip_plans_tenant_id_plan_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CouponRedemption", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_coupon_redemptions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_users_user_id"); - - b.HasOne("Tiku.Domain.Commerce.Coupon", null) - .WithMany() - .HasForeignKey("TenantId", "CouponId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_coupons_tenant_id_coupon_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_svip_plans_tenant_id_plan_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Entitlement", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("RevokedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_entitlements_users_revoked_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_entitlements_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_entitlements_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Order", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_orders_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_orders_users_user_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_orders_svip_plans_tenant_id_plan_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_orders_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.OrderItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_order_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_order_items_orders_tenant_id_order_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Payment", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payments_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payments_orders_tenant_id_order_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.PaymentEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payment_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_payment_events_payments_tenant_id_payment_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Product", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_products_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_products_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.SvipPlan", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_svip_plans_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_svip_plans_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantPaymentAccount", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_payment_accounts_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantSubscription", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_subscriptions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantUsageRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_usage_records_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.AiRecommendationReport", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_ai_recommendation_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_ai_recommendation_reports_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_ai_recommendation_reports_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.AppAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_app_assets_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAsset", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_assets_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_updated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("VerifiedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_verified_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAssetAccessEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_asset_access_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_asset_access_events_users_user_id"); - - b.HasOne("Tiku.Domain.Content.ContentAsset", null) - .WithMany() - .HasForeignKey("TenantId", "AssetId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_asset_access_events_content_assets_tenant_id_asset_~"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAssetSecurityScanEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_asset_security_scan_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentAsset", null) - .WithMany() - .HasForeignKey("TenantId", "AssetId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_asset_security_scan_events_content_assets_tenant_id~"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentEntry", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_entries_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportIssue", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportItem", null) - .WithMany() - .HasForeignKey("TenantId", "ItemId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_import_issues_content_import_items_tenant_id_item_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportJob", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_import_jobs_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_jobs_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "TargetCategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_categories_tenant_id_target_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "TargetContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_content_nodes_tenant_id_target_content_~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "TargetQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_question_banks_tenant_id_target_questio~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "TargetRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_regions_tenant_id_target_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentNode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_nodes_content_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookChapter", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_chapters_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.HandbookSubject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_chapters_handbook_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.HandbookChapter", null) - .WithMany() - .HasForeignKey("TenantId", "ChapterId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_entries_handbook_chapters_tenant_id_chapter_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_images_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_blueprints_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_question_collections_tenant_id_collecti~"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionBankGrant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_bank_grants_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("SourceQuestionBankId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_bank_grants_question_banks_source_question_bank_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_bank_grants_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_question_banks_tenant_id_question_bank~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_question_collections_tenant_id_co~"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_type_groups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_type_groups_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_videos_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.Content.VideoExplanation", null) - .WithMany() - .HasForeignKey("TenantId", "VideoId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_video_explanations_tenant_id_video_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SourceSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_source_subject_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.TenantQuestionBankAdoption", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_question_bank_adoptions_users_created_by"); - - b.HasOne("Tiku.Domain.Content.QuestionBankGrant", null) - .WithMany() - .HasForeignKey("GrantId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_question_bank_adoptions_question_bank_grants_grant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("SourceQuestionBankId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_question_bank_adoptions_question_banks_source_questi~"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_question_bank_adoptions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_question_bank_adoptions_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "TargetCollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_question_bank_adoptions_question_collections_tenant_~"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "TargetEntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_question_bank_adoptions_content_entries_tenant_id_ta~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "TargetQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_question_bank_adoptions_question_banks_tenant_id_tar~"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_video_explanations_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_video_explanations_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_units_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_words_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyUnit", null) - .WithMany() - .HasForeignKey("TenantId", "UnitId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_vocabulary_units_tenant_id_unit_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlement", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("GeneratedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_generated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("PaidBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_paid_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlements_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReviewedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_reviewed_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlements_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlementItem", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlement_items_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlement_items_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlement_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.CommissionSettlement", null) - .WithMany() - .HasForeignKey("TenantId", "SettlementId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlement_items_commission_settlements_tenant_i~"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmConfig", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_config_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookLog", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_webhook_log_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookQueueItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_webhook_queue_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralCode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_codes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_codes_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralLead", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_assigned_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedToUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_assigned_to_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_leads_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_leads_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.ReferralTrack", null) - .WithMany() - .HasForeignKey("TenantId", "FirstTrackId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_referral_tracks_tenant_id_first_track_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralQrcode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_qrcodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_qrcodes_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTeamEdge", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("LeaderUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_team_edges_users_leader_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("MemberUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_team_edges_users_member_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_team_edges_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTrack", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("TargetUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_users_target_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_tracks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.ReferralLead", null) - .WithMany() - .HasForeignKey("TenantId", "LeadId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_referral_leads_tenant_id_lead_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.TenantCommissionSetting", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_commission_settings_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_commission_settings_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedMajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_majors_tenant_id_selected_major_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedSchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_schools_tenant_id_selected_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_identities_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId", "QuestionVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_question_versions_tenant_id_question_id_ques~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "UserId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "UserId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_practice_sessions_tenant_id_user_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_dashboard_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_dashboard_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_exam_dates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_access_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_users_user_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_practice_sessions_tenant_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_question_collections_tenant_id_collection~"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_practice_blueprints_tenant_id_blue~"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_question_collections_tenant_id_col~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_practice_sessions_tenant_id_practi~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_sessions_tenant_i~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSessionReport", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_session_reports_t~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_recent_practices_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_recent_practices_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("HandledBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_handled_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_reports_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_report_status_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.Report", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_reports_tenant_id_report_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_revenue_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_revenue_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Announcement", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_announcements_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.AuditLog", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_audit_logs_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_audit_logs_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Badge", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_badges_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Banner", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_banners_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_banners_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Faq", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_faqs_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_faqs_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantContentNotification", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_content_notifications_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReadBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_content_notifications_users_read_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_content_notifications_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "SourceQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_tenant_content_notifications_question_banks_tenant_id_sourc~"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantThemeConfig", b => - { - b.HasOne("Tiku.Domain.Operations.TenantThemeTemplate", null) - .WithMany() - .HasForeignKey("ActiveTemplateCode") - .HasPrincipalKey("Code") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_tenant_theme_templates_active_template~"); - - b.HasOne("Tiku.Domain.Operations.TenantThemeTemplate", null) - .WithMany() - .HasForeignKey("DraftTemplateCode") - .HasPrincipalKey("Code") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_tenant_theme_templates_draft_template_~"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("DraftUpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_users_draft_updated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("PublishedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_users_published_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_theme_configs_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserBadge", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("GrantedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_user_badges_users_granted_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_badges_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_user_badges_users_user_id"); - - b.HasOne("Tiku.Domain.Operations.Badge", null) - .WithMany() - .HasForeignKey("TenantId", "BadgeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_user_badges_badges_tenant_id_badge_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserNotification", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_user_notifications_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_notifications_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_notifications_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "PrimaryCollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_collections_tenant_id_primary_collection~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_banks_tenant_id_question_bank_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_subjects_tenant_id_subject_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "Id", "CurrentVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_versions_tenant_id_id_current_version_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_banks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_banks_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_versions_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_versions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_login_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_auth_login_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_send_rate_limits_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_verification_codes_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("OwnerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenants_users_owner_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_auth_providers_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantBranding", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_branding_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_classes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_classes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_domains_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantRoleTemplate", null) - .WithMany() - .HasForeignKey("TenantId", "RoleTemplateId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_memberships_tenant_role_templates_tenant_id_role_tem~"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_role_templates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantSettings", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_settings_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedToUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_assigned_to_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CompletedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_completed_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_updated_by"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725215750_AddContentPlatformOperationsPersistence.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725215750_AddContentPlatformOperationsPersistence.cs deleted file mode 100644 index 1985a6a..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725215750_AddContentPlatformOperationsPersistence.cs +++ /dev/null @@ -1,452 +0,0 @@ -using System; -using System.Text.Json; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Tiku.Infrastructure.Persistence.Migrations -{ - /// - public partial class AddContentPlatformOperationsPersistence : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "security_scan_provider", - table: "content_assets", - type: "character varying(100)", - maxLength: 100, - nullable: true); - - migrationBuilder.AddColumn( - name: "security_scan_status", - table: "content_assets", - type: "character varying(32)", - maxLength: 32, - nullable: false, - defaultValue: "not_required"); - - migrationBuilder.AddColumn( - name: "security_scan_summary", - table: "content_assets", - type: "jsonb", - nullable: false, - defaultValueSql: "'{}'::jsonb"); - - migrationBuilder.AddColumn( - name: "security_scanned_at", - table: "content_assets", - type: "timestamp with time zone", - nullable: true); - - migrationBuilder.CreateTable( - name: "ai_recommendation_reports", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - user_id = table.Column(type: "uuid", nullable: false), - region_id = table.Column(type: "uuid", nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - provider = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - model = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - prompt_version = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - input_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - context_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - result_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - error_message = table.Column(type: "text", nullable: true), - generated_at = table.Column(type: "timestamp with time zone", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_ai_recommendation_reports", x => x.id); - table.UniqueConstraint("ak_ai_recommendation_reports_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_ai_recommendation_reports_regions_tenant_id_region_id", - columns: x => new { x.tenant_id, x.region_id }, - principalTable: "regions", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_ai_recommendation_reports_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_ai_recommendation_reports_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "content_asset_access_events", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - asset_id = table.Column(type: "uuid", nullable: true), - user_id = table.Column(type: "uuid", nullable: true), - actor_role = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - access_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - visibility = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - asset_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - storage_provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - disposition = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - expires_in_seconds = table.Column(type: "integer", nullable: true), - signature_mode = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - result = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - deny_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - ip_address = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - user_agent = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_content_asset_access_events", x => x.id); - table.UniqueConstraint("ak_content_asset_access_events_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_content_asset_access_events_expiry", "expires_in_seconds is null or expires_in_seconds > 0"); - table.ForeignKey( - name: "fk_content_asset_access_events_content_assets_tenant_id_asset_~", - columns: x => new { x.tenant_id, x.asset_id }, - principalTable: "content_assets", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_content_asset_access_events_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_content_asset_access_events_users_user_id", - column: x => x.user_id, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "content_asset_security_scan_events", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - asset_id = table.Column(type: "uuid", nullable: true), - provider = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - scan_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - risk_level = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - issue_codes = table.Column(type: "text[]", nullable: false, defaultValueSql: "'{}'::text[]"), - details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_content_asset_security_scan_events", x => x.id); - table.UniqueConstraint("ak_content_asset_security_scan_events_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_content_asset_security_scan_events_content_assets_tenant_id~", - columns: x => new { x.tenant_id, x.asset_id }, - principalTable: "content_assets", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_content_asset_security_scan_events_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "question_bank_grants", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - source_question_bank_id = table.Column(type: "uuid", nullable: false), - created_by = table.Column(type: "uuid", nullable: true), - updated_by = table.Column(type: "uuid", nullable: true), - grant_scope = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - allowed_plan_codes = table.Column(type: "text[]", nullable: false, defaultValueSql: "'{}'::text[]"), - allowed_tenant_ids = table.Column(type: "uuid[]", nullable: false, defaultValueSql: "'{}'::uuid[]"), - allowed_region_ids = table.Column(type: "uuid[]", nullable: false, defaultValueSql: "'{}'::uuid[]"), - allowed_subject_ids = table.Column(type: "uuid[]", nullable: false, defaultValueSql: "'{}'::uuid[]"), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - starts_at = table.Column(type: "timestamp with time zone", nullable: true), - expires_at = table.Column(type: "timestamp with time zone", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_question_bank_grants", x => x.id); - table.ForeignKey( - name: "fk_question_bank_grants_question_banks_source_question_bank_id", - column: x => x.source_question_bank_id, - principalTable: "question_banks", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_question_bank_grants_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_question_bank_grants_users_updated_by", - column: x => x.updated_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "tenant_question_bank_adoptions", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - source_question_bank_id = table.Column(type: "uuid", nullable: false), - grant_id = table.Column(type: "uuid", nullable: true), - target_question_bank_id = table.Column(type: "uuid", nullable: true), - target_entry_id = table.Column(type: "uuid", nullable: true), - target_collection_id = table.Column(type: "uuid", nullable: true), - created_by = table.Column(type: "uuid", nullable: true), - updated_by = table.Column(type: "uuid", nullable: true), - adoption_mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - sync_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - source_snapshot = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - copied_question_count = table.Column(type: "integer", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - last_synced_at = table.Column(type: "timestamp with time zone", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_question_bank_adoptions", x => x.id); - table.UniqueConstraint("ak_tenant_question_bank_adoptions_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_tenant_question_bank_adoptions_copied_count", "copied_question_count >= 0"); - table.ForeignKey( - name: "fk_tenant_question_bank_adoptions_content_entries_tenant_id_ta~", - columns: x => new { x.tenant_id, x.target_entry_id }, - principalTable: "content_entries", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_tenant_question_bank_adoptions_question_bank_grants_grant_id", - column: x => x.grant_id, - principalTable: "question_bank_grants", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_tenant_question_bank_adoptions_question_banks_source_questi~", - column: x => x.source_question_bank_id, - principalTable: "question_banks", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_question_bank_adoptions_question_banks_tenant_id_tar~", - columns: x => new { x.tenant_id, x.target_question_bank_id }, - principalTable: "question_banks", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_tenant_question_bank_adoptions_question_collections_tenant_~", - columns: x => new { x.tenant_id, x.target_collection_id }, - principalTable: "question_collections", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "fk_tenant_question_bank_adoptions_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_question_bank_adoptions_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_tenant_question_bank_adoptions_users_updated_by", - column: x => x.updated_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateIndex( - name: "ix_content_assets_tenant_id_security_scan_status_upload_status~", - table: "content_assets", - columns: new[] { "tenant_id", "security_scan_status", "upload_status", "status", "updated_at" }); - - migrationBuilder.CreateIndex( - name: "ix_ai_recommendation_reports_tenant_id_region_id_created_at", - table: "ai_recommendation_reports", - columns: new[] { "tenant_id", "region_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_ai_recommendation_reports_tenant_id_user_id_created_at", - table: "ai_recommendation_reports", - columns: new[] { "tenant_id", "user_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_ai_recommendation_reports_user_id", - table: "ai_recommendation_reports", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_content_asset_access_events_tenant_id_access_type_result_cr~", - table: "content_asset_access_events", - columns: new[] { "tenant_id", "access_type", "result", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_content_asset_access_events_tenant_id_asset_id_created_at", - table: "content_asset_access_events", - columns: new[] { "tenant_id", "asset_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_content_asset_access_events_tenant_id_user_id_created_at", - table: "content_asset_access_events", - columns: new[] { "tenant_id", "user_id", "created_at" }, - filter: "user_id is not null"); - - migrationBuilder.CreateIndex( - name: "ix_content_asset_access_events_user_id", - table: "content_asset_access_events", - column: "user_id"); - - migrationBuilder.CreateIndex( - name: "ix_content_asset_security_scan_events_tenant_id_asset_id_creat~", - table: "content_asset_security_scan_events", - columns: new[] { "tenant_id", "asset_id", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_content_asset_security_scan_events_tenant_id_scan_status_ri~", - table: "content_asset_security_scan_events", - columns: new[] { "tenant_id", "scan_status", "risk_level", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_question_bank_grants_allowed_plan_codes", - table: "question_bank_grants", - column: "allowed_plan_codes") - .Annotation("Npgsql:IndexMethod", "gin"); - - migrationBuilder.CreateIndex( - name: "ix_question_bank_grants_allowed_tenant_ids", - table: "question_bank_grants", - column: "allowed_tenant_ids") - .Annotation("Npgsql:IndexMethod", "gin"); - - migrationBuilder.CreateIndex( - name: "ix_question_bank_grants_created_by", - table: "question_bank_grants", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_question_bank_grants_source_question_bank_id_status_starts_~", - table: "question_bank_grants", - columns: new[] { "source_question_bank_id", "status", "starts_at", "expires_at" }); - - migrationBuilder.CreateIndex( - name: "ix_question_bank_grants_updated_by", - table: "question_bank_grants", - column: "updated_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_question_bank_adoptions_created_by", - table: "tenant_question_bank_adoptions", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_question_bank_adoptions_grant_id", - table: "tenant_question_bank_adoptions", - column: "grant_id"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_question_bank_adoptions_source_question_bank_id", - table: "tenant_question_bank_adoptions", - column: "source_question_bank_id"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_question_bank_adoptions_tenant_id_source_question_ba~", - table: "tenant_question_bank_adoptions", - columns: new[] { "tenant_id", "source_question_bank_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_question_bank_adoptions_tenant_id_status_updated_at", - table: "tenant_question_bank_adoptions", - columns: new[] { "tenant_id", "status", "updated_at" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_question_bank_adoptions_tenant_id_target_collection_~", - table: "tenant_question_bank_adoptions", - columns: new[] { "tenant_id", "target_collection_id" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_question_bank_adoptions_tenant_id_target_entry_id", - table: "tenant_question_bank_adoptions", - columns: new[] { "tenant_id", "target_entry_id" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_question_bank_adoptions_tenant_id_target_question_ba~", - table: "tenant_question_bank_adoptions", - columns: new[] { "tenant_id", "target_question_bank_id" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_question_bank_adoptions_updated_by", - table: "tenant_question_bank_adoptions", - column: "updated_by"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "ai_recommendation_reports"); - - migrationBuilder.DropTable( - name: "content_asset_access_events"); - - migrationBuilder.DropTable( - name: "content_asset_security_scan_events"); - - migrationBuilder.DropTable( - name: "tenant_question_bank_adoptions"); - - migrationBuilder.DropTable( - name: "question_bank_grants"); - - migrationBuilder.DropIndex( - name: "ix_content_assets_tenant_id_security_scan_status_upload_status~", - table: "content_assets"); - - migrationBuilder.DropColumn( - name: "security_scan_provider", - table: "content_assets"); - - migrationBuilder.DropColumn( - name: "security_scan_status", - table: "content_assets"); - - migrationBuilder.DropColumn( - name: "security_scan_summary", - table: "content_assets"); - - migrationBuilder.DropColumn( - name: "security_scanned_at", - table: "content_assets"); - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725220206_AddPlatformBillingDunningAndAuditPersistence.Designer.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725220206_AddPlatformBillingDunningAndAuditPersistence.Designer.cs deleted file mode 100644 index cc7f797..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725220206_AddPlatformBillingDunningAndAuditPersistence.Designer.cs +++ /dev/null @@ -1,15067 +0,0 @@ -// -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("20260725220206_AddPlatformBillingDunningAndAuditPersistence")] - partial class AddPlatformBillingDunningAndAuditPersistence - { - /// - 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.Commerce.ActivationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AgentUserId") - .HasColumnType("uuid") - .HasColumnName("agent_user_id"); - - b.Property("BatchId") - .HasColumnType("uuid") - .HasColumnName("batch_id"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CouponCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("coupon_code"); - - b.Property("CouponRedemptionId") - .HasColumnType("uuid") - .HasColumnName("coupon_redemption_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("IsUsed") - .HasColumnType("boolean") - .HasColumnName("is_used"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("SoldTo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("sold_to"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitPriceCents") - .HasColumnType("integer") - .HasColumnName("unit_price_cents"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("used_at"); - - b.Property("UsedBy") - .HasColumnType("uuid") - .HasColumnName("used_by"); - - b.Property("UsedRegionId") - .HasColumnType("uuid") - .HasColumnName("used_region_id"); - - b.HasKey("Id") - .HasName("pk_activation_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_activation_codes_tenant_id_id"); - - b.HasIndex("AgentUserId") - .HasDatabaseName("ix_activation_codes_agent_user_id"); - - b.HasIndex("UsedBy") - .HasDatabaseName("ix_activation_codes_used_by"); - - b.HasIndex("TenantId", "BatchId") - .HasDatabaseName("ix_activation_codes_tenant_id_batch_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_activation_codes_tenant_id_code"); - - b.HasIndex("TenantId", "CouponRedemptionId") - .HasDatabaseName("ix_activation_codes_tenant_id_coupon_redemption_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_activation_codes_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UsedRegionId") - .HasDatabaseName("ix_activation_codes_tenant_id_used_region_id"); - - b.ToTable("activation_codes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CodeBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CampaignName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("campaign_name"); - - b.Property("Channel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("channel"); - - b.Property("CommissionRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("commission_rate"); - - b.Property("CostPriceCents") - .HasColumnType("integer") - .HasColumnName("cost_price_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("DefaultUnitPriceCents") - .HasColumnType("integer") - .HasColumnName("default_unit_price_cents"); - - b.Property("IssuedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("issued_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - 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.HasKey("Id") - .HasName("pk_code_batches"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_code_batches_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_code_batches_tenant_id_legacy_id"); - - b.ToTable("code_batches", null, t => - { - t.HasCheckConstraint("ck_code_batches_amounts", "default_unit_price_cents >= 0 and cost_price_cents >= 0"); - - t.HasCheckConstraint("ck_code_batches_counts", "total_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationBatch", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("BillDate") - .HasColumnType("date") - .HasColumnName("bill_date"); - - b.Property("BillType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("bill_type"); - - b.Property("CompletedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("completed_at"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DuplicateCount") - .HasColumnType("integer") - .HasColumnName("duplicate_count"); - - b.Property("Error") - .HasColumnType("text") - .HasColumnName("error"); - - b.Property("FeeCents") - .HasColumnType("integer") - .HasColumnName("fee_cents"); - - b.Property("IgnoredCount") - .HasColumnType("integer") - .HasColumnName("ignored_count"); - - b.Property("MatchedCount") - .HasColumnType("integer") - .HasColumnName("matched_count"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("MismatchCount") - .HasColumnType("integer") - .HasColumnName("mismatch_count"); - - b.Property("MissingLocalCount") - .HasColumnType("integer") - .HasColumnName("missing_local_count"); - - b.Property("MissingProviderCount") - .HasColumnType("integer") - .HasColumnName("missing_provider_count"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("RefundAmountCents") - .HasColumnType("integer") - .HasColumnName("refund_amount_cents"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source"); - - b.Property("SourceHash") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("source_hash"); - - b.Property("SourceName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("source_name"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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.HasKey("Id") - .HasName("pk_commerce_reconciliation_batches"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_reconciliation_batches_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_commerce_reconciliation_batches_created_by"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_batches_tenant_id_status_created_at"); - - b.HasIndex("TenantId", "Provider", "BillDate", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_batches_tenant_id_provider_bill_dat~"); - - b.ToTable("commerce_reconciliation_batches", null, t => - { - t.HasCheckConstraint("ck_commerce_reconciliation_batches_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commerce_reconciliation_batches_counts", "total_count >= 0 and matched_count >= 0 and mismatch_count >= 0 and missing_local_count >= 0 and missing_provider_count >= 0 and duplicate_count >= 0 and ignored_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationIssue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("AssignedTo") - .HasColumnType("uuid") - .HasColumnName("assigned_to"); - - b.Property("BatchId") - .HasColumnType("uuid") - .HasColumnName("batch_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("DueAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("due_at"); - - b.Property("IssueCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("issue_code"); - - b.Property("IssueNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("issue_no"); - - b.Property("ItemId") - .HasColumnType("uuid") - .HasColumnName("item_id"); - - b.Property("MatchStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("match_status"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("OrderNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("order_no"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderRefundNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_refund_no"); - - b.Property("ProviderTradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_trade_no"); - - b.Property("RefundAmountCents") - .HasColumnType("integer") - .HasColumnName("refund_amount_cents"); - - b.Property("RefundNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("refund_no"); - - b.Property("RefundRequestId") - .HasColumnType("uuid") - .HasColumnName("refund_request_id"); - - b.Property("ResolutionNote") - .HasColumnType("text") - .HasColumnName("resolution_note"); - - b.Property("ResolutionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("resolution_type"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("ResolvedBy") - .HasColumnType("uuid") - .HasColumnName("resolved_by"); - - b.Property("Severity") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("severity"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("Summary") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("summary"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TransactionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("transaction_type"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_commerce_reconciliation_issues"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_reconciliation_issues_tenant_id_id"); - - b.HasIndex("AssignedTo") - .HasDatabaseName("ix_commerce_reconciliation_issues_assigned_to"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_commerce_reconciliation_issues_created_by"); - - b.HasIndex("ResolvedBy") - .HasDatabaseName("ix_commerce_reconciliation_issues_resolved_by"); - - b.HasIndex("TenantId", "IssueNo") - .IsUnique() - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_issue_no"); - - b.HasIndex("TenantId", "ItemId") - .IsUnique() - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_item_id") - .HasFilter("item_id is not null and status in ('open', 'investigating', 'escalated')"); - - b.HasIndex("TenantId", "OrderId") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_order_id"); - - b.HasIndex("TenantId", "RefundRequestId") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_refund_request_id"); - - b.HasIndex("TenantId", "OrderNo", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_order_no_created_at"); - - b.HasIndex("TenantId", "PaymentId", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_payment_id_created~"); - - b.HasIndex("TenantId", "AssignedTo", "Status", "DueAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_assigned_to_status~"); - - b.HasIndex("TenantId", "BatchId", "Status", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_batch_id_status_cr~"); - - b.HasIndex("TenantId", "Status", "Severity", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issues_tenant_id_status_severity_cr~"); - - b.ToTable("commerce_reconciliation_issues", null, t => - { - t.HasCheckConstraint("ck_commerce_reconciliation_issues_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationIssueEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - 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("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("IssueId") - .HasColumnType("uuid") - .HasColumnName("issue_id"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_commerce_reconciliation_issue_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_reconciliation_issue_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_commerce_reconciliation_issue_events_actor_user_id"); - - b.HasIndex("TenantId", "IssueId", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_issue_events_tenant_id_issue_id_cre~"); - - b.ToTable("commerce_reconciliation_issue_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("BatchId") - .HasColumnType("uuid") - .HasColumnName("batch_id"); - - 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("FeeCents") - .HasColumnType("integer") - .HasColumnName("fee_cents"); - - b.Property("IssueCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("issue_code"); - - b.Property("LocalStatus") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("local_status"); - - b.Property("MatchStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("match_status"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("OrderNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("order_no"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderRefundNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_refund_no"); - - b.Property("ProviderStatus") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider_status"); - - b.Property("ProviderTradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_trade_no"); - - b.Property("RefundAmountCents") - .HasColumnType("integer") - .HasColumnName("refund_amount_cents"); - - b.Property("RefundNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("refund_no"); - - b.Property("RefundRequestId") - .HasColumnType("uuid") - .HasColumnName("refund_request_id"); - - b.Property("RefundedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("refunded_at"); - - 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("TransactionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("transaction_type"); - - b.HasKey("Id") - .HasName("pk_commerce_reconciliation_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_reconciliation_items_tenant_id_id"); - - b.HasIndex("BatchId", "RowNo") - .IsUnique() - .HasDatabaseName("ix_commerce_reconciliation_items_batch_id_row_no"); - - b.HasIndex("TenantId", "OrderId") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_order_id"); - - b.HasIndex("TenantId", "PaymentId") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_payment_id"); - - b.HasIndex("TenantId", "RefundRequestId") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_refund_request_id"); - - b.HasIndex("TenantId", "OrderNo", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_order_no_created_at"); - - b.HasIndex("TenantId", "BatchId", "MatchStatus", "RowNo") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_batch_id_match_stat~"); - - b.HasIndex("TenantId", "Provider", "ProviderTradeNo", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_provider_provider_t~"); - - b.HasIndex("TenantId", "RefundNo", "ProviderRefundNo", "CreatedAt") - .HasDatabaseName("ix_commerce_reconciliation_items_tenant_id_refund_no_provider_~"); - - b.ToTable("commerce_reconciliation_items", null, t => - { - t.HasCheckConstraint("ck_commerce_reconciliation_items_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commerce_reconciliation_items_row", "row_no > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceRefundEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - 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("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("RefundRequestId") - .HasColumnType("uuid") - .HasColumnName("refund_request_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_commerce_refund_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_refund_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_commerce_refund_events_actor_user_id"); - - b.HasIndex("TenantId", "RefundRequestId", "CreatedAt") - .HasDatabaseName("ix_commerce_refund_events_tenant_id_refund_request_id_created_~"); - - b.ToTable("commerce_refund_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceRefundRequest", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("CancelledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("cancelled_at"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EntitlementAction") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("entitlement_action"); - - b.Property("FailedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("failed_at"); - - b.Property("FailureReason") - .HasColumnType("text") - .HasColumnName("failure_reason"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("ProcessedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("processed_at"); - - b.Property("ProcessedBy") - .HasColumnType("uuid") - .HasColumnName("processed_by"); - - b.Property("Provider") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderRefundNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_refund_no"); - - b.Property("Reason") - .HasColumnType("text") - .HasColumnName("reason"); - - b.Property("RefundNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("refund_no"); - - b.Property("RequestedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("requested_at") - .HasDefaultValueSql("now()"); - - b.Property("RequestedBy") - .HasColumnType("uuid") - .HasColumnName("requested_by"); - - b.Property("ReviewedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("reviewed_at"); - - b.Property("ReviewedBy") - .HasColumnType("uuid") - .HasColumnName("reviewed_by"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SucceededAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("succeeded_at"); - - 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_commerce_refund_requests"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commerce_refund_requests_tenant_id_id"); - - b.HasIndex("ProcessedBy") - .HasDatabaseName("ix_commerce_refund_requests_processed_by"); - - b.HasIndex("RequestedBy") - .HasDatabaseName("ix_commerce_refund_requests_requested_by"); - - b.HasIndex("ReviewedBy") - .HasDatabaseName("ix_commerce_refund_requests_reviewed_by"); - - b.HasIndex("TenantId", "PaymentId") - .HasDatabaseName("ix_commerce_refund_requests_tenant_id_payment_id"); - - b.HasIndex("TenantId", "RefundNo") - .IsUnique() - .HasDatabaseName("ix_commerce_refund_requests_tenant_id_refund_no"); - - b.HasIndex("TenantId", "OrderId", "CreatedAt") - .HasDatabaseName("ix_commerce_refund_requests_tenant_id_order_id_created_at"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_commerce_refund_requests_tenant_id_status_created_at"); - - b.ToTable("commerce_refund_requests", null, t => - { - t.HasCheckConstraint("ck_commerce_refund_requests_amount", "amount_cents > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Coupon", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DiscountType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("discount_type"); - - b.Property("DiscountValue") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("discount_value"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("MaxUses") - .HasColumnType("integer") - .HasColumnName("max_uses"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("Source") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("ValidFrom") - .HasColumnType("timestamp with time zone") - .HasColumnName("valid_from"); - - b.Property("ValidTo") - .HasColumnType("timestamp with time zone") - .HasColumnName("valid_to"); - - b.HasKey("Id") - .HasName("pk_coupons"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_coupons_tenant_id_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_coupons_tenant_id_code"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_coupons_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_coupons_tenant_id_plan_id"); - - b.ToTable("coupons", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CouponRedemption", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ClaimedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("claimed_at"); - - b.Property("CouponCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("coupon_code"); - - b.Property("CouponId") - .HasColumnType("uuid") - .HasColumnName("coupon_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DiscountAppliedCents") - .HasColumnType("integer") - .HasColumnName("discount_applied_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("Source") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("used_at"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_coupon_redemptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_coupon_redemptions_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_coupon_redemptions_user_id"); - - b.HasIndex("TenantId", "CouponId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_coupon_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_coupon_redemptions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_plan_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_region_id"); - - b.HasIndex("TenantId", "OrderId", "UserId") - .HasDatabaseName("ix_coupon_redemptions_tenant_id_order_id_user_id") - .HasFilter("order_id is not null"); - - b.HasIndex("TenantId", "UserId", "CouponId") - .IsUnique() - .HasDatabaseName("ix_coupon_redemptions_tenant_id_user_id_coupon_id") - .HasFilter("coupon_id is not null"); - - b.ToTable("coupon_redemptions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Entitlement", 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("EntitlementType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("entitlement_type"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("LegacySourceId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_source_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RevokedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("revoked_at"); - - b.Property("RevokedBy") - .HasColumnType("uuid") - .HasColumnName("revoked_by"); - - b.Property("RevokedReason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("revoked_reason"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("StartsAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at") - .HasDefaultValueSql("now()"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_entitlements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_entitlements_tenant_id_id"); - - b.HasIndex("RevokedBy") - .HasDatabaseName("ix_entitlements_revoked_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_entitlements_user_id"); - - b.HasIndex("TenantId", "UserId", "Status", "ExpiresAt") - .HasDatabaseName("ix_entitlements_tenant_id_user_id_status_expires_at"); - - b.ToTable("entitlements", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPlanId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_plan_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("OrderNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("order_no"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PayMethod") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("pay_method"); - - b.Property("PayProvider") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("pay_provider"); - - b.Property("PlanId") - .HasColumnType("uuid") - .HasColumnName("plan_id"); - - b.Property("ProductName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("product_name"); - - b.Property("ProductType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("product_type"); - - b.Property("RawPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RefundedAmountCents") - .HasColumnType("integer") - .HasColumnName("refunded_amount_cents"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("trade_no"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_orders"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_orders_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_orders_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_orders_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderNo") - .IsUnique() - .HasDatabaseName("ix_orders_tenant_id_order_no"); - - b.HasIndex("TenantId", "PlanId") - .HasDatabaseName("ix_orders_tenant_id_plan_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_orders_tenant_id_region_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_orders_tenant_id_user_id_created_at"); - - b.ToTable("orders", null, t => - { - t.HasCheckConstraint("ck_orders_amount", "amount_cents >= 0"); - - t.HasCheckConstraint("ck_orders_refunded_amount", "refunded_amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.OrderItem", 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("ItemId") - .HasColumnType("uuid") - .HasColumnName("item_id"); - - b.Property("ItemType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("item_type"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("Quantity") - .HasColumnType("integer") - .HasColumnName("quantity"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalAmountCents") - .HasColumnType("integer") - .HasColumnName("total_amount_cents"); - - b.Property("UnitAmountCents") - .HasColumnType("integer") - .HasColumnName("unit_amount_cents"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_order_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_order_items_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_order_items_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderId") - .HasDatabaseName("ix_order_items_tenant_id_order_id"); - - b.ToTable("order_items", null, t => - { - t.HasCheckConstraint("ck_order_items_amounts", "unit_amount_cents >= 0 and total_amount_cents >= 0"); - - t.HasCheckConstraint("ck_order_items_quantity", "quantity > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Payment", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - 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("LegacyOrderId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_order_id"); - - b.Property("Method") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("method"); - - b.Property("OrderId") - .HasColumnType("uuid") - .HasColumnName("order_id"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderTradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_trade_no"); - - b.Property("RawPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RefundedAmountCents") - .HasColumnType("integer") - .HasColumnName("refunded_amount_cents"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_payments"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_payments_tenant_id_id"); - - b.HasIndex("Provider", "ProviderTradeNo") - .IsUnique() - .HasDatabaseName("ix_payments_provider_provider_trade_no") - .HasFilter("provider_trade_no is not null"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_payments_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "OrderId", "UpdatedAt") - .HasDatabaseName("ix_payments_tenant_id_order_id_updated_at"); - - b.ToTable("payments", null, t => - { - t.HasCheckConstraint("ck_payments_amount", "amount_cents >= 0"); - - t.HasCheckConstraint("ck_payments_refunded_amount", "refunded_amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.PaymentEvent", 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("Error") - .HasColumnType("text") - .HasColumnName("error"); - - b.Property("EventId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("event_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("Payload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PaymentId") - .HasColumnType("uuid") - .HasColumnName("payment_id"); - - b.Property("ProcessedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("processed_at"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("SignatureValid") - .HasColumnType("boolean") - .HasColumnName("signature_valid"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_payment_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_payment_events_tenant_id_id"); - - b.HasIndex("Provider", "EventId") - .IsUnique() - .HasDatabaseName("ix_payment_events_provider_event_id"); - - b.HasIndex("TenantId", "PaymentId") - .HasDatabaseName("ix_payment_events_tenant_id_payment_id"); - - b.ToTable("payment_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Product", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Cover") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cover"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DetailImages") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("detail_images") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPriceText") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("legacy_price_text"); - - b.Property("Link") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("link"); - - b.Property("PreviewIframe") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("preview_iframe"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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_products"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_products_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_products_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "Type", "SortOrder") - .HasDatabaseName("ix_products_tenant_id_region_id_type_sort_order"); - - b.ToTable("products", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.SvipPlan", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Badge") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("badge"); - - b.Property("CouponOnly") - .HasColumnType("boolean") - .HasColumnName("coupon_only"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Days") - .HasColumnType("integer") - .HasColumnName("days"); - - 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(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OriginalPriceCents") - .HasColumnType("integer") - .HasColumnName("original_price_cents"); - - b.Property("PerDayLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("per_day_label"); - - b.Property("PriceCents") - .HasColumnType("integer") - .HasColumnName("price_cents"); - - b.Property("Recommended") - .HasColumnType("boolean") - .HasColumnName("recommended"); - - 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("VpEnabled") - .HasColumnType("boolean") - .HasColumnName("vp_enabled"); - - b.Property("VpProductId") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("vp_product_id"); - - b.HasKey("Id") - .HasName("pk_svip_plans"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_svip_plans_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_svip_plans_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_svip_plans_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("svip_plans", null, t => - { - t.HasCheckConstraint("ck_svip_plans_days", "days >= 0"); - - t.HasCheckConstraint("ck_svip_plans_price", "price_cents >= 0 and (original_price_cents is null or original_price_cents >= 0)"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantPaymentAccount", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ConfigPublic") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("config_public") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_payment_accounts"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_payment_accounts_tenant_id_id"); - - b.HasIndex("TenantId", "Provider") - .IsUnique() - .HasDatabaseName("ix_tenant_payment_accounts_tenant_id_provider"); - - b.ToTable("tenant_payment_accounts", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantSubscription", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("BillingCycle") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("billing_cycle"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PlanCode") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("plan_code"); - - b.Property("StartsAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_subscriptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_subscriptions_tenant_id_id"); - - b.HasIndex("TenantId", "Status", "ExpiresAt") - .HasDatabaseName("ix_tenant_subscriptions_tenant_id_status_expires_at"); - - b.ToTable("tenant_subscriptions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantUsageRecord", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("MetricKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("metric_key"); - - b.Property("MetricValue") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)") - .HasColumnName("metric_value"); - - b.Property("PeriodEnd") - .HasColumnType("date") - .HasColumnName("period_end"); - - b.Property("PeriodStart") - .HasColumnType("date") - .HasColumnName("period_start"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_tenant_usage_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_usage_records_tenant_id_id"); - - b.HasIndex("TenantId", "MetricKey", "PeriodStart", "PeriodEnd") - .HasDatabaseName("ix_tenant_usage_records_tenant_id_metric_key_period_start_peri~"); - - b.ToTable("tenant_usage_records", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.AiRecommendationReport", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ContextPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("context_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ErrorMessage") - .HasColumnType("text") - .HasColumnName("error_message"); - - b.Property("GeneratedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("generated_at"); - - b.Property("InputPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("input_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Model") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("model"); - - b.Property("PromptVersion") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("prompt_version"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("ResultPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("result_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_ai_recommendation_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_ai_recommendation_reports_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_ai_recommendation_reports_user_id"); - - b.HasIndex("TenantId", "RegionId", "CreatedAt") - .HasDatabaseName("ix_ai_recommendation_reports_tenant_id_region_id_created_at"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_ai_recommendation_reports_tenant_id_user_id_created_at"); - - b.ToTable("ai_recommendation_reports", (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("SecurityScanProvider") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("security_scan_provider"); - - b.Property("SecurityScanStatus") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasDefaultValue("not_required") - .HasColumnName("security_scan_status"); - - b.Property("SecurityScanSummary") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("security_scan_summary") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SecurityScannedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("security_scanned_at"); - - 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", "SecurityScanStatus", "UploadStatus", "Status", "UpdatedAt") - .HasDatabaseName("ix_content_assets_tenant_id_security_scan_status_upload_status~"); - - 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.ContentAssetAccessEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("access_type"); - - b.Property("ActorRole") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("actor_role"); - - b.Property("AssetId") - .HasColumnType("uuid") - .HasColumnName("asset_id"); - - b.Property("AssetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("asset_type"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DenyCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("deny_code"); - - b.Property("Disposition") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("disposition"); - - b.Property("ExpiresInSeconds") - .HasColumnType("integer") - .HasColumnName("expires_in_seconds"); - - b.Property("IpAddress") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Result") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("result"); - - b.Property("SignatureMode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("signature_mode"); - - b.Property("StorageProvider") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("storage_provider"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("Visibility") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("visibility"); - - b.HasKey("Id") - .HasName("pk_content_asset_access_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_content_asset_access_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_content_asset_access_events_user_id"); - - b.HasIndex("TenantId", "AssetId", "CreatedAt") - .HasDatabaseName("ix_content_asset_access_events_tenant_id_asset_id_created_at"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_content_asset_access_events_tenant_id_user_id_created_at") - .HasFilter("user_id is not null"); - - b.HasIndex("TenantId", "AccessType", "Result", "CreatedAt") - .HasDatabaseName("ix_content_asset_access_events_tenant_id_access_type_result_cr~"); - - b.ToTable("content_asset_access_events", null, t => - { - t.HasCheckConstraint("ck_content_asset_access_events_expiry", "expires_in_seconds is null or expires_in_seconds > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAssetSecurityScanEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssetId") - .HasColumnType("uuid") - .HasColumnName("asset_id"); - - 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.PrimitiveCollection("IssueCodes") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("text[]") - .HasColumnName("issue_codes") - .HasDefaultValueSql("'{}'::text[]"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("RiskLevel") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("risk_level"); - - b.Property("ScanStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scan_status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.HasKey("Id") - .HasName("pk_content_asset_security_scan_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_content_asset_security_scan_events_tenant_id_id"); - - b.HasIndex("TenantId", "AssetId", "CreatedAt") - .HasDatabaseName("ix_content_asset_security_scan_events_tenant_id_asset_id_creat~"); - - b.HasIndex("TenantId", "ScanStatus", "RiskLevel", "CreatedAt") - .HasDatabaseName("ix_content_asset_security_scan_events_tenant_id_scan_status_ri~"); - - b.ToTable("content_asset_security_scan_events", (string)null); - }); - - 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_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_handbook_chapters"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_chapters_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_chapters_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_handbook_chapters_tenant_id_subject_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_chapters_tenant_id_entry_id_content_node_id_subjec~"); - - b.ToTable("handbook_chapters", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ChapterId") - .HasColumnType("uuid") - .HasColumnName("chapter_id"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Summary") - .HasColumnType("text") - .HasColumnName("summary"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_handbook_entries"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_entries_tenant_id_id"); - - b.HasIndex("TenantId", "ChapterId") - .HasDatabaseName("ix_handbook_entries_tenant_id_chapter_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_entries_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_entries_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "ChapterId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_entries_tenant_id_entry_id_content_node_id_chapter~"); - - b.ToTable("handbook_entries", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", 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("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("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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - 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_handbook_subjects"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_handbook_subjects_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_handbook_subjects_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "MajorId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_major_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId") - .HasDatabaseName("ix_handbook_subjects_tenant_id_school_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_handbook_subjects_tenant_id_entry_id_content_node_id_region~"); - - b.ToTable("handbook_subjects", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("CdnUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("cdn_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FileName") - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("file_name"); - - 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("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.HasKey("Id") - .HasName("pk_images"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_images_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_images_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "Category", "IsPublic") - .HasDatabaseName("ix_images_tenant_id_category_is_public"); - - b.ToTable("images", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", 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("AssemblyType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assembly_type"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_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("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PassScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("pass_score"); - - b.Property("QuestionLimit") - .HasColumnType("integer") - .HasColumnName("question_limit"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("Rules") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("rules") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Sections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sections") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_practice_blueprints"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_blueprints_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_practice_blueprints_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_practice_blueprints_updated_by"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_collection_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_practice_blueprints_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_practice_blueprints_tenant_id_region_id"); - - b.HasIndex("TenantId", "NodeId", "CollectionId", "Mode", "Status", "SortOrder") - .HasDatabaseName("ix_practice_blueprints_tenant_id_node_id_collection_id_mode_st~"); - - b.ToTable("practice_blueprints", null, t => - { - t.HasCheckConstraint("ck_practice_blueprints_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_practice_blueprints_question_limit", "question_limit is null or question_limit > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionBankGrant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.PrimitiveCollection("AllowedPlanCodes") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("text[]") - .HasColumnName("allowed_plan_codes") - .HasDefaultValueSql("'{}'::text[]"); - - b.PrimitiveCollection("AllowedRegionIds") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("uuid[]") - .HasColumnName("allowed_region_ids") - .HasDefaultValueSql("'{}'::uuid[]"); - - b.PrimitiveCollection("AllowedSubjectIds") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("uuid[]") - .HasColumnName("allowed_subject_ids") - .HasDefaultValueSql("'{}'::uuid[]"); - - b.PrimitiveCollection("AllowedTenantIds") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("uuid[]") - .HasColumnName("allowed_tenant_ids") - .HasDefaultValueSql("'{}'::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("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("GrantScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("grant_scope"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SourceQuestionBankId") - .HasColumnType("uuid") - .HasColumnName("source_question_bank_id"); - - b.Property("StartsAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("starts_at"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_bank_grants"); - - b.HasIndex("AllowedPlanCodes") - .HasDatabaseName("ix_question_bank_grants_allowed_plan_codes"); - - NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("AllowedPlanCodes"), "gin"); - - b.HasIndex("AllowedTenantIds") - .HasDatabaseName("ix_question_bank_grants_allowed_tenant_ids"); - - NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("AllowedTenantIds"), "gin"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_bank_grants_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_question_bank_grants_updated_by"); - - b.HasIndex("SourceQuestionBankId", "Status", "StartsAt", "ExpiresAt") - .HasDatabaseName("ix_question_bank_grants_source_question_bank_id_status_starts_~"); - - b.ToTable("question_bank_grants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", 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("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - b.Property("CollectionType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("collection_type"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Filters") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("filters") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - 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_question_collections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collections_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_collections_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_question_collections_updated_by"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_question_collections_tenant_id_category_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_question_collections_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_collections_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_question_collections_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_collections_tenant_id_region_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_question_collections_tenant_id_subject_id"); - - b.HasIndex("TenantId", "NodeId", "Status", "SortOrder") - .HasDatabaseName("ix_question_collections_tenant_id_node_id_status_sort_order"); - - b.ToTable("question_collections", null, t => - { - t.HasCheckConstraint("ck_question_collections_duration", "duration_minutes is null or duration_minutes > 0"); - - t.HasCheckConstraint("ck_question_collections_question_count", "question_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Required") - .HasColumnType("boolean") - .HasColumnName("required"); - - b.Property("Score") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - 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_question_collection_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_collection_items_tenant_id_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_question_collection_items_tenant_id_question_id"); - - b.HasIndex("TenantId", "CollectionId", "QuestionId") - .IsUnique() - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_question_~"); - - b.HasIndex("TenantId", "CollectionId", "SectionKey", "SortOrder") - .HasDatabaseName("ix_question_collection_items_tenant_id_collection_id_section_k~"); - - b.ToTable("question_collection_items", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", 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("DisplayName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Types") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("types") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_question_type_groups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_type_groups_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_type_groups_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_question_type_groups_tenant_id_subject_id_is_active_sort_or~"); - - b.ToTable("question_type_groups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", 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("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("LegacyVideoId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_video_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_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("VideoId") - .HasColumnType("uuid") - .HasColumnName("video_id"); - - b.Property("VideoType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("video_type"); - - b.HasKey("Id") - .HasName("pk_question_videos"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_videos_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "VideoId") - .HasDatabaseName("ix_question_videos_tenant_id_video_id"); - - b.HasIndex("TenantId", "QuestionId", "VideoId", "VideoType") - .IsUnique() - .HasDatabaseName("ix_question_videos_tenant_id_question_id_video_id_video_type"); - - b.ToTable("question_videos", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("SourceSubjectId") - .HasColumnType("uuid") - .HasColumnName("source_subject_id"); - - b.Property("TargetSubjectId") - .HasColumnType("uuid") - .HasColumnName("target_subject_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Id") - .HasColumnType("uuid") - .HasColumnName("id"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacySourceSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_source_subject_id"); - - b.Property("LegacyTargetSubjectId") - .HasColumnType("text") - .HasColumnName("legacy_target_subject_id"); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at"); - - b.HasKey("TenantId", "SourceSubjectId", "TargetSubjectId") - .HasName("pk_subject_shares"); - - b.HasIndex("TenantId", "TargetSubjectId") - .HasDatabaseName("ix_subject_shares_tenant_id_target_subject_id"); - - b.ToTable("subject_shares", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.TenantQuestionBankAdoption", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AdoptionMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("adoption_mode"); - - b.Property("CopiedQuestionCount") - .HasColumnType("integer") - .HasColumnName("copied_question_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("GrantId") - .HasColumnType("uuid") - .HasColumnName("grant_id"); - - b.Property("LastSyncedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_synced_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SourceQuestionBankId") - .HasColumnType("uuid") - .HasColumnName("source_question_bank_id"); - - b.Property("SourceSnapshot") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("source_snapshot") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SyncStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("sync_status"); - - b.Property("TargetCollectionId") - .HasColumnType("uuid") - .HasColumnName("target_collection_id"); - - b.Property("TargetEntryId") - .HasColumnType("uuid") - .HasColumnName("target_entry_id"); - - b.Property("TargetQuestionBankId") - .HasColumnType("uuid") - .HasColumnName("target_question_bank_id"); - - 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_tenant_question_bank_adoptions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_question_bank_adoptions_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_question_bank_adoptions_created_by"); - - b.HasIndex("GrantId") - .HasDatabaseName("ix_tenant_question_bank_adoptions_grant_id"); - - b.HasIndex("SourceQuestionBankId") - .HasDatabaseName("ix_tenant_question_bank_adoptions_source_question_bank_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_question_bank_adoptions_updated_by"); - - b.HasIndex("TenantId", "SourceQuestionBankId") - .IsUnique() - .HasDatabaseName("ix_tenant_question_bank_adoptions_tenant_id_source_question_ba~"); - - b.HasIndex("TenantId", "TargetCollectionId") - .HasDatabaseName("ix_tenant_question_bank_adoptions_tenant_id_target_collection_~"); - - b.HasIndex("TenantId", "TargetEntryId") - .HasDatabaseName("ix_tenant_question_bank_adoptions_tenant_id_target_entry_id"); - - b.HasIndex("TenantId", "TargetQuestionBankId") - .HasDatabaseName("ix_tenant_question_bank_adoptions_tenant_id_target_question_ba~"); - - b.HasIndex("TenantId", "Status", "UpdatedAt") - .HasDatabaseName("ix_tenant_question_bank_adoptions_tenant_id_status_updated_at"); - - b.ToTable("tenant_question_bank_adoptions", null, t => - { - t.HasCheckConstraint("ck_tenant_question_bank_adoptions_copied_count", "copied_question_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", 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("FavoritedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("favorited_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Note") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.HasKey("Id") - .HasName("pk_user_word_favorites"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_favorites_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_favorites_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_favorites_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_favorites_tenant_id_user_id_word_id"); - - b.ToTable("user_word_favorites", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CorrectStreak") - .HasColumnType("integer") - .HasColumnName("correct_streak"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DueLevel") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("due_level"); - - b.Property("EaseFactor") - .ValueGeneratedOnAdd() - .HasPrecision(4, 2) - .HasColumnType("numeric(4,2)") - .HasDefaultValue(2.50m) - .HasColumnName("ease_factor"); - - b.Property("LastResult") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("last_result"); - - b.Property("LastReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_review_at"); - - b.Property("LegacyId") - .HasColumnType("text") - .HasColumnName("legacy_id"); - - b.Property("LegacyUserId") - .HasColumnType("text") - .HasColumnName("legacy_user_id"); - - b.Property("LegacyWordId") - .HasColumnType("text") - .HasColumnName("legacy_word_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NextReviewAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_review_at"); - - b.Property("ReviewCount") - .HasColumnType("integer") - .HasColumnName("review_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WordId") - .HasColumnType("uuid") - .HasColumnName("word_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_user_word_progress"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_word_progress_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_word_progress_user_id"); - - b.HasIndex("TenantId", "WordId") - .HasDatabaseName("ix_user_word_progress_tenant_id_word_id"); - - b.HasIndex("TenantId", "UserId", "WordId") - .IsUnique() - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_word_id"); - - b.HasIndex("TenantId", "UserId", "NextReviewAt", "Status", "DueLevel") - .HasDatabaseName("ix_user_word_progress_tenant_id_user_id_next_review_at_status_~"); - - b.ToTable("user_word_progress", null, t => - { - t.HasCheckConstraint("ck_user_word_progress_correct_streak", "correct_streak >= 0"); - - t.HasCheckConstraint("ck_user_word_progress_ease_factor", "ease_factor >= 1.30 and ease_factor <= 3.00"); - - t.HasCheckConstraint("ck_user_word_progress_review_count", "review_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("IsGeneral") - .HasColumnType("boolean") - .HasColumnName("is_general"); - - b.Property("KnowledgeTags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("knowledge_tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ThumbnailUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("thumbnail_url"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VideoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("video_url"); - - b.HasKey("Id") - .HasName("pk_video_explanations"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_video_explanations_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_video_explanations_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "SourceHash") - .HasDatabaseName("ix_video_explanations_tenant_id_source_hash") - .HasFilter("source_hash is not null"); - - b.HasIndex("TenantId", "SubjectId", "IsActive", "SortOrder") - .HasDatabaseName("ix_video_explanations_tenant_id_subject_id_is_active_sort_order"); - - b.ToTable("video_explanations", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WordCount") - .HasColumnType("integer") - .HasColumnName("word_count"); - - b.HasKey("Id") - .HasName("pk_vocabulary_units"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_units_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_units_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_vocabulary_units_tenant_id_region_id"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_units_tenant_id_entry_id_content_node_id_region_~"); - - b.ToTable("vocabulary_units", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", 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("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("Example") - .HasColumnType("text") - .HasColumnName("example"); - - b.Property("ExampleTranslation") - .HasColumnType("text") - .HasColumnName("example_translation"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Meaning") - .HasColumnType("text") - .HasColumnName("meaning"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phonetic") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("phonetic"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitId") - .HasColumnType("uuid") - .HasColumnName("unit_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Word") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("word"); - - b.HasKey("Id") - .HasName("pk_vocabulary_words"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_vocabulary_words_tenant_id_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_vocabulary_words_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_vocabulary_words_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UnitId", "IsActive", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_vocabulary_words_tenant_id_unit_id_is_active_sort_order_cre~"); - - b.HasIndex("TenantId", "EntryId", "ContentNodeId", "UnitId", "IsActive", "SortOrder") - .HasDatabaseName("ix_vocabulary_words_tenant_id_entry_id_content_node_id_unit_id~"); - - b.ToTable("vocabulary_words", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlement", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CommissionAmountCents") - .HasColumnType("integer") - .HasColumnName("commission_amount_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DefaultRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("default_rate"); - - b.Property("EffectiveRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("effective_rate"); - - b.Property("GeneratedBy") - .HasColumnType("uuid") - .HasColumnName("generated_by"); - - b.Property("GrossAmountCents") - .HasColumnType("integer") - .HasColumnName("gross_amount_cents"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PaidBy") - .HasColumnType("uuid") - .HasColumnName("paid_by"); - - b.Property("PaidUserCount") - .HasColumnType("integer") - .HasColumnName("paid_user_count"); - - b.Property("PaymentAccount") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("payment_account"); - - b.Property("PaymentMethod") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("payment_method"); - - b.Property("PeriodEnd") - .HasColumnType("date") - .HasColumnName("period_end"); - - b.Property("PeriodStart") - .HasColumnType("date") - .HasColumnName("period_start"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Remark") - .HasColumnType("text") - .HasColumnName("remark"); - - b.Property("ReviewedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("reviewed_at"); - - b.Property("ReviewedBy") - .HasColumnType("uuid") - .HasColumnName("reviewed_by"); - - b.Property("SettlementNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("settlement_no"); - - b.Property("SourceCount") - .HasColumnType("integer") - .HasColumnName("source_count"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_commission_settlements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commission_settlements_tenant_id_id"); - - b.HasIndex("GeneratedBy") - .HasDatabaseName("ix_commission_settlements_generated_by"); - - b.HasIndex("PaidBy") - .HasDatabaseName("ix_commission_settlements_paid_by"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_commission_settlements_referrer_user_id"); - - b.HasIndex("ReviewedBy") - .HasDatabaseName("ix_commission_settlements_reviewed_by"); - - b.HasIndex("TenantId", "SettlementNo") - .IsUnique() - .HasDatabaseName("ix_commission_settlements_tenant_id_settlement_no"); - - b.HasIndex("TenantId", "ReferrerUserId", "PeriodStart") - .HasDatabaseName("ix_commission_settlements_referrer_start"); - - b.HasIndex("TenantId", "ReferrerUserId", "PeriodStart", "PeriodEnd") - .IsUnique() - .HasDatabaseName("ux_commission_settlements_referrer_period"); - - b.ToTable("commission_settlements", null, t => - { - t.HasCheckConstraint("ck_commission_settlements_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commission_settlements_counts", "source_count >= 0 and paid_user_count >= 0"); - - t.HasCheckConstraint("ck_commission_settlements_period", "period_end >= period_start"); - - t.HasCheckConstraint("ck_commission_settlements_rates", "default_rate >= 0 and default_rate <= 1 and (effective_rate is null or (effective_rate >= 0 and effective_rate <= 1))"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlementItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AttributionType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("attribution_type"); - - b.Property("CommissionAmountCents") - .HasColumnType("integer") - .HasColumnName("commission_amount_cents"); - - b.Property("CommissionRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("commission_rate"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("GrossAmountCents") - .HasColumnType("integer") - .HasColumnName("gross_amount_cents"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RateSource") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("rate_source"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("SettlementId") - .HasColumnType("uuid") - .HasColumnName("settlement_id"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceNo") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_no"); - - b.Property("SourcePaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("source_paid_at"); - - b.Property("SourceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_type"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_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_commission_settlement_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_commission_settlement_items_tenant_id_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_commission_settlement_items_referrer_user_id"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_commission_settlement_items_student_user_id"); - - b.HasIndex("TenantId", "SettlementId") - .HasDatabaseName("ix_commission_settlement_items_tenant_id_settlement_id"); - - b.HasIndex("TenantId", "ReferrerUserId", "SourcePaidAt") - .HasDatabaseName("ix_commission_settlement_items_tenant_id_referrer_user_id_sour~"); - - b.HasIndex("TenantId", "SourceType", "SourceId") - .IsUnique() - .HasDatabaseName("ix_commission_settlement_items_tenant_id_source_type_source_id"); - - b.ToTable("commission_settlement_items", null, t => - { - t.HasCheckConstraint("ck_commission_settlement_items_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); - - t.HasCheckConstraint("ck_commission_settlement_items_rate", "commission_rate >= 0 and commission_rate <= 1"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignmentConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("assignment_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("AssignmentCursor") - .HasColumnType("integer") - .HasColumnName("assignment_cursor"); - - b.Property("AssignmentMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assignment_mode"); - - b.Property("AssignmentPool") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("assignment_pool") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DelaySeconds") - .HasColumnType("integer") - .HasColumnName("delay_seconds"); - - b.Property("Enabled") - .HasColumnType("boolean") - .HasColumnName("enabled"); - - b.Property("ExamType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("exam_type"); - - b.Property("FormName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("form_name"); - - b.Property("SecretRef") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("secret_ref"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TimeoutSeconds") - .HasColumnType("integer") - .HasColumnName("timeout_seconds"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Url") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("url"); - - b.HasKey("Id") - .HasName("pk_crm_config"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_config_tenant_id_id"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_crm_config_tenant_id"); - - b.HasIndex("TenantId", "AssignmentMode") - .HasDatabaseName("ix_crm_config_tenant_id_assignment_mode"); - - b.ToTable("crm_config", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempt") - .HasColumnType("integer") - .HasColumnName("attempt"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ErrorMessage") - .HasColumnType("text") - .HasColumnName("error_message"); - - b.Property("HttpCode") - .HasColumnType("integer") - .HasColumnName("http_code"); - - b.Property("LeadId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Outcome") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("outcome"); - - b.Property("RecordId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("record_id"); - - b.Property("RequestBody") - .HasColumnType("text") - .HasColumnName("request_body"); - - b.Property("RequestPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("request_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ResponseSummary") - .HasMaxLength(2000) - .HasColumnType("character varying(2000)") - .HasColumnName("response_summary"); - - b.Property("SignedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("signed_at"); - - 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_crm_webhook_log"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_webhook_log_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_log_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RecordId", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_log_tenant_id_record_id_created_at"); - - b.ToTable("crm_webhook_log", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookQueueItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempts") - .HasColumnType("integer") - .HasColumnName("attempts"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IdempotencyKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("idempotency_key"); - - b.Property("LastAttemptAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_attempt_at"); - - b.Property("LastError") - .HasColumnType("text") - .HasColumnName("last_error"); - - b.Property("LastHttpCode") - .HasColumnType("integer") - .HasColumnName("last_http_code"); - - b.Property("LastResponseSummary") - .HasColumnType("text") - .HasColumnName("last_response_summary"); - - b.Property("LeadId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("NextAttemptAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_attempt_at"); - - b.Property("Payload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("RecordId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("record_id"); - - b.Property("ScheduledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("scheduled_at"); - - b.Property("SentAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("sent_at"); - - b.Property("Source") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TargetUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("target_url"); - - 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_crm_webhook_queue"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_crm_webhook_queue_tenant_id_id"); - - b.HasIndex("TenantId", "IdempotencyKey") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_idempotency_key") - .HasFilter("idempotency_key is not null"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RecordId") - .IsUnique() - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_record_id") - .HasFilter("record_id is not null"); - - b.HasIndex("TenantId", "RecordId", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_record_id_created_at") - .HasFilter("record_id is not null"); - - b.HasIndex("TenantId", "Source", "CreatedAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_source_created_at") - .HasFilter("source = 'tenant.student.crm_push'"); - - b.HasIndex("TenantId", "Status", "ScheduledAt", "NextAttemptAt") - .HasDatabaseName("ix_crm_webhook_queue_tenant_id_status_scheduled_at_next_attemp~"); - - b.ToTable("crm_webhook_queue", null, t => - { - t.HasCheckConstraint("ck_crm_webhook_queue_attempts", "attempts >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Channel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("channel"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("code"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("LandingPath") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("landing_path"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_referral_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_codes_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_referral_codes_user_id"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_referral_codes_tenant_id_code"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_referral_codes_tenant_id_user_id"); - - b.HasIndex("TenantId", "Code", "Status") - .HasDatabaseName("ix_referral_codes_tenant_id_code_status"); - - b.ToTable("referral_codes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralLead", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("assigned_at"); - - b.Property("AssignedBy") - .HasColumnType("uuid") - .HasColumnName("assigned_by"); - - b.Property("AssignedToUserId") - .HasColumnType("uuid") - .HasColumnName("assigned_to_user_id"); - - b.Property("AssignmentMode") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("assignment_mode"); - - b.Property("BindType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("bind_type"); - - b.Property("BoundAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("bound_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FirstTrackId") - .HasColumnType("uuid") - .HasColumnName("first_track_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ProtectedUntil") - .HasColumnType("timestamp with time zone") - .HasColumnName("protected_until"); - - b.Property("RefCode") - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Source") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_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_referral_leads"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_leads_tenant_id_id"); - - b.HasIndex("AssignedBy") - .HasDatabaseName("ix_referral_leads_assigned_by"); - - b.HasIndex("AssignedToUserId") - .HasDatabaseName("ix_referral_leads_assigned_to_user_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_referral_leads_referrer_user_id"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_referral_leads_student_user_id"); - - b.HasIndex("TenantId", "FirstTrackId") - .HasDatabaseName("ix_referral_leads_tenant_id_first_track_id"); - - b.HasIndex("TenantId", "StudentUserId") - .IsUnique() - .HasDatabaseName("ix_referral_leads_tenant_id_student_user_id"); - - b.HasIndex("TenantId", "ReferrerUserId", "BoundAt") - .HasDatabaseName("ix_referral_leads_tenant_id_referrer_user_id_bound_at"); - - b.HasIndex("TenantId", "AssignedToUserId", "Status", "BoundAt") - .HasDatabaseName("ix_referral_leads_tenant_id_assigned_to_user_id_status_bound_at"); - - b.ToTable("referral_leads", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralQrcode", 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("ErrorMessage") - .HasColumnType("text") - .HasColumnName("error_message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Page") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("page"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("provider"); - - b.Property("QrcodeUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("qrcode_url"); - - b.Property("RefCode") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("Scene") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("scene"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_referral_qrcodes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_qrcodes_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_referral_qrcodes_user_id"); - - b.HasIndex("TenantId", "RefCode", "Status") - .HasDatabaseName("ix_referral_qrcodes_tenant_id_ref_code_status"); - - b.HasIndex("TenantId", "Provider", "Scene", "Page") - .IsUnique() - .HasDatabaseName("ix_referral_qrcodes_tenant_id_provider_scene_page"); - - b.ToTable("referral_qrcodes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTeamEdge", 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("LeaderUserId") - .HasColumnType("uuid") - .HasColumnName("leader_user_id"); - - b.Property("MemberUserId") - .HasColumnType("uuid") - .HasColumnName("member_user_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RelationType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("relation_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_referral_team_edges"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_team_edges_tenant_id_id"); - - b.HasIndex("LeaderUserId") - .HasDatabaseName("ix_referral_team_edges_leader_user_id"); - - b.HasIndex("MemberUserId") - .HasDatabaseName("ix_referral_team_edges_member_user_id"); - - b.HasIndex("TenantId", "LeaderUserId", "Status") - .HasDatabaseName("ix_referral_team_edges_tenant_id_leader_user_id_status"); - - b.HasIndex("TenantId", "MemberUserId", "RelationType") - .IsUnique() - .HasDatabaseName("ix_referral_team_edges_tenant_id_member_user_id_relation_type"); - - b.ToTable("referral_team_edges", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTrack", 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("EventType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("event_type"); - - b.Property("IpAddress") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("ip_address"); - - b.Property("LeadId") - .HasColumnType("uuid") - .HasColumnName("lead_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("RefCode") - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("ref_code"); - - b.Property("ReferrerUserId") - .HasColumnType("uuid") - .HasColumnName("referrer_user_id"); - - b.Property("Source") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source"); - - b.Property("TargetUserId") - .HasColumnType("uuid") - .HasColumnName("target_user_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserAgent") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_referral_tracks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_referral_tracks_tenant_id_id"); - - b.HasIndex("ReferrerUserId") - .HasDatabaseName("ix_referral_tracks_referrer_user_id"); - - b.HasIndex("TargetUserId") - .HasDatabaseName("ix_referral_tracks_target_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_referral_tracks_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "LeadId", "CreatedAt") - .HasDatabaseName("ix_referral_tracks_tenant_id_lead_id_created_at"); - - b.HasIndex("TenantId", "RefCode", "EventType", "CreatedAt") - .HasDatabaseName("ix_referral_tracks_tenant_id_ref_code_event_type_created_at"); - - b.ToTable("referral_tracks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.TenantCommissionSetting", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - 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("DefaultRate") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("default_rate"); - - b.Property("MinSettlementCents") - .HasColumnType("integer") - .HasColumnName("min_settlement_cents"); - - b.Property("SettlementCycle") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("settlement_cycle"); - - 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_tenant_commission_settings"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_commission_settings_tenant_id_id"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_tenant_commission_settings_tenant_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_commission_settings_updated_by"); - - b.ToTable("tenant_commission_settings", null, t => - { - t.HasCheckConstraint("ck_tenant_commission_settings_default_rate", "default_rate >= 0 and default_rate <= 1"); - - t.HasCheckConstraint("ck_tenant_commission_settings_min_settlement", "min_settlement_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", 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("LastCheckInDate") - .HasColumnType("date") - .HasColumnName("last_check_in_date"); - - b.Property("LegacyUserId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_user_id"); - - b.Property("MasteredWordsCount") - .HasColumnType("integer") - .HasColumnName("mastered_words_count"); - - b.Property("ModuleSelections") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_selections") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Progress") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("progress") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("QuestionsAnsweredToday") - .HasColumnType("integer") - .HasColumnName("questions_answered_today"); - - b.Property("RecentActivities") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("recent_activities") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SelectedMajorId") - .HasColumnType("uuid") - .HasColumnName("selected_major_id"); - - b.Property("SelectedSchoolId") - .HasColumnType("uuid") - .HasColumnName("selected_school_id"); - - b.Property("Stats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("stats") - .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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_student_profiles"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_student_profiles_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_student_profiles_user_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_student_profiles_tenant_id_region_id"); - - b.HasIndex("TenantId", "SelectedMajorId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_major_id"); - - b.HasIndex("TenantId", "SelectedSchoolId") - .HasDatabaseName("ix_student_profiles_tenant_id_selected_school_id"); - - b.HasIndex("TenantId", "UserId") - .IsUnique() - .HasDatabaseName("ix_student_profiles_tenant_id_user_id"); - - b.ToTable("student_profiles", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AvatarUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("avatar_url"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("LastSeenAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_seen_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyPasswordHash") - .HasMaxLength(512) - .HasColumnType("character varying(512)") - .HasColumnName("legacy_password_hash"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PasswordMigrationRequired") - .HasColumnType("boolean") - .HasColumnName("password_migration_required"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("PrimaryRole") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("primary_role"); - - b.Property("RawProfile") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_profile") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Score") - .HasColumnType("integer") - .HasColumnName("score"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("Username") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("username"); - - b.HasKey("Id") - .HasName("pk_users"); - - b.HasIndex("Email") - .IsUnique() - .HasDatabaseName("ix_users_email"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_users_legacy_id"); - - b.HasIndex("Phone") - .IsUnique() - .HasDatabaseName("ix_users_phone"); - - b.HasIndex("Username") - .IsUnique() - .HasDatabaseName("ix_users_username"); - - b.ToTable("users", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", 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("Email") - .HasMaxLength(320) - .HasColumnType("citext") - .HasColumnName("email"); - - b.Property("OpenId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("open_id"); - - b.Property("Phone") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderSubject") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("provider_subject"); - - b.Property("SecretPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("secret_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UnionId") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("union_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_identities"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_identities_user_id"); - - b.HasIndex("Provider", "ProviderSubject") - .IsUnique() - .HasDatabaseName("ix_user_identities_provider_provider_subject"); - - b.ToTable("user_identities", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("AnsweredAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("answered_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("IsCorrect") - .HasColumnType("boolean") - .HasColumnName("is_correct"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyQuestionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_question_id"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("QuestionVersionId") - .HasColumnType("uuid") - .HasColumnName("question_version_id"); - - b.Property("SelectedOptions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("selected_options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_answer_records"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_answer_records_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_answer_records_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_answer_records_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id"); - - b.HasIndex("TenantId", "QuestionId", "QuestionVersionId") - .HasDatabaseName("ix_answer_records_tenant_id_question_id_question_version_id"); - - b.HasIndex("TenantId", "UserId", "PracticeSessionId") - .HasDatabaseName("ix_answer_records_tenant_id_user_id_practice_session_id"); - - b.ToTable("answer_records", null, t => - { - t.HasCheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActiveUsers") - .HasColumnType("integer") - .HasColumnName("active_users"); - - 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("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("NewOrders") - .HasColumnType("integer") - .HasColumnName("new_orders"); - - b.Property("NewQuestions") - .HasColumnType("integer") - .HasColumnName("new_questions"); - - b.Property("NewRevenueCents") - .HasColumnType("integer") - .HasColumnName("new_revenue_cents"); - - b.Property("NewUsers") - .HasColumnType("integer") - .HasColumnName("new_users"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_dashboard_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_dashboard_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId") - .IsUnique() - .HasDatabaseName("ix_dashboard_daily_stats_tenant_id_stat_date_region_id"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId"), false); - - b.ToTable("dashboard_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", 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("ExamAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("exam_at"); - - b.Property("ExamName") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("exam_name"); - - b.Property("ExamType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("exam_type"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - 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("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_exam_dates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_exam_dates_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_exam_dates_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_exam_dates_tenant_id_region_id"); - - b.HasIndex("TenantId", "SchoolId", "ExamAt") - .HasDatabaseName("ix_exam_dates_tenant_id_school_id_exam_at"); - - b.ToTable("exam_dates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Source") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("source"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_favorite_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_favorite_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_favorite_questions_tenant_id_question_id"); - - b.ToTable("favorite_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessMode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("access_mode"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EntitlementId") - .HasColumnType("uuid") - .HasColumnName("entitlement_id"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("GrantedCount") - .HasColumnType("integer") - .HasColumnName("granted_count"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("Reason") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("reason"); - - b.Property("RequestedCount") - .HasColumnType("integer") - .HasColumnName("requested_count"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_access_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_access_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_access_events_user_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_access_events_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_practice_access_events_tenant_id_user_id_created_at"); - - b.ToTable("practice_access_events", null, t => - { - t.HasCheckConstraint("ck_practice_access_events_consumed_free_quota", "consumed_free_quota >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_granted_count", "granted_count >= 0"); - - t.HasCheckConstraint("ck_practice_access_events_requested_count", "requested_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", 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("FreeLimit") - .HasColumnType("integer") - .HasColumnName("free_limit"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ScopeId") - .HasColumnType("uuid") - .HasColumnName("scope_id"); - - b.Property("ScopeType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("scope_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UsageDate") - .ValueGeneratedOnAdd() - .HasColumnType("date") - .HasColumnName("usage_date") - .HasDefaultValueSql("current_date"); - - b.Property("UsedCount") - .HasColumnType("integer") - .HasColumnName("used_count"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_daily_usage"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_daily_usage_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_daily_usage_user_id"); - - b.HasIndex("TenantId", "UserId", "UsageDate") - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date"); - - b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId") - .IsUnique() - .HasDatabaseName("ix_practice_daily_usage_tenant_id_user_id_usage_date_scope_typ~"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "UserId", "UsageDate", "ScopeType", "ScopeId"), false); - - b.ToTable("practice_daily_usage", null, t => - { - t.HasCheckConstraint("ck_practice_daily_usage_free_limit", "free_limit >= 0"); - - t.HasCheckConstraint("ck_practice_daily_usage_used_count", "used_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AccessEntitlementId") - .HasColumnType("uuid") - .HasColumnName("access_entitlement_id"); - - b.Property("AccessMode") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasDefaultValue("free") - .HasColumnName("access_mode"); - - b.Property("AccessSnapshot") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("access_snapshot") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("ConsumedFreeQuota") - .HasColumnType("integer") - .HasColumnName("consumed_free_quota"); - - b.Property("ContentNodeId") - .HasColumnType("uuid") - .HasColumnName("content_node_id"); - - b.Property("DurationMinutes") - .HasColumnType("integer") - .HasColumnName("duration_minutes"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("FinishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("finished_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at") - .HasDefaultValueSql("now()"); - - b.Property("TargetId") - .HasColumnType("uuid") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(8, 2) - .HasColumnType("numeric(8,2)") - .HasColumnName("total_score"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_practice_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_sessions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "UserId", "Id") - .HasName("ak_practice_sessions_tenant_id_user_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_sessions_user_id"); - - b.HasIndex("TenantId", "BlueprintId") - .HasDatabaseName("ix_practice_sessions_tenant_id_blueprint_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_sessions_tenant_id_collection_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_practice_sessions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_practice_sessions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "UserId", "StartedAt") - .HasDatabaseName("ix_practice_sessions_tenant_id_user_id_started_at"); - - b.ToTable("practice_sessions", null, t => - { - t.HasCheckConstraint("ck_practice_sessions_consumed_free_quota", "consumed_free_quota >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("BlueprintId") - .HasColumnType("uuid") - .HasColumnName("blueprint_id"); - - b.Property("CollectionId") - .HasColumnType("uuid") - .HasColumnName("collection_id"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DurationSeconds") - .HasColumnType("integer") - .HasColumnName("duration_seconds"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("mode"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionResults") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("question_results") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionStats") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("section_stats") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("StartedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("started_at"); - - b.Property("SubmittedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("submitted_at") - .HasDefaultValueSql("now()"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalQuestions") - .HasColumnType("integer") - .HasColumnName("total_questions"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.Property("WrongQuestionIds") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("wrong_question_ids") - .HasDefaultValueSql("'[]'::jsonb"); - - b.HasKey("Id") - .HasName("pk_practice_session_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_reports_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_practice_session_reports_user_id"); - - b.HasIndex("TenantId", "CollectionId") - .HasDatabaseName("ix_practice_session_reports_tenant_id_collection_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .IsUnique() - .HasDatabaseName("ix_practice_session_reports_tenant_id_practice_session_id"); - - b.HasIndex("TenantId", "BlueprintId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_blueprint_id_submitted_at") - .HasFilter("blueprint_id is not null"); - - b.HasIndex("TenantId", "UserId", "SubmittedAt") - .HasDatabaseName("ix_practice_session_reports_tenant_id_user_id_submitted_at"); - - b.ToTable("practice_session_reports", null, t => - { - t.HasCheckConstraint("ck_practice_session_reports_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_reports_counts", "total_questions >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_duration", "duration_seconds >= 0"); - - t.HasCheckConstraint("ck_practice_session_reports_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Accuracy") - .HasPrecision(6, 4) - .HasColumnType("numeric(6,4)") - .HasColumnName("accuracy"); - - b.Property("AnsweredCount") - .HasColumnType("integer") - .HasColumnName("answered_count"); - - b.Property("CorrectCount") - .HasColumnType("integer") - .HasColumnName("correct_count"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeSessionId") - .HasColumnType("uuid") - .HasColumnName("practice_session_id"); - - b.Property("QuestionCount") - .HasColumnType("integer") - .HasColumnName("question_count"); - - b.Property("QuestionType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("question_type"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("Score") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("score"); - - b.Property("SectionKey") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("section_key"); - - b.Property("SectionName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("section_name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalScore") - .HasPrecision(10, 2) - .HasColumnType("numeric(10,2)") - .HasColumnName("total_score"); - - b.Property("UnansweredCount") - .HasColumnType("integer") - .HasColumnName("unanswered_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WrongCount") - .HasColumnType("integer") - .HasColumnName("wrong_count"); - - b.HasKey("Id") - .HasName("pk_practice_session_report_sections"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_practice_session_report_sections_tenant_id_id"); - - b.HasIndex("TenantId", "PracticeSessionId") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_practice_session~"); - - b.HasIndex("TenantId", "ReportId", "SectionKey") - .IsUnique() - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sectio~"); - - b.HasIndex("TenantId", "ReportId", "SortOrder") - .HasDatabaseName("ix_practice_session_report_sections_tenant_id_report_id_sort_o~"); - - b.ToTable("practice_session_report_sections", null, t => - { - t.HasCheckConstraint("ck_practice_session_report_sections_accuracy", "accuracy >= 0 and accuracy <= 1"); - - t.HasCheckConstraint("ck_practice_session_report_sections_counts", "question_count >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); - - t.HasCheckConstraint("ck_practice_session_report_sections_scores", "score >= 0 and total_score >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", 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("LastAccessAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_access_at"); - - b.Property("LastPracticeAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_practice_at"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PracticeType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("practice_type"); - - b.Property("Progress") - .HasColumnType("integer") - .HasColumnName("progress"); - - b.Property("TargetLegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("target_legacy_id"); - - b.Property("TargetName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("target_name"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_recent_practices"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_recent_practices_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_recent_practices_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_recent_practices_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "LastAccessAt") - .HasDatabaseName("ix_recent_practices_tenant_id_user_id_last_access_at"); - - b.ToTable("recent_practices", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attachments") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("attachments") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("Contact") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("contact"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("HandledAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("handled_at"); - - b.Property("HandledBy") - .HasColumnType("uuid") - .HasColumnName("handled_by"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("Resolution") - .HasColumnType("text") - .HasColumnName("resolution"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - 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.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_reports"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_reports_tenant_id_id"); - - b.HasIndex("HandledBy") - .HasDatabaseName("ix_reports_handled_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_reports_user_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_reports_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "QuestionId", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_question_id_created_at") - .HasFilter("question_id is not null"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_reports_tenant_id_status_created_at"); - - b.ToTable("reports", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FromStatus") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("from_status"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("ReportId") - .HasColumnType("uuid") - .HasColumnName("report_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("ToStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("to_status"); - - b.HasKey("Id") - .HasName("pk_report_status_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_report_status_events_tenant_id_id"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_report_status_events_actor_user_id"); - - b.HasIndex("TenantId", "ReportId", "CreatedAt") - .HasDatabaseName("ix_report_status_events_tenant_id_report_id_created_at"); - - b.ToTable("report_status_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CodeCount") - .HasColumnType("integer") - .HasColumnName("code_count"); - - b.Property("CodeEstimated") - .HasColumnType("integer") - .HasColumnName("code_estimated"); - - b.Property("CodeUsed") - .HasColumnType("integer") - .HasColumnName("code_used"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EstimatedRevenueCents") - .HasColumnType("integer") - .HasColumnName("estimated_revenue_cents"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyRegionId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_region_id"); - - b.Property("OrderCount") - .HasColumnType("integer") - .HasColumnName("order_count"); - - b.Property("RealRevenueCents") - .HasColumnType("integer") - .HasColumnName("real_revenue_cents"); - - b.Property("RebuiltAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("rebuilt_at"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SaleType") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("sale_type"); - - b.Property("StatDate") - .HasColumnType("date") - .HasColumnName("stat_date"); - - 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_revenue_daily_stats"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_revenue_daily_stats_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_region_id"); - - b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType") - .IsUnique() - .HasDatabaseName("ix_revenue_daily_stats_tenant_id_stat_date_region_id_sale_type"); - - NpgsqlIndexBuilderExtensions.AreNullsDistinct(b.HasIndex("TenantId", "StatDate", "RegionId", "SaleType"), false); - - b.ToTable("revenue_daily_stats", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BalanceAfter") - .HasColumnType("integer") - .HasColumnName("balance_after"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("event_type"); - - b.Property("IdempotencyKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("idempotency_key"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Points") - .HasColumnType("integer") - .HasColumnName("points"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_score_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_score_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_score_events_user_id"); - - b.HasIndex("TenantId", "IdempotencyKey") - .IsUnique() - .HasDatabaseName("ix_user_score_events_tenant_id_idempotency_key"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_user_score_events_tenant_id_user_id_created_at"); - - b.ToTable("user_score_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("LastWrongAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("last_wrong_at") - .HasDefaultValueSql("now()"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("WrongCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(1) - .HasColumnName("wrong_count"); - - b.HasKey("TenantId", "UserId", "QuestionId") - .HasName("pk_wrong_questions"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_wrong_questions_user_id"); - - b.HasIndex("TenantId", "QuestionId") - .HasDatabaseName("ix_wrong_questions_tenant_id_question_id"); - - b.ToTable("wrong_questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Announcement", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BackgroundColor") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("background_color"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("Link") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("link"); - - 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_announcements"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_announcements_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_announcements_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "IsActive", "SortOrder") - .HasDatabaseName("ix_announcements_tenant_id_is_active_sort_order"); - - b.ToTable("announcements", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.AuditLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Action") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("action"); - - b.Property("ActorUserId") - .HasColumnType("uuid") - .HasColumnName("actor_user_id"); - - 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("IpAddress") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("ip_address"); - - b.Property("TargetId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_audit_logs"); - - b.HasIndex("ActorUserId") - .HasDatabaseName("ix_audit_logs_actor_user_id"); - - b.HasIndex("TenantId", "CreatedAt") - .HasDatabaseName("ix_audit_logs_tenant_id_created_at"); - - b.HasIndex("TenantId", "TargetType", "TargetId", "CreatedAt") - .HasDatabaseName("ix_audit_logs_tenant_id_target_type_target_id_created_at"); - - b.ToTable("audit_logs", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Badge", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Category") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("category"); - - b.Property("ConditionExtra") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("condition_extra") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ConditionField") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("condition_field"); - - b.Property("ConditionOperator") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("condition_operator"); - - b.Property("ConditionValue") - .HasPrecision(18, 4) - .HasColumnType("numeric(18,4)") - .HasColumnName("condition_value"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("IconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("icon_url"); - - b.Property("IsActive") - .HasColumnType("boolean") - .HasColumnName("is_active"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Level") - .HasColumnType("integer") - .HasColumnName("level"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnlockType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("unlock_type"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_badges"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_badges_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_badges_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "Category", "IsActive", "SortOrder") - .HasDatabaseName("ix_badges_tenant_id_category_is_active_sort_order"); - - b.ToTable("badges", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Banner", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BackgroundColor") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("background_color"); - - b.Property("BorderColor") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("border_color"); - - b.Property("ButtonLink") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("button_link"); - - b.Property("ButtonText") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("button_text"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - 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("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Subtitle") - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("subtitle"); - - 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.HasKey("Id") - .HasName("pk_banners"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_banners_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_banners_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_banners_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("banners", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Faq", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Answer") - .HasColumnType("text") - .HasColumnName("answer"); - - 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("Question") - .HasColumnType("text") - .HasColumnName("question"); - - 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.HasKey("Id") - .HasName("pk_faqs"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_faqs_tenant_id_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_faqs_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId", "IsActive", "SortOrder") - .HasDatabaseName("ix_faqs_tenant_id_region_id_is_active_sort_order"); - - b.ToTable("faqs", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantContentNotification", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActionLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("action_label"); - - b.Property("ActionPath") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("action_path"); - - b.Property("AdoptionId") - .HasColumnType("uuid") - .HasColumnName("adoption_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("DedupeKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("dedupe_key"); - - b.Property("Message") - .IsRequired() - .HasColumnType("text") - .HasColumnName("message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NotificationType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("notification_type"); - - b.Property("ReadAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("read_at"); - - b.Property("ReadBy") - .HasColumnType("uuid") - .HasColumnName("read_by"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("Severity") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("severity"); - - b.Property("SourceQuestionBankId") - .HasColumnType("uuid") - .HasColumnName("source_question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenant_content_notifications"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_content_notifications_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_content_notifications_created_by"); - - b.HasIndex("ReadBy") - .HasDatabaseName("ix_tenant_content_notifications_read_by"); - - b.HasIndex("TenantId", "SourceQuestionBankId") - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_source_question_bank~"); - - b.HasIndex("TenantId", "NotificationType", "DedupeKey") - .IsUnique() - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_notification_type_de~") - .HasFilter("dedupe_key is not null"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_status_created_at"); - - b.HasIndex("TenantId", "AdoptionId", "NotificationType", "Status") - .HasDatabaseName("ix_tenant_content_notifications_tenant_id_adoption_id_notifica~"); - - b.ToTable("tenant_content_notifications", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantThemeConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActivePublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("active_public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ActiveTemplateCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("active_template_code"); - - b.Property("ActiveTheme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("active_theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DraftPublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("draft_public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("DraftTemplateCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("draft_template_code"); - - b.Property("DraftTheme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("draft_theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("DraftUpdatedBy") - .HasColumnType("uuid") - .HasColumnName("draft_updated_by"); - - b.Property("PublishedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("published_at"); - - b.Property("PublishedBy") - .HasColumnType("uuid") - .HasColumnName("published_by"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_theme_configs"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_theme_configs_tenant_id_id"); - - b.HasIndex("ActiveTemplateCode") - .HasDatabaseName("ix_tenant_theme_configs_active_template_code"); - - b.HasIndex("DraftTemplateCode") - .HasDatabaseName("ix_tenant_theme_configs_draft_template_code"); - - b.HasIndex("DraftUpdatedBy") - .HasDatabaseName("ix_tenant_theme_configs_draft_updated_by"); - - b.HasIndex("PublishedBy") - .HasDatabaseName("ix_tenant_theme_configs_published_by"); - - b.HasIndex("TenantId") - .IsUnique() - .HasDatabaseName("ix_tenant_theme_configs_tenant_id"); - - b.ToTable("tenant_theme_configs", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantThemeTemplate", 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("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("PreviewImageUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("preview_image_url"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenant_theme_templates"); - - b.HasAlternateKey("Code") - .HasName("ak_tenant_theme_templates_code"); - - b.HasIndex("Code") - .IsUnique() - .HasDatabaseName("ix_tenant_theme_templates_code"); - - b.HasIndex("Status", "SortOrder", "Code") - .HasDatabaseName("ix_tenant_theme_templates_status_sort_order_code"); - - b.ToTable("tenant_theme_templates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserBadge", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BadgeId") - .HasColumnType("uuid") - .HasColumnName("badge_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("GrantedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("granted_at"); - - b.Property("GrantedBy") - .HasColumnType("uuid") - .HasColumnName("granted_by"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_badges"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_badges_tenant_id_id"); - - b.HasIndex("GrantedBy") - .HasDatabaseName("ix_user_badges_granted_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_badges_user_id"); - - b.HasIndex("TenantId", "BadgeId") - .HasDatabaseName("ix_user_badges_tenant_id_badge_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_user_badges_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "UserId", "BadgeId") - .IsUnique() - .HasDatabaseName("ix_user_badges_tenant_id_user_id_badge_id"); - - b.ToTable("user_badges", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserNotification", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ActionLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("action_label"); - - b.Property("ActionPath") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("action_path"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DedupeKey") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("dedupe_key"); - - b.Property("Message") - .IsRequired() - .HasColumnType("text") - .HasColumnName("message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NotificationType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("notification_type"); - - b.Property("ReadAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("read_at"); - - b.Property("Severity") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("severity"); - - b.Property("SourceId") - .HasColumnType("uuid") - .HasColumnName("source_id"); - - b.Property("SourceType") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("source_type"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_user_notifications"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_user_notifications_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_user_notifications_created_by"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_user_notifications_user_id"); - - b.HasIndex("TenantId", "SourceType", "SourceId") - .HasDatabaseName("ix_user_notifications_tenant_id_source_type_source_id"); - - b.HasIndex("TenantId", "UserId", "NotificationType", "DedupeKey") - .IsUnique() - .HasDatabaseName("ix_user_notifications_tenant_id_user_id_notification_type_dedu~") - .HasFilter("dedupe_key is not null"); - - b.HasIndex("TenantId", "UserId", "Status", "CreatedAt") - .HasDatabaseName("ix_user_notifications_tenant_id_user_id_status_created_at"); - - b.ToTable("user_notifications", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.PlatformAuditAlert", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AcknowledgedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("acknowledged_at"); - - b.Property("AcknowledgedBy") - .HasColumnType("uuid") - .HasColumnName("acknowledged_by"); - - b.Property("Action") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("action"); - - b.Property("AuditLogId") - .HasColumnType("uuid") - .HasColumnName("audit_log_id"); - - 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("FirstSeenAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("first_seen_at") - .HasDefaultValueSql("now()"); - - b.Property("LastSeenAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("last_seen_at") - .HasDefaultValueSql("now()"); - - b.Property("ResolutionNote") - .HasColumnType("text") - .HasColumnName("resolution_note"); - - b.Property("ResolvedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("resolved_at"); - - b.Property("ResolvedBy") - .HasColumnType("uuid") - .HasColumnName("resolved_by"); - - b.Property("RuleId") - .HasColumnType("uuid") - .HasColumnName("rule_id"); - - b.Property("Severity") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("severity"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("Summary") - .HasColumnType("text") - .HasColumnName("summary"); - - b.Property("TargetId") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("target_id"); - - b.Property("TargetType") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("target_type"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("title"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_platform_audit_alerts"); - - b.HasIndex("AcknowledgedBy") - .HasDatabaseName("ix_platform_audit_alerts_acknowledged_by"); - - b.HasIndex("AuditLogId") - .HasDatabaseName("ix_platform_audit_alerts_audit_log_id"); - - b.HasIndex("ResolvedBy") - .HasDatabaseName("ix_platform_audit_alerts_resolved_by"); - - b.HasIndex("RuleId", "AuditLogId") - .IsUnique() - .HasDatabaseName("ix_platform_audit_alerts_rule_id_audit_log_id"); - - b.HasIndex("Status", "Severity", "CreatedAt") - .HasDatabaseName("ix_platform_audit_alerts_status_severity_created_at"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_platform_audit_alerts_tenant_id_status_created_at"); - - b.ToTable("platform_audit_alerts", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.PlatformAuditAlertRule", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.PrimitiveCollection("ActionPatterns") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("text[]") - .HasColumnName("action_patterns") - .HasDefaultValueSql("'{}'::text[]"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("code"); - - b.Property("Conditions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("conditions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("Enabled") - .HasColumnType("boolean") - .HasColumnName("enabled"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("Severity") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("severity"); - - b.PrimitiveCollection("TargetTypes") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("text[]") - .HasColumnName("target_types") - .HasDefaultValueSql("'{}'::text[]"); - - 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_platform_audit_alert_rules"); - - b.HasIndex("Code") - .IsUnique() - .HasDatabaseName("ix_platform_audit_alert_rules_code"); - - b.HasIndex("TenantId") - .HasDatabaseName("ix_platform_audit_alert_rules_tenant_id"); - - b.HasIndex("Enabled", "Severity", "Code") - .HasDatabaseName("ix_platform_audit_alert_rules_enabled_severity_code"); - - b.ToTable("platform_audit_alert_rules", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.PlatformDunningNotificationChannel", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ChannelCode") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("channel_code"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("Enabled") - .HasColumnType("boolean") - .HasColumnName("enabled"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("MinReminderLevel") - .HasColumnType("integer") - .HasColumnName("min_reminder_level"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("provider"); - - b.PrimitiveCollection("ReminderChannels") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("text[]") - .HasColumnName("reminder_channels") - .HasDefaultValueSql("array['internal']::text[]"); - - b.PrimitiveCollection("ReminderTypes") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("text[]") - .HasColumnName("reminder_types") - .HasDefaultValueSql("array['overdue', 'final_notice']::text[]"); - - b.Property("SecretRef") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("secret_ref"); - - b.PrimitiveCollection("TenantIds") - .IsRequired() - .ValueGeneratedOnAdd() - .HasColumnType("uuid[]") - .HasColumnName("tenant_ids") - .HasDefaultValueSql("'{}'::uuid[]"); - - b.Property("TimeoutSeconds") - .HasColumnType("integer") - .HasColumnName("timeout_seconds"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("WebhookUrl") - .IsRequired() - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("webhook_url"); - - b.HasKey("Id") - .HasName("pk_platform_dunning_notification_channels"); - - b.HasIndex("ChannelCode") - .IsUnique() - .HasDatabaseName("ix_platform_dunning_notification_channels_channel_code"); - - b.HasIndex("Enabled", "MinReminderLevel", "ChannelCode") - .HasDatabaseName("ix_platform_dunning_notification_channels_enabled_min_reminder~"); - - b.ToTable("platform_dunning_notification_channels", null, t => - { - t.HasCheckConstraint("ck_platform_dunning_channels_level", "min_reminder_level between 1 and 20"); - - t.HasCheckConstraint("ck_platform_dunning_channels_timeout", "timeout_seconds between 1 and 60"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.PlatformDunningNotificationEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempts") - .HasColumnType("integer") - .HasColumnName("attempts"); - - b.Property("ChannelId") - .HasColumnType("uuid") - .HasColumnName("channel_id"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("InvoiceId") - .HasColumnType("uuid") - .HasColumnName("invoice_id"); - - b.Property("LastAttemptAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("last_attempt_at"); - - b.Property("LastError") - .HasColumnType("text") - .HasColumnName("last_error"); - - b.Property("LastHttpCode") - .HasColumnType("integer") - .HasColumnName("last_http_code"); - - b.Property("LastResponseSummary") - .HasColumnType("text") - .HasColumnName("last_response_summary"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NextAttemptAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("next_attempt_at"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("provider"); - - b.Property("ReminderId") - .HasColumnType("uuid") - .HasColumnName("reminder_id"); - - b.Property("RequestPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("request_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ScheduledAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("scheduled_at") - .HasDefaultValueSql("now()"); - - b.Property("SentAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("sent_at"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_platform_dunning_notification_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_platform_dunning_notification_events_tenant_id_id"); - - b.HasIndex("ChannelId", "ReminderId") - .IsUnique() - .HasDatabaseName("ix_platform_dunning_notification_events_channel_id_reminder_id"); - - b.HasIndex("TenantId", "InvoiceId") - .HasDatabaseName("ix_platform_dunning_notification_events_tenant_id_invoice_id"); - - b.HasIndex("TenantId", "ReminderId") - .HasDatabaseName("ix_platform_dunning_notification_events_tenant_id_reminder_id"); - - b.HasIndex("InvoiceId", "Status", "CreatedAt") - .HasDatabaseName("ix_platform_dunning_notification_events_invoice_id_status_crea~"); - - b.HasIndex("ReminderId", "Status", "CreatedAt") - .HasDatabaseName("ix_platform_dunning_notification_events_reminder_id_status_cre~"); - - b.HasIndex("TenantId", "Status", "CreatedAt") - .HasDatabaseName("ix_platform_dunning_notification_events_tenant_id_status_creat~"); - - b.HasIndex("Status", "NextAttemptAt", "ScheduledAt", "CreatedAt") - .HasDatabaseName("ix_platform_dunning_notification_events_status_next_attempt_at~"); - - b.ToTable("platform_dunning_notification_events", null, t => - { - t.HasCheckConstraint("ck_platform_dunning_events_attempts", "attempts >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.PlatformSaasPlan", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BaseAmountCents") - .HasColumnType("integer") - .HasColumnName("base_amount_cents"); - - b.Property("BillingCycle") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("billing_cycle"); - - 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("Currency") - .IsRequired() - .HasMaxLength(10) - .HasColumnType("character varying(10)") - .HasColumnName("currency"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("FeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("IncludedQuotas") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("included_quotas") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OveragePrices") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("overage_prices") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_platform_saas_plans"); - - b.HasIndex("Code") - .IsUnique() - .HasDatabaseName("ix_platform_saas_plans_code"); - - b.HasIndex("Status", "SortOrder") - .HasDatabaseName("ix_platform_saas_plans_status_sort_order"); - - b.ToTable("platform_saas_plans", null, t => - { - t.HasCheckConstraint("ck_platform_saas_plans_amount", "base_amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.TenantBillingProfile", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("BankAccountMasked") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("bank_account_masked"); - - b.Property("BankName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("bank_name"); - - b.Property("BillingAddress") - .HasColumnType("text") - .HasColumnName("billing_address"); - - b.Property("BillingName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("billing_name"); - - b.Property("ContactEmail") - .HasMaxLength(300) - .HasColumnType("citext") - .HasColumnName("contact_email"); - - b.Property("ContactName") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("contact_name"); - - b.Property("ContactPhone") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("contact_phone"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("InvoiceTitle") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("invoice_title"); - - b.Property("InvoiceType") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("invoice_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("TaxId") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("tax_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_billing_profiles"); - - b.ToTable("tenant_billing_profiles", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.TenantInvoice", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BalanceCents") - .HasColumnType("integer") - .HasColumnName("balance_cents"); - - b.Property("BillingPeriodEnd") - .HasColumnType("date") - .HasColumnName("billing_period_end"); - - b.Property("BillingPeriodStart") - .HasColumnType("date") - .HasColumnName("billing_period_start"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("Currency") - .IsRequired() - .HasMaxLength(10) - .HasColumnType("character varying(10)") - .HasColumnName("currency"); - - b.Property("DiscountCents") - .HasColumnType("integer") - .HasColumnName("discount_cents"); - - b.Property("DueDate") - .HasColumnType("date") - .HasColumnName("due_date"); - - b.Property("InvoiceNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("invoice_no"); - - b.Property("InvoiceType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("invoice_type"); - - b.Property("IssuedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("issued_at"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Note") - .HasColumnType("text") - .HasColumnName("note"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PaidCents") - .HasColumnType("integer") - .HasColumnName("paid_cents"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubtotalCents") - .HasColumnType("integer") - .HasColumnName("subtotal_cents"); - - b.Property("TaxCents") - .HasColumnType("integer") - .HasColumnName("tax_cents"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TotalCents") - .HasColumnType("integer") - .HasColumnName("total_cents"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenant_invoices"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_invoices_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_invoices_created_by"); - - b.HasIndex("InvoiceNo") - .IsUnique() - .HasDatabaseName("ix_tenant_invoices_invoice_no"); - - b.HasIndex("TenantId", "BillingPeriodStart", "BillingPeriodEnd") - .IsUnique() - .HasDatabaseName("ix_tenant_invoices_tenant_id_billing_period_start_billing_peri~") - .HasFilter("invoice_type = 'usage_overage' and status <> 'void' and metadata->>'source' = 'usage_overage_auto'"); - - b.HasIndex("TenantId", "Status", "DueDate") - .HasDatabaseName("ix_tenant_invoices_tenant_id_status_due_date"); - - b.ToTable("tenant_invoices", null, t => - { - t.HasCheckConstraint("ck_tenant_invoices_amounts", "subtotal_cents >= 0 and discount_cents >= 0 and tax_cents >= 0 and total_cents >= 0 and paid_cents >= 0 and balance_cents >= 0"); - - t.HasCheckConstraint("ck_tenant_invoices_period", "billing_period_end is null or billing_period_start is null or billing_period_end >= billing_period_start"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.TenantInvoiceItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasColumnName("description"); - - b.Property("InvoiceId") - .HasColumnType("uuid") - .HasColumnName("invoice_id"); - - b.Property("ItemRefId") - .HasColumnType("uuid") - .HasColumnName("item_ref_id"); - - b.Property("ItemType") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("item_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Quantity") - .HasPrecision(12, 2) - .HasColumnType("numeric(12,2)") - .HasColumnName("quantity"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UnitAmountCents") - .HasColumnType("integer") - .HasColumnName("unit_amount_cents"); - - b.HasKey("Id") - .HasName("pk_tenant_invoice_items"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_invoice_items_tenant_id_id"); - - b.HasIndex("InvoiceId") - .HasDatabaseName("ix_tenant_invoice_items_invoice_id"); - - b.HasIndex("TenantId", "InvoiceId") - .HasDatabaseName("ix_tenant_invoice_items_tenant_id_invoice_id"); - - b.ToTable("tenant_invoice_items", null, t => - { - t.HasCheckConstraint("ck_tenant_invoice_items_amounts", "unit_amount_cents >= 0 and amount_cents >= 0"); - - t.HasCheckConstraint("ck_tenant_invoice_items_quantity", "quantity > 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.TenantInvoicePayment", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AmountCents") - .HasColumnType("integer") - .HasColumnName("amount_cents"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("InvoiceId") - .HasColumnType("uuid") - .HasColumnName("invoice_id"); - - b.Property("Method") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("method"); - - b.Property("PaidAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("paid_at"); - - b.Property("PaymentNo") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("payment_no"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("ProviderTradeNo") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("provider_trade_no"); - - b.Property("RawPayload") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("raw_payload") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ReceivedBy") - .HasColumnType("uuid") - .HasColumnName("received_by"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_invoice_payments"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_invoice_payments_tenant_id_id"); - - b.HasIndex("PaymentNo") - .IsUnique() - .HasDatabaseName("ix_tenant_invoice_payments_payment_no"); - - b.HasIndex("ReceivedBy") - .HasDatabaseName("ix_tenant_invoice_payments_received_by"); - - b.HasIndex("InvoiceId", "Status") - .HasDatabaseName("ix_tenant_invoice_payments_invoice_id_status"); - - b.HasIndex("TenantId", "InvoiceId") - .HasDatabaseName("ix_tenant_invoice_payments_tenant_id_invoice_id"); - - b.ToTable("tenant_invoice_payments", null, t => - { - t.HasCheckConstraint("ck_tenant_invoice_payments_amount", "amount_cents >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.TenantInvoiceReminder", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AcknowledgedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("acknowledged_at"); - - b.Property("BalanceCentsSnapshot") - .HasColumnType("integer") - .HasColumnName("balance_cents_snapshot"); - - b.Property("Channel") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("channel"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DueDate") - .HasColumnType("date") - .HasColumnName("due_date"); - - b.Property("InvoiceId") - .HasColumnType("uuid") - .HasColumnName("invoice_id"); - - b.Property("Message") - .HasColumnType("text") - .HasColumnName("message"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ReminderDate") - .HasColumnType("date") - .HasColumnName("reminder_date"); - - b.Property("ReminderLevel") - .HasColumnType("integer") - .HasColumnName("reminder_level"); - - b.Property("ReminderType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("reminder_type"); - - b.Property("SentAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("sent_at"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_invoice_reminders"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_invoice_reminders_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_invoice_reminders_created_by"); - - b.HasIndex("InvoiceId", "ReminderDate") - .HasDatabaseName("ix_tenant_invoice_reminders_invoice_id_reminder_date"); - - b.HasIndex("TenantId", "Status", "ReminderDate") - .HasDatabaseName("ix_tenant_invoice_reminders_tenant_id_status_reminder_date"); - - b.HasIndex("TenantId", "InvoiceId", "ReminderType", "Channel", "ReminderDate") - .IsUnique() - .HasDatabaseName("ix_tenant_invoice_reminders_tenant_id_invoice_id_reminder_type~"); - - b.ToTable("tenant_invoice_reminders", null, t => - { - t.HasCheckConstraint("ck_tenant_invoice_reminders_balance", "balance_cents_snapshot >= 0"); - - t.HasCheckConstraint("ck_tenant_invoice_reminders_level", "reminder_level between 1 and 20"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("CategoryId") - .HasColumnType("uuid") - .HasColumnName("category_id"); - - 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("CurrentVersionId") - .HasColumnType("uuid") - .HasColumnName("current_version_id"); - - b.Property("Difficulty") - .HasColumnType("integer") - .HasColumnName("difficulty"); - - b.Property("EntryId") - .HasColumnType("uuid") - .HasColumnName("entry_id"); - - b.Property("ExamMarkers") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("exam_markers") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("HasVideoExplanation") - .HasColumnType("boolean") - .HasColumnName("has_video_explanation"); - - b.Property("LegacyCategoryId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_category_id"); - - b.Property("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("LegacyNodeId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_node_id"); - - b.Property("LegacySubjectId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_subject_id"); - - b.Property("MediaUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("media_url"); - - b.Property("NodeId") - .HasColumnType("uuid") - .HasColumnName("node_id"); - - b.Property("PrimaryCollectionId") - .HasColumnType("uuid") - .HasColumnName("primary_collection_id"); - - b.Property("QuestionBankId") - .HasColumnType("uuid") - .HasColumnName("question_bank_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("SubjectId") - .HasColumnType("uuid") - .HasColumnName("subject_id"); - - b.Property("Tags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("tags") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Type") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("type"); - - b.Property("TypeLabel") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("type_label"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_questions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_questions_tenant_id_id"); - - b.HasIndex("TenantId", "CategoryId") - .HasDatabaseName("ix_questions_tenant_id_category_id"); - - b.HasIndex("TenantId", "ContentNodeId") - .HasDatabaseName("ix_questions_tenant_id_content_node_id"); - - b.HasIndex("TenantId", "EntryId") - .HasDatabaseName("ix_questions_tenant_id_entry_id"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_questions_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "NodeId") - .HasDatabaseName("ix_questions_tenant_id_node_id"); - - b.HasIndex("TenantId", "PrimaryCollectionId") - .HasDatabaseName("ix_questions_tenant_id_primary_collection_id"); - - b.HasIndex("TenantId", "QuestionBankId") - .HasDatabaseName("ix_questions_tenant_id_question_bank_id"); - - b.HasIndex("TenantId", "SubjectId") - .HasDatabaseName("ix_questions_tenant_id_subject_id"); - - b.HasIndex("TenantId", "Id", "CurrentVersionId") - .HasDatabaseName("ix_questions_tenant_id_id_current_version_id"); - - b.ToTable("questions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", 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("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SourceScope") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("source_scope"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_question_banks"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_banks_tenant_id_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_question_banks_tenant_id_region_id"); - - b.ToTable("question_banks", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AnswerText") - .HasColumnType("text") - .HasColumnName("answer_text"); - - b.Property("CodeLang") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("code_lang"); - - b.Property("CodeTemplate") - .HasColumnType("text") - .HasColumnName("code_template"); - - b.Property("Content") - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CorrectOptionIndex") - .HasColumnType("integer") - .HasColumnName("correct_option_index"); - - b.Property("CorrectOptionIndices") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("correct_option_indices") - .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("Explanation") - .HasColumnType("text") - .HasColumnName("explanation"); - - b.Property("Options") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("options") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("QuestionId") - .HasColumnType("uuid") - .HasColumnName("question_id"); - - b.Property("SourceHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("source_hash"); - - b.Property("SubQuestions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("sub_questions") - .HasDefaultValueSql("'[]'::jsonb"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("VersionNo") - .HasColumnType("integer") - .HasColumnName("version_no"); - - b.HasKey("Id") - .HasName("pk_question_versions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_question_versions_tenant_id_id"); - - b.HasAlternateKey("TenantId", "QuestionId", "Id") - .HasName("ak_question_versions_tenant_id_question_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_question_versions_created_by"); - - b.HasIndex("QuestionId", "VersionNo") - .IsUnique() - .HasDatabaseName("ix_question_versions_question_id_version_no"); - - b.ToTable("question_versions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", 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("FailureCode") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("failure_code"); - - b.Property("Identifier") - .HasMaxLength(320) - .HasColumnType("character varying(320)") - .HasColumnName("identifier"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Result") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("result"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_login_events"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_login_events_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_login_events_user_id"); - - b.HasIndex("TenantId", "UserId", "CreatedAt") - .HasDatabaseName("ix_auth_login_events_tenant_id_user_id_created_at"); - - b.ToTable("auth_login_events", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", 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("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("RevokedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("revoked_at"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("TokenHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("token_hash"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_auth_sessions"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_auth_sessions_tenant_id_id"); - - b.HasIndex("TokenHash") - .IsUnique() - .HasDatabaseName("ix_auth_sessions_token_hash"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_auth_sessions_user_id"); - - b.HasIndex("TenantId", "UserId", "ExpiresAt") - .HasDatabaseName("ix_auth_sessions_tenant_id_user_id_expires_at") - .HasFilter("revoked_at is null"); - - b.ToTable("auth_sessions", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Dimension") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("dimension"); - - b.Property("ScopeHash") - .HasMaxLength(128) - .HasColumnType("character varying(128)") - .HasColumnName("scope_hash"); - - b.Property("BucketStart") - .HasColumnType("timestamp with time zone") - .HasColumnName("bucket_start"); - - b.Property("RequestCount") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0) - .HasColumnName("request_count"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId", "Dimension", "ScopeHash", "BucketStart") - .HasName("pk_sms_send_rate_limits"); - - b.HasIndex("UpdatedAt") - .HasDatabaseName("ix_sms_send_rate_limits_updated_at"); - - b.ToTable("sms_send_rate_limits", null, t => - { - t.HasCheckConstraint("ck_sms_send_rate_limits_request_count", "request_count >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Attempts") - .HasColumnType("integer") - .HasColumnName("attempts"); - - b.Property("CodeHash") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("code_hash"); - - b.Property("ConsumedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("consumed_at"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("expires_at"); - - b.Property("IpAddress") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("ip_address"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Phone") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("phone"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Purpose") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("purpose"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UserAgent") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)") - .HasColumnName("user_agent"); - - b.HasKey("Id") - .HasName("pk_sms_verification_codes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_sms_verification_codes_tenant_id_id"); - - b.HasIndex("TenantId", "Phone", "Purpose") - .IsUnique() - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "CreatedAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_created_at") - .HasFilter("consumed_at is null and status in ('pending', 'sent')"); - - b.HasIndex("TenantId", "Phone", "Purpose", "ExpiresAt") - .HasDatabaseName("ix_sms_verification_codes_tenant_id_phone_purpose_expires_at"); - - b.ToTable("sms_verification_codes", null, t => - { - t.HasCheckConstraint("ck_sms_verification_codes_attempts", "attempts >= 0"); - }); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BillingStatus") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("billing_status"); - - 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("LegalName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("legal_name"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Mode") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("mode"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("OwnerUserId") - .HasColumnType("uuid") - .HasColumnName("owner_user_id"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("citext") - .HasColumnName("slug"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("Id") - .HasName("pk_tenants"); - - b.HasIndex("LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenants_legacy_id"); - - b.HasIndex("OwnerUserId") - .HasDatabaseName("ix_tenants_owner_user_id"); - - b.HasIndex("Slug") - .IsUnique() - .HasDatabaseName("ix_tenants_slug"); - - b.ToTable("tenants", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ConfigPublic") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("config_public") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("DisplayName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("display_name"); - - b.Property("Provider") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("provider"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_auth_providers"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_auth_providers_tenant_id_id"); - - b.HasIndex("TenantId", "Provider") - .IsUnique() - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider"); - - b.HasIndex("TenantId", "Provider", "Status") - .HasDatabaseName("ix_tenant_auth_providers_tenant_id_provider_status"); - - b.ToTable("tenant_auth_providers", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("BrandName") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("brand_name"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FaviconUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("favicon_url"); - - b.Property("LogoUrl") - .HasMaxLength(2048) - .HasColumnType("character varying(2048)") - .HasColumnName("logo_url"); - - b.Property("OrganizationName") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("organization_name"); - - b.Property("PublicAssets") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_assets") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ServiceAccountName") - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("service_account_name"); - - b.Property("ServiceWechat") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("service_wechat"); - - b.Property("ShortName") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("short_name"); - - b.Property("Slogan") - .HasMaxLength(300) - .HasColumnType("character varying(300)") - .HasColumnName("slogan"); - - b.Property("Theme") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("theme") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_branding"); - - b.ToTable("tenant_branding", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Code") - .HasMaxLength(100) - .HasColumnType("character varying(100)") - .HasColumnName("code"); - - 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("LegacyId") - .HasMaxLength(64) - .HasColumnType("character varying(64)") - .HasColumnName("legacy_id"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("RegionId") - .HasColumnType("uuid") - .HasColumnName("region_id"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_classes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_classes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_classes_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_classes_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_code") - .HasFilter("code is not null and code <> ''"); - - b.HasIndex("TenantId", "LegacyId") - .IsUnique() - .HasDatabaseName("ix_tenant_classes_tenant_id_legacy_id"); - - b.HasIndex("TenantId", "RegionId") - .HasDatabaseName("ix_tenant_classes_tenant_id_region_id") - .HasFilter("region_id is not null"); - - b.HasIndex("TenantId", "Status", "SortOrder", "CreatedAt") - .HasDatabaseName("ix_tenant_classes_tenant_id_status_sort_order_created_at"); - - b.ToTable("tenant_classes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_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("JoinedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("joined_at") - .HasDefaultValueSql("now()"); - - b.Property("LeftAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("left_at"); - - b.Property("MemberType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("member_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_class_members"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_class_members_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_class_members_user_id"); - - b.HasIndex("TenantId", "ClassId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_status_member_type"); - - b.HasIndex("TenantId", "ClassId", "UserId", "MemberType") - .IsUnique() - .HasDatabaseName("ix_tenant_class_members_tenant_id_class_id_user_id_member_type"); - - b.HasIndex("TenantId", "UserId", "Status", "MemberType") - .HasDatabaseName("ix_tenant_class_members_tenant_id_user_id_status_member_type"); - - b.ToTable("tenant_class_members", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", 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("DomainType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("domain_type"); - - b.Property("Host") - .IsRequired() - .HasMaxLength(253) - .HasColumnType("citext") - .HasColumnName("host"); - - b.Property("IsPrimary") - .HasColumnType("boolean") - .HasColumnName("is_primary"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("VerificationToken") - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasColumnName("verification_token"); - - b.Property("VerifiedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("verified_at"); - - b.HasKey("Id") - .HasName("pk_tenant_domains"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_domains_tenant_id_id"); - - b.HasIndex("Host") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_host"); - - b.HasIndex("TenantId", "IsPrimary") - .IsUnique() - .HasDatabaseName("ix_tenant_domains_tenant_id_is_primary") - .HasFilter("is_primary"); - - b.ToTable("tenant_domains", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", 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("LegacyRole") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("legacy_role"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Role") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("role"); - - b.Property("RoleTemplateId") - .HasColumnType("uuid") - .HasColumnName("role_template_id"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.Property("UserId") - .HasColumnType("uuid") - .HasColumnName("user_id"); - - b.HasKey("Id") - .HasName("pk_tenant_memberships"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_memberships_tenant_id_id"); - - b.HasIndex("UserId") - .HasDatabaseName("ix_tenant_memberships_user_id"); - - b.HasIndex("TenantId", "RoleTemplateId") - .HasDatabaseName("ix_tenant_memberships_tenant_id_role_template_id"); - - b.HasIndex("TenantId", "UserId", "Role") - .IsUnique() - .HasDatabaseName("ix_tenant_memberships_tenant_id_user_id_role"); - - b.ToTable("tenant_memberships", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("BaseRole") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("base_role"); - - 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("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("DataScope") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("data_scope") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Description") - .HasColumnType("text") - .HasColumnName("description"); - - b.Property("FieldPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("field_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("IsSystem") - .HasColumnType("boolean") - .HasColumnName("is_system"); - - b.Property("MenuPermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("menu_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("ModulePermissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("module_permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("character varying(200)") - .HasColumnName("name"); - - b.Property("Permissions") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("permissions") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("sort_order"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - 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_tenant_role_templates"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_role_templates_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_role_templates_created_by"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_role_templates_updated_by"); - - b.HasIndex("TenantId", "Code") - .IsUnique() - .HasDatabaseName("ix_tenant_role_templates_tenant_id_code"); - - b.HasIndex("TenantId", "Status", "SortOrder") - .HasDatabaseName("ix_tenant_role_templates_tenant_id_status_sort_order"); - - b.ToTable("tenant_role_templates", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("AdminFeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("admin_feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("FeatureFlags") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("feature_flags") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("PublicConfig") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("public_config") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("UpdatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("updated_at") - .HasDefaultValueSql("now()"); - - b.HasKey("TenantId") - .HasName("pk_tenant_settings"); - - b.ToTable("tenant_settings", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("AssignedToUserId") - .HasColumnType("uuid") - .HasColumnName("assigned_to_user_id"); - - b.Property("ClassId") - .HasColumnType("uuid") - .HasColumnName("class_id"); - - b.Property("CompletedAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("completed_at"); - - b.Property("CompletedBy") - .HasColumnType("uuid") - .HasColumnName("completed_by"); - - 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("DueAt") - .HasColumnType("timestamp with time zone") - .HasColumnName("due_at"); - - b.Property("FollowupType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("followup_type"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("Priority") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("priority"); - - b.Property("Status") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("status"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - b.Property("TenantId") - .HasColumnType("uuid") - .HasColumnName("tenant_id"); - - b.Property("Title") - .IsRequired() - .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.HasKey("Id") - .HasName("pk_tenant_student_followups"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_followups_tenant_id_id"); - - b.HasIndex("AssignedToUserId") - .HasDatabaseName("ix_tenant_student_followups_assigned_to_user_id"); - - b.HasIndex("CompletedBy") - .HasDatabaseName("ix_tenant_student_followups_completed_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_followups_student_user_id"); - - b.HasIndex("TenantId", "AssignedToUserId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_assigned_to_user_id_stat~") - .HasFilter("assigned_to_user_id is not null"); - - b.HasIndex("TenantId", "ClassId", "Status", "DueAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_class_id_status_due_at") - .HasFilter("class_id is not null"); - - b.HasIndex("TenantId", "StudentUserId", "Status", "DueAt", "CreatedAt") - .HasDatabaseName("ix_tenant_student_followups_tenant_id_student_user_id_status_d~"); - - b.ToTable("tenant_student_followups", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid") - .HasColumnName("id") - .HasDefaultValueSql("gen_random_uuid()"); - - b.Property("Content") - .IsRequired() - .HasColumnType("text") - .HasColumnName("content"); - - b.Property("CreatedAt") - .ValueGeneratedOnAdd() - .HasColumnType("timestamp with time zone") - .HasColumnName("created_at") - .HasDefaultValueSql("now()"); - - b.Property("CreatedBy") - .HasColumnType("uuid") - .HasColumnName("created_by"); - - b.Property("IsPinned") - .HasColumnType("boolean") - .HasColumnName("is_pinned"); - - b.Property("Metadata") - .ValueGeneratedOnAdd() - .HasColumnType("jsonb") - .HasColumnName("metadata") - .HasDefaultValueSql("'{}'::jsonb"); - - b.Property("NoteType") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("note_type"); - - b.Property("StudentUserId") - .HasColumnType("uuid") - .HasColumnName("student_user_id"); - - 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_tenant_student_notes"); - - b.HasAlternateKey("TenantId", "Id") - .HasName("ak_tenant_student_notes_tenant_id_id"); - - b.HasIndex("CreatedBy") - .HasDatabaseName("ix_tenant_student_notes_created_by"); - - b.HasIndex("StudentUserId") - .HasDatabaseName("ix_tenant_student_notes_student_user_id"); - - b.HasIndex("UpdatedBy") - .HasDatabaseName("ix_tenant_student_notes_updated_by"); - - b.HasIndex("TenantId", "CreatedBy", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_created_by_created_at") - .HasFilter("created_by is not null"); - - b.HasIndex("TenantId", "StudentUserId", "IsPinned", "CreatedAt") - .HasDatabaseName("ix_tenant_student_notes_tenant_id_student_user_id_is_pinned_cr~"); - - b.ToTable("tenant_student_notes", (string)null); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Category", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_categories_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_categories_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Major", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_majors_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_majors_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.ModuleNode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_module_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_module_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_module_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Region", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_regions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.RegionModule", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_region_modules_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_region_modules_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.School", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_schools_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_schools_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Catalog.Subject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.RegionModule", null) - .WithMany() - .HasForeignKey("TenantId", "ModuleId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_region_modules_tenant_id_module_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.ActivationCode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AgentUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_users_agent_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_activation_codes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UsedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_users_used_by"); - - b.HasOne("Tiku.Domain.Commerce.CodeBatch", null) - .WithMany() - .HasForeignKey("TenantId", "BatchId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_code_batches_tenant_id_batch_id"); - - b.HasOne("Tiku.Domain.Commerce.CouponRedemption", null) - .WithMany() - .HasForeignKey("TenantId", "CouponRedemptionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_coupon_redemptions_tenant_id_coupon_redemp~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "UsedRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_activation_codes_regions_tenant_id_used_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CodeBatch", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_code_batches_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationBatch", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_batches_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_batches_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationIssue", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedTo") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_issues_users_assigned_to"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_issues_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ResolvedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_issues_users_resolved_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_issues_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceReconciliationBatch", null) - .WithMany() - .HasForeignKey("TenantId", "BatchId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_commerce_reconciliation_batc~"); - - b.HasOne("Tiku.Domain.Commerce.CommerceReconciliationItem", null) - .WithMany() - .HasForeignKey("TenantId", "ItemId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_commerce_reconciliation_item~"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_payments_tenant_id_payment_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceRefundRequest", null) - .WithMany() - .HasForeignKey("TenantId", "RefundRequestId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_issues_commerce_refund_requests_ten~"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationIssueEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_reconciliation_issue_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_issue_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceReconciliationIssue", null) - .WithMany() - .HasForeignKey("TenantId", "IssueId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_issue_events_commerce_reconciliatio~"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceReconciliationItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceReconciliationBatch", null) - .WithMany() - .HasForeignKey("TenantId", "BatchId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_reconciliation_items_commerce_reconciliation_batch~"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_items_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_items_payments_tenant_id_payment_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceRefundRequest", null) - .WithMany() - .HasForeignKey("TenantId", "RefundRequestId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_reconciliation_items_commerce_refund_requests_tena~"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceRefundEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_refund_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_refund_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.CommerceRefundRequest", null) - .WithMany() - .HasForeignKey("TenantId", "RefundRequestId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_refund_events_commerce_refund_requests_tenant_id_r~"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CommerceRefundRequest", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ProcessedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_refund_requests_users_processed_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("RequestedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_refund_requests_users_requested_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReviewedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commerce_refund_requests_users_reviewed_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_refund_requests_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commerce_refund_requests_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_commerce_refund_requests_payments_tenant_id_payment_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Coupon", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_coupons_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_coupons_svip_plans_tenant_id_plan_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.CouponRedemption", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_coupon_redemptions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_users_user_id"); - - b.HasOne("Tiku.Domain.Commerce.Coupon", null) - .WithMany() - .HasForeignKey("TenantId", "CouponId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_coupons_tenant_id_coupon_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_orders_tenant_id_order_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_svip_plans_tenant_id_plan_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_coupon_redemptions_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Entitlement", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("RevokedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_entitlements_users_revoked_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_entitlements_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_entitlements_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Order", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_orders_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_orders_users_user_id"); - - b.HasOne("Tiku.Domain.Commerce.SvipPlan", null) - .WithMany() - .HasForeignKey("TenantId", "PlanId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_orders_svip_plans_tenant_id_plan_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_orders_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.OrderItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_order_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_order_items_orders_tenant_id_order_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Payment", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payments_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Order", null) - .WithMany() - .HasForeignKey("TenantId", "OrderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payments_orders_tenant_id_order_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.PaymentEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_payment_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Commerce.Payment", null) - .WithMany() - .HasForeignKey("TenantId", "PaymentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_payment_events_payments_tenant_id_payment_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.Product", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_products_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_products_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.SvipPlan", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_svip_plans_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_svip_plans_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantPaymentAccount", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_payment_accounts_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantSubscription", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_subscriptions_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Commerce.TenantUsageRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_usage_records_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.AiRecommendationReport", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_ai_recommendation_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_ai_recommendation_reports_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_ai_recommendation_reports_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.AppAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_app_assets_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAsset", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_assets_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_updated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("VerifiedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_assets_users_verified_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_assets_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAssetAccessEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_asset_access_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_asset_access_events_users_user_id"); - - b.HasOne("Tiku.Domain.Content.ContentAsset", null) - .WithMany() - .HasForeignKey("TenantId", "AssetId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_asset_access_events_content_assets_tenant_id_asset_~"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentAssetSecurityScanEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_asset_security_scan_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentAsset", null) - .WithMany() - .HasForeignKey("TenantId", "AssetId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_asset_security_scan_events_content_assets_tenant_id~"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentEntry", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_entries_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_entries_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportIssue", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportItem", null) - .WithMany() - .HasForeignKey("TenantId", "ItemId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_import_issues_content_import_items_tenant_id_item_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_issues_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentImportJob", null) - .WithMany() - .HasForeignKey("TenantId", "JobId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_items_content_import_jobs_tenant_id_job_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentImportJob", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_import_jobs_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_import_jobs_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "TargetCategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_categories_tenant_id_target_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "TargetContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_content_nodes_tenant_id_target_content_~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "TargetQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_question_banks_tenant_id_target_questio~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "TargetRegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_regions_tenant_id_target_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_import_jobs_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ContentNode", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_content_nodes_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_content_nodes_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ParentId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_content_nodes_content_nodes_tenant_id_parent_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_content_nodes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookChapter", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_chapters_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_chapters_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.HandbookSubject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_chapters_handbook_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookEntry", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_entries_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.HandbookChapter", null) - .WithMany() - .HasForeignKey("TenantId", "ChapterId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_handbook_entries_handbook_chapters_tenant_id_chapter_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_entries_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.HandbookSubject", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_handbook_subjects_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "MajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_majors_tenant_id_major_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_handbook_subjects_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.ImageAsset", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_images_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.PracticeBlueprint", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_blueprints_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_blueprints_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_question_collections_tenant_id_collecti~"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_blueprints_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionBankGrant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_bank_grants_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("SourceQuestionBankId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_bank_grants_question_banks_source_question_bank_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_bank_grants_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollection", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_collections_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_content_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_question_banks_tenant_id_question_bank~"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_collections_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionCollectionItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_question_collections_tenant_id_co~"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_collection_items_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionTypeGroup", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_type_groups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_type_groups_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.QuestionVideo", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_videos_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.Content.VideoExplanation", null) - .WithMany() - .HasForeignKey("TenantId", "VideoId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_question_videos_video_explanations_tenant_id_video_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.SubjectShare", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SourceSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_source_subject_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "TargetSubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_subject_shares_subjects_tenant_id_target_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.TenantQuestionBankAdoption", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_question_bank_adoptions_users_created_by"); - - b.HasOne("Tiku.Domain.Content.QuestionBankGrant", null) - .WithMany() - .HasForeignKey("GrantId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_question_bank_adoptions_question_bank_grants_grant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("SourceQuestionBankId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_question_bank_adoptions_question_banks_source_questi~"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_question_bank_adoptions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_question_bank_adoptions_users_updated_by"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "TargetCollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_question_bank_adoptions_question_collections_tenant_~"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "TargetEntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_question_bank_adoptions_content_entries_tenant_id_ta~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "TargetQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_question_bank_adoptions_question_banks_tenant_id_tar~"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordFavorite", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_favorites_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.UserWordProgress", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_users_user_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyWord", null) - .WithMany() - .HasForeignKey("TenantId", "WordId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_word_progress_vocabulary_words_tenant_id_word_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VideoExplanation", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_video_explanations_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_video_explanations_subjects_tenant_id_subject_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyUnit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_units_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_units_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Content.VocabularyWord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_vocabulary_words_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Content.VocabularyUnit", null) - .WithMany() - .HasForeignKey("TenantId", "UnitId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_vocabulary_words_vocabulary_units_tenant_id_unit_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlement", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("GeneratedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_generated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("PaidBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_paid_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlements_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReviewedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlements_users_reviewed_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlements_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CommissionSettlementItem", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlement_items_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlement_items_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_commission_settlement_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.CommissionSettlement", null) - .WithMany() - .HasForeignKey("TenantId", "SettlementId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_commission_settlement_items_commission_settlements_tenant_i~"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmConfig", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_config_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookLog", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_webhook_log_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.CrmWebhookQueueItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_crm_webhook_queue_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralCode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_codes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_codes_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralLead", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_assigned_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedToUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_assigned_to_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_leads_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_leads_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.ReferralTrack", null) - .WithMany() - .HasForeignKey("TenantId", "FirstTrackId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_leads_referral_tracks_tenant_id_first_track_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralQrcode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_qrcodes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_qrcodes_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTeamEdge", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("LeaderUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_team_edges_users_leader_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("MemberUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_team_edges_users_member_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_team_edges_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.ReferralTrack", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReferrerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_users_referrer_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("TargetUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_users_target_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_referral_tracks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Growth.ReferralLead", null) - .WithMany() - .HasForeignKey("TenantId", "LeadId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_referral_tracks_referral_leads_tenant_id_lead_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Growth.TenantCommissionSetting", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_commission_settings_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_commission_settings_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.StudentProfile", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_student_profiles_users_user_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.Major", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedMajorId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_majors_tenant_id_selected_major_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SelectedSchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_student_profiles_schools_tenant_id_selected_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Identity.UserIdentity", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_identities_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.AnswerRecord", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_answer_records_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_questions_tenant_id_question_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId", "QuestionVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_question_versions_tenant_id_question_id_ques~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "UserId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "UserId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_answer_records_practice_sessions_tenant_id_user_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.DashboardDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_dashboard_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_dashboard_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ExamDate", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_exam_dates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_regions_tenant_id_region_id"); - - b.HasOne("Tiku.Domain.Catalog.School", null) - .WithMany() - .HasForeignKey("TenantId", "SchoolId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_exam_dates_schools_tenant_id_school_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.FavoriteQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_favorite_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeAccessEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_access_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_users_user_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_practice_access_events_practice_sessions_tenant_id_practice~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeDailyUsage", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_daily_usage_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_sessions_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_question_collections_tenant_id_collection~"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_sessions_content_entries_tenant_id_entry_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReport", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_users_user_id"); - - b.HasOne("Tiku.Domain.Content.PracticeBlueprint", null) - .WithMany() - .HasForeignKey("TenantId", "BlueprintId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_practice_blueprints_tenant_id_blue~"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "CollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_practice_session_reports_question_collections_tenant_id_col~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_reports_practice_sessions_tenant_id_practi~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.PracticeSessionReportSection", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.PracticeSession", null) - .WithMany() - .HasForeignKey("TenantId", "PracticeSessionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_sessions_tenant_i~"); - - b.HasOne("Tiku.Domain.Learning.PracticeSessionReport", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_practice_session_report_sections_practice_session_reports_t~"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RecentPractice", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_recent_practices_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_recent_practices_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.Report", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("HandledBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_handled_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_reports_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_reports_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_reports_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.ReportStatusEvent", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_report_status_events_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Learning.Report", null) - .WithMany() - .HasForeignKey("TenantId", "ReportId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_report_status_events_reports_tenant_id_report_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.RevenueDailyStat", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_revenue_daily_stats_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_revenue_daily_stats_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.UserScoreEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_score_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Learning.WrongQuestion", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_users_user_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_wrong_questions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Announcement", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_announcements_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.AuditLog", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ActorUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_audit_logs_users_actor_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_audit_logs_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Badge", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_badges_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Banner", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_banners_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_banners_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.Faq", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_faqs_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_faqs_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantContentNotification", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_content_notifications_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReadBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_content_notifications_users_read_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_content_notifications_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "SourceQuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_tenant_content_notifications_question_banks_tenant_id_sourc~"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.TenantThemeConfig", b => - { - b.HasOne("Tiku.Domain.Operations.TenantThemeTemplate", null) - .WithMany() - .HasForeignKey("ActiveTemplateCode") - .HasPrincipalKey("Code") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_tenant_theme_templates_active_template~"); - - b.HasOne("Tiku.Domain.Operations.TenantThemeTemplate", null) - .WithMany() - .HasForeignKey("DraftTemplateCode") - .HasPrincipalKey("Code") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_tenant_theme_templates_draft_template_~"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("DraftUpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_users_draft_updated_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("PublishedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_theme_configs_users_published_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_theme_configs_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserBadge", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("GrantedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_user_badges_users_granted_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_badges_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_user_badges_users_user_id"); - - b.HasOne("Tiku.Domain.Operations.Badge", null) - .WithMany() - .HasForeignKey("TenantId", "BadgeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_user_badges_badges_tenant_id_badge_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Operations.UserNotification", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_user_notifications_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_notifications_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_user_notifications_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.PlatformAuditAlert", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AcknowledgedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_platform_audit_alerts_users_acknowledged_by"); - - b.HasOne("Tiku.Domain.Operations.AuditLog", null) - .WithMany() - .HasForeignKey("AuditLogId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_platform_audit_alerts_audit_logs_audit_log_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ResolvedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_platform_audit_alerts_users_resolved_by"); - - b.HasOne("Tiku.Domain.Platform.PlatformAuditAlertRule", null) - .WithMany() - .HasForeignKey("RuleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_platform_audit_alerts_platform_audit_alert_rules_rule_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_platform_audit_alerts_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.PlatformAuditAlertRule", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .HasConstraintName("fk_platform_audit_alert_rules_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.PlatformDunningNotificationEvent", b => - { - b.HasOne("Tiku.Domain.Platform.PlatformDunningNotificationChannel", null) - .WithMany() - .HasForeignKey("ChannelId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_platform_dunning_notification_events_platform_dunning_notif~"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_platform_dunning_notification_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Platform.TenantInvoice", null) - .WithMany() - .HasForeignKey("TenantId", "InvoiceId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_platform_dunning_notification_events_tenant_invoices_tenant~"); - - b.HasOne("Tiku.Domain.Platform.TenantInvoiceReminder", null) - .WithMany() - .HasForeignKey("TenantId", "ReminderId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_platform_dunning_notification_events_tenant_invoice_reminde~"); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.TenantBillingProfile", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Platform.TenantBillingProfile", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_billing_profiles_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.TenantInvoice", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_invoices_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_invoices_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.TenantInvoiceItem", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_invoice_items_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Platform.TenantInvoice", null) - .WithMany() - .HasForeignKey("TenantId", "InvoiceId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_invoice_items_tenant_invoices_tenant_id_invoice_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.TenantInvoicePayment", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("ReceivedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_invoice_payments_users_received_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_invoice_payments_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Platform.TenantInvoice", null) - .WithMany() - .HasForeignKey("TenantId", "InvoiceId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_invoice_payments_tenant_invoices_tenant_id_invoice_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Platform.TenantInvoiceReminder", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_invoice_reminders_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_invoice_reminders_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Platform.TenantInvoice", null) - .WithMany() - .HasForeignKey("TenantId", "InvoiceId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_invoice_reminders_tenant_invoices_tenant_id_invoice_~"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.Question", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_questions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Category", null) - .WithMany() - .HasForeignKey("TenantId", "CategoryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_categories_tenant_id_category_id"); - - b.HasOne("Tiku.Domain.Content.ContentNode", null) - .WithMany() - .HasForeignKey("TenantId", "ContentNodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_nodes_tenant_id_content_node_id"); - - b.HasOne("Tiku.Domain.Content.ContentEntry", null) - .WithMany() - .HasForeignKey("TenantId", "EntryId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_content_entries_tenant_id_entry_id"); - - b.HasOne("Tiku.Domain.Catalog.ModuleNode", null) - .WithMany() - .HasForeignKey("TenantId", "NodeId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_module_nodes_tenant_id_node_id"); - - b.HasOne("Tiku.Domain.Content.QuestionCollection", null) - .WithMany() - .HasForeignKey("TenantId", "PrimaryCollectionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_collections_tenant_id_primary_collection~"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionBank", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionBankId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_banks_tenant_id_question_bank_id"); - - b.HasOne("Tiku.Domain.Catalog.Subject", null) - .WithMany() - .HasForeignKey("TenantId", "SubjectId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_subjects_tenant_id_subject_id"); - - b.HasOne("Tiku.Domain.QuestionBanks.QuestionVersion", null) - .WithMany() - .HasForeignKey("TenantId", "Id", "CurrentVersionId") - .HasPrincipalKey("TenantId", "QuestionId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_questions_question_versions_tenant_id_id_current_version_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionBank", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_banks_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_question_banks_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.QuestionBanks.QuestionVersion", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_question_versions_users_created_by"); - - b.HasOne("Tiku.Domain.QuestionBanks.Question", null) - .WithMany() - .HasForeignKey("TenantId", "QuestionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_question_versions_questions_tenant_id_question_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthLoginEvent", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_login_events_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_auth_login_events_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.AuthSession", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_auth_sessions_users_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsSendRateLimit", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_send_rate_limits_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.SmsVerificationCode", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_sms_verification_codes_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.Tenant", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("OwnerUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenants_users_owner_user_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantAuthProvider", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_auth_providers_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantBranding", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantBranding", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_branding_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClass", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_classes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_classes_users_updated_by"); - - b.HasOne("Tiku.Domain.Catalog.Region", null) - .WithMany() - .HasForeignKey("TenantId", "RegionId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_classes_regions_tenant_id_region_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantClassMember", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_class_members_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantDomain", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_domains_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantMembership", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_memberships_users_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantRoleTemplate", null) - .WithMany() - .HasForeignKey("TenantId", "RoleTemplateId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.Restrict) - .HasConstraintName("fk_tenant_memberships_tenant_role_templates_tenant_id_role_tem~"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantRoleTemplate", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_created_by"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_role_templates_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_role_templates_users_updated_by"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantSettings", b => - { - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithOne() - .HasForeignKey("Tiku.Domain.Tenancy.TenantSettings", "TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_settings_tenants_tenant_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentFollowup", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("AssignedToUserId") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_assigned_to_user_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CompletedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_users_completed_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_followups_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Tenancy.TenantClass", null) - .WithMany() - .HasForeignKey("TenantId", "ClassId") - .HasPrincipalKey("TenantId", "Id") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_followups_tenant_classes_tenant_id_class_id"); - }); - - modelBuilder.Entity("Tiku.Domain.Tenancy.TenantStudentNote", b => - { - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("CreatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_created_by"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("StudentUserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_users_student_user_id"); - - b.HasOne("Tiku.Domain.Tenancy.Tenant", null) - .WithMany() - .HasForeignKey("TenantId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("fk_tenant_student_notes_tenants_tenant_id"); - - b.HasOne("Tiku.Domain.Identity.User", null) - .WithMany() - .HasForeignKey("UpdatedBy") - .OnDelete(DeleteBehavior.SetNull) - .HasConstraintName("fk_tenant_student_notes_users_updated_by"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725220206_AddPlatformBillingDunningAndAuditPersistence.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725220206_AddPlatformBillingDunningAndAuditPersistence.cs deleted file mode 100644 index 8d50bdb..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725220206_AddPlatformBillingDunningAndAuditPersistence.cs +++ /dev/null @@ -1,633 +0,0 @@ -using System; -using System.Text.Json; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Tiku.Infrastructure.Persistence.Migrations -{ - /// - public partial class AddPlatformBillingDunningAndAuditPersistence : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "platform_audit_alert_rules", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: true), - code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - description = table.Column(type: "text", nullable: true), - enabled = table.Column(type: "boolean", nullable: false), - severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - action_patterns = table.Column(type: "text[]", nullable: false, defaultValueSql: "'{}'::text[]"), - target_types = table.Column(type: "text[]", nullable: false, defaultValueSql: "'{}'::text[]"), - conditions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_platform_audit_alert_rules", x => x.id); - table.ForeignKey( - name: "fk_platform_audit_alert_rules_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "platform_dunning_notification_channels", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - channel_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - description = table.Column(type: "text", nullable: true), - enabled = table.Column(type: "boolean", nullable: false), - provider = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - webhook_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: false), - secret_ref = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - reminder_types = table.Column(type: "text[]", nullable: false, defaultValueSql: "array['overdue', 'final_notice']::text[]"), - reminder_channels = table.Column(type: "text[]", nullable: false, defaultValueSql: "array['internal']::text[]"), - min_reminder_level = table.Column(type: "integer", nullable: false), - tenant_ids = table.Column(type: "uuid[]", nullable: false, defaultValueSql: "'{}'::uuid[]"), - timeout_seconds = table.Column(type: "integer", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_platform_dunning_notification_channels", x => x.id); - table.CheckConstraint("ck_platform_dunning_channels_level", "min_reminder_level between 1 and 20"); - table.CheckConstraint("ck_platform_dunning_channels_timeout", "timeout_seconds between 1 and 60"); - }); - - migrationBuilder.CreateTable( - name: "platform_saas_plans", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - description = table.Column(type: "text", nullable: true), - billing_cycle = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - base_amount_cents = table.Column(type: "integer", nullable: false), - currency = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), - included_quotas = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - overage_prices = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - feature_flags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - sort_order = table.Column(type: "integer", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_platform_saas_plans", x => x.id); - table.CheckConstraint("ck_platform_saas_plans_amount", "base_amount_cents >= 0"); - }); - - migrationBuilder.CreateTable( - name: "tenant_billing_profiles", - columns: table => new - { - tenant_id = table.Column(type: "uuid", nullable: false), - billing_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - tax_id = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - contact_name = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - contact_phone = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - contact_email = table.Column(type: "citext", maxLength: 300, nullable: true), - billing_address = table.Column(type: "text", nullable: true), - invoice_title = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), - invoice_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - bank_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - bank_account_masked = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_billing_profiles", x => x.tenant_id); - table.ForeignKey( - name: "fk_tenant_billing_profiles_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_invoices", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - created_by = table.Column(type: "uuid", nullable: true), - invoice_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - invoice_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - currency = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), - subtotal_cents = table.Column(type: "integer", nullable: false), - discount_cents = table.Column(type: "integer", nullable: false), - tax_cents = table.Column(type: "integer", nullable: false), - total_cents = table.Column(type: "integer", nullable: false), - paid_cents = table.Column(type: "integer", nullable: false), - balance_cents = table.Column(type: "integer", nullable: false), - billing_period_start = table.Column(type: "date", nullable: true), - billing_period_end = table.Column(type: "date", nullable: true), - due_date = table.Column(type: "date", nullable: true), - issued_at = table.Column(type: "timestamp with time zone", nullable: true), - paid_at = table.Column(type: "timestamp with time zone", nullable: true), - note = table.Column(type: "text", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_invoices", x => x.id); - table.UniqueConstraint("ak_tenant_invoices_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_tenant_invoices_amounts", "subtotal_cents >= 0 and discount_cents >= 0 and tax_cents >= 0 and total_cents >= 0 and paid_cents >= 0 and balance_cents >= 0"); - table.CheckConstraint("ck_tenant_invoices_period", "billing_period_end is null or billing_period_start is null or billing_period_end >= billing_period_start"); - table.ForeignKey( - name: "fk_tenant_invoices_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_invoices_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "platform_audit_alerts", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - rule_id = table.Column(type: "uuid", nullable: false), - audit_log_id = table.Column(type: "uuid", nullable: false), - tenant_id = table.Column(type: "uuid", nullable: true), - acknowledged_by = table.Column(type: "uuid", nullable: true), - resolved_by = table.Column(type: "uuid", nullable: true), - severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - action = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), - target_type = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - target_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - title = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), - summary = table.Column(type: "text", nullable: true), - details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - first_seen_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - last_seen_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - acknowledged_at = table.Column(type: "timestamp with time zone", nullable: true), - resolved_at = table.Column(type: "timestamp with time zone", nullable: true), - resolution_note = table.Column(type: "text", nullable: true), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_platform_audit_alerts", x => x.id); - table.ForeignKey( - name: "fk_platform_audit_alerts_audit_logs_audit_log_id", - column: x => x.audit_log_id, - principalTable: "audit_logs", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_platform_audit_alerts_platform_audit_alert_rules_rule_id", - column: x => x.rule_id, - principalTable: "platform_audit_alert_rules", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_platform_audit_alerts_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_platform_audit_alerts_users_acknowledged_by", - column: x => x.acknowledged_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - table.ForeignKey( - name: "fk_platform_audit_alerts_users_resolved_by", - column: x => x.resolved_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "tenant_invoice_items", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - invoice_id = table.Column(type: "uuid", nullable: false), - item_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - item_ref_id = table.Column(type: "uuid", nullable: true), - description = table.Column(type: "character varying(500)", maxLength: 500, nullable: false), - quantity = table.Column(type: "numeric(12,2)", precision: 12, scale: 2, nullable: false), - unit_amount_cents = table.Column(type: "integer", nullable: false), - amount_cents = table.Column(type: "integer", nullable: false), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_invoice_items", x => x.id); - table.UniqueConstraint("ak_tenant_invoice_items_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_tenant_invoice_items_amounts", "unit_amount_cents >= 0 and amount_cents >= 0"); - table.CheckConstraint("ck_tenant_invoice_items_quantity", "quantity > 0"); - table.ForeignKey( - name: "fk_tenant_invoice_items_tenant_invoices_tenant_id_invoice_id", - columns: x => new { x.tenant_id, x.invoice_id }, - principalTable: "tenant_invoices", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_invoice_items_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "tenant_invoice_payments", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - invoice_id = table.Column(type: "uuid", nullable: false), - received_by = table.Column(type: "uuid", nullable: true), - payment_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - method = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - amount_cents = table.Column(type: "integer", nullable: false), - paid_at = table.Column(type: "timestamp with time zone", nullable: true), - provider_trade_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), - raw_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_invoice_payments", x => x.id); - table.UniqueConstraint("ak_tenant_invoice_payments_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_tenant_invoice_payments_amount", "amount_cents >= 0"); - table.ForeignKey( - name: "fk_tenant_invoice_payments_tenant_invoices_tenant_id_invoice_id", - columns: x => new { x.tenant_id, x.invoice_id }, - principalTable: "tenant_invoices", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_invoice_payments_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_invoice_payments_users_received_by", - column: x => x.received_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "tenant_invoice_reminders", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - invoice_id = table.Column(type: "uuid", nullable: false), - created_by = table.Column(type: "uuid", nullable: true), - reminder_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - channel = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - reminder_date = table.Column(type: "date", nullable: false), - reminder_level = table.Column(type: "integer", nullable: false), - due_date = table.Column(type: "date", nullable: true), - balance_cents_snapshot = table.Column(type: "integer", nullable: false), - message = table.Column(type: "text", nullable: true), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - sent_at = table.Column(type: "timestamp with time zone", nullable: true), - acknowledged_at = table.Column(type: "timestamp with time zone", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_tenant_invoice_reminders", x => x.id); - table.UniqueConstraint("ak_tenant_invoice_reminders_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_tenant_invoice_reminders_balance", "balance_cents_snapshot >= 0"); - table.CheckConstraint("ck_tenant_invoice_reminders_level", "reminder_level between 1 and 20"); - table.ForeignKey( - name: "fk_tenant_invoice_reminders_tenant_invoices_tenant_id_invoice_~", - columns: x => new { x.tenant_id, x.invoice_id }, - principalTable: "tenant_invoices", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_invoice_reminders_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_tenant_invoice_reminders_users_created_by", - column: x => x.created_by, - principalTable: "users", - principalColumn: "id", - onDelete: ReferentialAction.SetNull); - }); - - migrationBuilder.CreateTable( - name: "platform_dunning_notification_events", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - channel_id = table.Column(type: "uuid", nullable: false), - reminder_id = table.Column(type: "uuid", nullable: false), - invoice_id = table.Column(type: "uuid", nullable: false), - provider = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - attempts = table.Column(type: "integer", nullable: false), - scheduled_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - next_attempt_at = table.Column(type: "timestamp with time zone", nullable: true), - last_attempt_at = table.Column(type: "timestamp with time zone", nullable: true), - sent_at = table.Column(type: "timestamp with time zone", nullable: true), - last_error = table.Column(type: "text", nullable: true), - last_http_code = table.Column(type: "integer", nullable: true), - last_response_summary = table.Column(type: "text", nullable: true), - request_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - tenant_id = table.Column(type: "uuid", nullable: false), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_platform_dunning_notification_events", x => x.id); - table.UniqueConstraint("ak_platform_dunning_notification_events_tenant_id_id", x => new { x.tenant_id, x.id }); - table.CheckConstraint("ck_platform_dunning_events_attempts", "attempts >= 0"); - table.ForeignKey( - name: "fk_platform_dunning_notification_events_platform_dunning_notif~", - column: x => x.channel_id, - principalTable: "platform_dunning_notification_channels", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_platform_dunning_notification_events_tenant_invoice_reminde~", - columns: x => new { x.tenant_id, x.reminder_id }, - principalTable: "tenant_invoice_reminders", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_platform_dunning_notification_events_tenant_invoices_tenant~", - columns: x => new { x.tenant_id, x.invoice_id }, - principalTable: "tenant_invoices", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_platform_dunning_notification_events_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "ix_platform_audit_alert_rules_code", - table: "platform_audit_alert_rules", - column: "code", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_platform_audit_alert_rules_enabled_severity_code", - table: "platform_audit_alert_rules", - columns: new[] { "enabled", "severity", "code" }); - - migrationBuilder.CreateIndex( - name: "ix_platform_audit_alert_rules_tenant_id", - table: "platform_audit_alert_rules", - column: "tenant_id"); - - migrationBuilder.CreateIndex( - name: "ix_platform_audit_alerts_acknowledged_by", - table: "platform_audit_alerts", - column: "acknowledged_by"); - - migrationBuilder.CreateIndex( - name: "ix_platform_audit_alerts_audit_log_id", - table: "platform_audit_alerts", - column: "audit_log_id"); - - migrationBuilder.CreateIndex( - name: "ix_platform_audit_alerts_resolved_by", - table: "platform_audit_alerts", - column: "resolved_by"); - - migrationBuilder.CreateIndex( - name: "ix_platform_audit_alerts_rule_id_audit_log_id", - table: "platform_audit_alerts", - columns: new[] { "rule_id", "audit_log_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_platform_audit_alerts_status_severity_created_at", - table: "platform_audit_alerts", - columns: new[] { "status", "severity", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_platform_audit_alerts_tenant_id_status_created_at", - table: "platform_audit_alerts", - columns: new[] { "tenant_id", "status", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_platform_dunning_notification_channels_channel_code", - table: "platform_dunning_notification_channels", - column: "channel_code", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_platform_dunning_notification_channels_enabled_min_reminder~", - table: "platform_dunning_notification_channels", - columns: new[] { "enabled", "min_reminder_level", "channel_code" }); - - migrationBuilder.CreateIndex( - name: "ix_platform_dunning_notification_events_channel_id_reminder_id", - table: "platform_dunning_notification_events", - columns: new[] { "channel_id", "reminder_id" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_platform_dunning_notification_events_invoice_id_status_crea~", - table: "platform_dunning_notification_events", - columns: new[] { "invoice_id", "status", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_platform_dunning_notification_events_reminder_id_status_cre~", - table: "platform_dunning_notification_events", - columns: new[] { "reminder_id", "status", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_platform_dunning_notification_events_status_next_attempt_at~", - table: "platform_dunning_notification_events", - columns: new[] { "status", "next_attempt_at", "scheduled_at", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_platform_dunning_notification_events_tenant_id_invoice_id", - table: "platform_dunning_notification_events", - columns: new[] { "tenant_id", "invoice_id" }); - - migrationBuilder.CreateIndex( - name: "ix_platform_dunning_notification_events_tenant_id_reminder_id", - table: "platform_dunning_notification_events", - columns: new[] { "tenant_id", "reminder_id" }); - - migrationBuilder.CreateIndex( - name: "ix_platform_dunning_notification_events_tenant_id_status_creat~", - table: "platform_dunning_notification_events", - columns: new[] { "tenant_id", "status", "created_at" }); - - migrationBuilder.CreateIndex( - name: "ix_platform_saas_plans_code", - table: "platform_saas_plans", - column: "code", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_platform_saas_plans_status_sort_order", - table: "platform_saas_plans", - columns: new[] { "status", "sort_order" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoice_items_invoice_id", - table: "tenant_invoice_items", - column: "invoice_id"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoice_items_tenant_id_invoice_id", - table: "tenant_invoice_items", - columns: new[] { "tenant_id", "invoice_id" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoice_payments_invoice_id_status", - table: "tenant_invoice_payments", - columns: new[] { "invoice_id", "status" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoice_payments_payment_no", - table: "tenant_invoice_payments", - column: "payment_no", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoice_payments_received_by", - table: "tenant_invoice_payments", - column: "received_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoice_payments_tenant_id_invoice_id", - table: "tenant_invoice_payments", - columns: new[] { "tenant_id", "invoice_id" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoice_reminders_created_by", - table: "tenant_invoice_reminders", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoice_reminders_invoice_id_reminder_date", - table: "tenant_invoice_reminders", - columns: new[] { "invoice_id", "reminder_date" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoice_reminders_tenant_id_invoice_id_reminder_type~", - table: "tenant_invoice_reminders", - columns: new[] { "tenant_id", "invoice_id", "reminder_type", "channel", "reminder_date" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoice_reminders_tenant_id_status_reminder_date", - table: "tenant_invoice_reminders", - columns: new[] { "tenant_id", "status", "reminder_date" }); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoices_created_by", - table: "tenant_invoices", - column: "created_by"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoices_invoice_no", - table: "tenant_invoices", - column: "invoice_no", - unique: true); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoices_tenant_id_billing_period_start_billing_peri~", - table: "tenant_invoices", - columns: new[] { "tenant_id", "billing_period_start", "billing_period_end" }, - unique: true, - filter: "invoice_type = 'usage_overage' and status <> 'void' and metadata->>'source' = 'usage_overage_auto'"); - - migrationBuilder.CreateIndex( - name: "ix_tenant_invoices_tenant_id_status_due_date", - table: "tenant_invoices", - columns: new[] { "tenant_id", "status", "due_date" }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "platform_audit_alerts"); - - migrationBuilder.DropTable( - name: "platform_dunning_notification_events"); - - migrationBuilder.DropTable( - name: "platform_saas_plans"); - - migrationBuilder.DropTable( - name: "tenant_billing_profiles"); - - migrationBuilder.DropTable( - name: "tenant_invoice_items"); - - migrationBuilder.DropTable( - name: "tenant_invoice_payments"); - - migrationBuilder.DropTable( - name: "platform_audit_alert_rules"); - - migrationBuilder.DropTable( - name: "platform_dunning_notification_channels"); - - migrationBuilder.DropTable( - name: "tenant_invoice_reminders"); - - migrationBuilder.DropTable( - name: "tenant_invoices"); - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725220429_AddPocketBaseImportAuditPersistence.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725220429_AddPocketBaseImportAuditPersistence.cs deleted file mode 100644 index d69691b..0000000 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725220429_AddPocketBaseImportAuditPersistence.cs +++ /dev/null @@ -1,148 +0,0 @@ -using System; -using System.Text.Json; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Tiku.Infrastructure.Persistence.Migrations -{ - /// - public partial class AddPocketBaseImportAuditPersistence : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "pb_import_runs", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - tenant_id = table.Column(type: "uuid", nullable: false), - source_name = table.Column(type: "character varying(500)", maxLength: 500, nullable: false), - source_kind = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - stats = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - started_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), - finished_at = table.Column(type: "timestamp with time zone", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("pk_pb_import_runs", x => x.id); - table.UniqueConstraint("ak_pb_import_runs_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_pb_import_runs_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "pb_import_issues", - columns: table => new - { - id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), - run_id = table.Column(type: "uuid", nullable: true), - tenant_id = table.Column(type: "uuid", nullable: false), - collection_name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - legacy_id = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), - severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - issue_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - message = table.Column(type: "text", nullable: false), - field_path = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), - raw_value_sample = table.Column(type: "character varying(2000)", maxLength: 2000, nullable: true), - created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_pb_import_issues", x => x.id); - table.UniqueConstraint("ak_pb_import_issues_tenant_id_id", x => new { x.tenant_id, x.id }); - table.ForeignKey( - name: "fk_pb_import_issues_pb_import_runs_tenant_id_run_id", - columns: x => new { x.tenant_id, x.run_id }, - principalTable: "pb_import_runs", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_pb_import_issues_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "pb_raw_records", - columns: table => new - { - run_id = table.Column(type: "uuid", nullable: false), - collection_name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - legacy_id = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), - tenant_id = table.Column(type: "uuid", nullable: false), - record = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), - normalized = table.Column(type: "boolean", nullable: false), - errors = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), - imported_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") - }, - constraints: table => - { - table.PrimaryKey("pk_pb_raw_records", x => new { x.run_id, x.collection_name, x.legacy_id }); - table.ForeignKey( - name: "fk_pb_raw_records_pb_import_runs_tenant_id_run_id", - columns: x => new { x.tenant_id, x.run_id }, - principalTable: "pb_import_runs", - principalColumns: new[] { "tenant_id", "id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "fk_pb_raw_records_tenants_tenant_id", - column: x => x.tenant_id, - principalTable: "tenants", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "ix_pb_import_issues_run_id_severity_collection_name", - table: "pb_import_issues", - columns: new[] { "run_id", "severity", "collection_name" }); - - migrationBuilder.CreateIndex( - name: "ix_pb_import_issues_tenant_id_collection_name_legacy_id", - table: "pb_import_issues", - columns: new[] { "tenant_id", "collection_name", "legacy_id" }); - - migrationBuilder.CreateIndex( - name: "ix_pb_import_issues_tenant_id_run_id", - table: "pb_import_issues", - columns: new[] { "tenant_id", "run_id" }); - - migrationBuilder.CreateIndex( - name: "ix_pb_import_runs_tenant_id_status_started_at", - table: "pb_import_runs", - columns: new[] { "tenant_id", "status", "started_at" }); - - migrationBuilder.CreateIndex( - name: "ix_pb_raw_records_tenant_id_collection_name_legacy_id", - table: "pb_raw_records", - columns: new[] { "tenant_id", "collection_name", "legacy_id" }); - - migrationBuilder.CreateIndex( - name: "ix_pb_raw_records_tenant_id_run_id", - table: "pb_raw_records", - columns: new[] { "tenant_id", "run_id" }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "pb_import_issues"); - - migrationBuilder.DropTable( - name: "pb_raw_records"); - - migrationBuilder.DropTable( - name: "pb_import_runs"); - } - } -} diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725220429_AddPocketBaseImportAuditPersistence.Designer.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725220742_InitialSchema.Designer.cs similarity index 99% rename from Tiku.Infrastructure/Persistence/Migrations/20260725220429_AddPocketBaseImportAuditPersistence.Designer.cs rename to Tiku.Infrastructure/Persistence/Migrations/20260725220742_InitialSchema.Designer.cs index 27f712d..86cd65d 100644 --- a/Tiku.Infrastructure/Persistence/Migrations/20260725220429_AddPocketBaseImportAuditPersistence.Designer.cs +++ b/Tiku.Infrastructure/Persistence/Migrations/20260725220742_InitialSchema.Designer.cs @@ -13,8 +13,8 @@ using Tiku.Infrastructure.Persistence; namespace Tiku.Infrastructure.Persistence.Migrations { [DbContext(typeof(TikuDbContext))] - [Migration("20260725220429_AddPocketBaseImportAuditPersistence")] - partial class AddPocketBaseImportAuditPersistence + [Migration("20260725220742_InitialSchema")] + partial class InitialSchema { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/Tiku.Infrastructure/Persistence/Migrations/20260725220742_InitialSchema.cs b/Tiku.Infrastructure/Persistence/Migrations/20260725220742_InitialSchema.cs new file mode 100644 index 0000000..cfb7a65 --- /dev/null +++ b/Tiku.Infrastructure/Persistence/Migrations/20260725220742_InitialSchema.cs @@ -0,0 +1,8531 @@ +using System; +using System.Text.Json; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Tiku.Infrastructure.Persistence.Migrations +{ + /// + public partial class InitialSchema : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterDatabase() + .Annotation("Npgsql:PostgresExtension:citext", ",,") + .Annotation("Npgsql:PostgresExtension:ltree", ",,"); + + migrationBuilder.CreateTable( + name: "platform_dunning_notification_channels", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + channel_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + description = table.Column(type: "text", nullable: true), + enabled = table.Column(type: "boolean", nullable: false), + provider = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + webhook_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: false), + secret_ref = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + reminder_types = table.Column(type: "text[]", nullable: false, defaultValueSql: "array['overdue', 'final_notice']::text[]"), + reminder_channels = table.Column(type: "text[]", nullable: false, defaultValueSql: "array['internal']::text[]"), + min_reminder_level = table.Column(type: "integer", nullable: false), + tenant_ids = table.Column(type: "uuid[]", nullable: false, defaultValueSql: "'{}'::uuid[]"), + timeout_seconds = table.Column(type: "integer", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_platform_dunning_notification_channels", x => x.id); + table.CheckConstraint("ck_platform_dunning_channels_level", "min_reminder_level between 1 and 20"); + table.CheckConstraint("ck_platform_dunning_channels_timeout", "timeout_seconds between 1 and 60"); + }); + + migrationBuilder.CreateTable( + name: "platform_saas_plans", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + description = table.Column(type: "text", nullable: true), + billing_cycle = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + base_amount_cents = table.Column(type: "integer", nullable: false), + currency = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), + included_quotas = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + overage_prices = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + feature_flags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + sort_order = table.Column(type: "integer", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_platform_saas_plans", x => x.id); + table.CheckConstraint("ck_platform_saas_plans_amount", "base_amount_cents >= 0"); + }); + + migrationBuilder.CreateTable( + name: "tenant_theme_templates", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + description = table.Column(type: "text", nullable: true), + preview_image_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + theme = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + public_assets = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + sort_order = table.Column(type: "integer", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_theme_templates", x => x.id); + table.UniqueConstraint("ak_tenant_theme_templates_code", x => x.code); + }); + + migrationBuilder.CreateTable( + name: "users", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + username = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + email = table.Column(type: "citext", maxLength: 320, nullable: true), + phone = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + avatar_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + primary_role = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + score = table.Column(type: "integer", nullable: false), + last_seen_at = table.Column(type: "timestamp with time zone", nullable: true), + legacy_password_hash = table.Column(type: "character varying(512)", maxLength: 512, nullable: true), + password_migration_required = table.Column(type: "boolean", nullable: false), + raw_profile = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_users", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "tenants", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + slug = table.Column(type: "citext", maxLength: 100, nullable: false), + name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + legal_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + billing_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + owner_user_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenants", x => x.id); + table.ForeignKey( + name: "fk_tenants_users_owner_user_id", + column: x => x.owner_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "user_identities", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: false), + provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + provider_subject = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), + union_id = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), + open_id = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), + phone = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + email = table.Column(type: "citext", maxLength: 320, nullable: true), + secret_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_user_identities", x => x.id); + table.ForeignKey( + name: "fk_user_identities_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "announcements", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + content = table.Column(type: "text", nullable: true), + link = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + background_color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_announcements", x => x.id); + table.UniqueConstraint("ak_announcements_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_announcements_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "app_assets", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + asset_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + file_name = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), + description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_app_assets", x => x.id); + table.UniqueConstraint("ak_app_assets_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_app_assets_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "audit_logs", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: true), + actor_user_id = table.Column(type: "uuid", nullable: true), + action = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + target_type = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + target_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + ip_address = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + user_agent = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: true), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_audit_logs", x => x.id); + table.ForeignKey( + name: "fk_audit_logs_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_audit_logs_users_actor_user_id", + column: x => x.actor_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "auth_login_events", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + user_id = table.Column(type: "uuid", nullable: true), + provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + identifier = table.Column(type: "character varying(320)", maxLength: 320, nullable: true), + result = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + failure_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + ip_address = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + user_agent = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_auth_login_events", x => x.id); + table.UniqueConstraint("ak_auth_login_events_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_auth_login_events_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_auth_login_events_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "auth_sessions", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: false), + token_hash = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), + provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + expires_at = table.Column(type: "timestamp with time zone", nullable: false), + revoked_at = table.Column(type: "timestamp with time zone", nullable: true), + ip_address = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + user_agent = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_auth_sessions", x => x.id); + table.UniqueConstraint("ak_auth_sessions_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_auth_sessions_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_auth_sessions_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "badges", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + description = table.Column(type: "text", nullable: true), + category = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + icon_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + level = table.Column(type: "integer", nullable: true), + unlock_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + condition_field = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + condition_operator = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + condition_value = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: true), + condition_extra = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_badges", x => x.id); + table.UniqueConstraint("ak_badges_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_badges_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "code_batches", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + created_by = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + sale_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + channel = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + campaign_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + default_unit_price_cents = table.Column(type: "integer", nullable: false), + cost_price_cents = table.Column(type: "integer", nullable: false), + total_count = table.Column(type: "integer", nullable: false), + days = table.Column(type: "integer", nullable: true), + legacy_region_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + issued_at = table.Column(type: "timestamp with time zone", nullable: true), + remark = table.Column(type: "text", nullable: true), + commission_rate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_code_batches", x => x.id); + table.UniqueConstraint("ak_code_batches_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_code_batches_amounts", "default_unit_price_cents >= 0 and cost_price_cents >= 0"); + table.CheckConstraint("ck_code_batches_counts", "total_count >= 0"); + table.ForeignKey( + name: "fk_code_batches_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "commerce_reconciliation_batches", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + created_by = table.Column(type: "uuid", nullable: true), + provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + bill_date = table.Column(type: "date", nullable: false), + bill_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + source = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + source_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + source_hash = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + total_count = table.Column(type: "integer", nullable: false), + matched_count = table.Column(type: "integer", nullable: false), + mismatch_count = table.Column(type: "integer", nullable: false), + missing_local_count = table.Column(type: "integer", nullable: false), + missing_provider_count = table.Column(type: "integer", nullable: false), + duplicate_count = table.Column(type: "integer", nullable: false), + ignored_count = table.Column(type: "integer", nullable: false), + amount_cents = table.Column(type: "integer", nullable: false), + refund_amount_cents = table.Column(type: "integer", nullable: false), + fee_cents = table.Column(type: "integer", nullable: false), + completed_at = table.Column(type: "timestamp with time zone", nullable: true), + error = table.Column(type: "text", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_commerce_reconciliation_batches", x => x.id); + table.UniqueConstraint("ak_commerce_reconciliation_batches_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_commerce_reconciliation_batches_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); + table.CheckConstraint("ck_commerce_reconciliation_batches_counts", "total_count >= 0 and matched_count >= 0 and mismatch_count >= 0 and missing_local_count >= 0 and missing_provider_count >= 0 and duplicate_count >= 0 and ignored_count >= 0"); + table.ForeignKey( + name: "fk_commerce_reconciliation_batches_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_commerce_reconciliation_batches_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "commission_settlements", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + referrer_user_id = table.Column(type: "uuid", nullable: false), + generated_by = table.Column(type: "uuid", nullable: true), + reviewed_by = table.Column(type: "uuid", nullable: true), + paid_by = table.Column(type: "uuid", nullable: true), + settlement_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + period_start = table.Column(type: "date", nullable: false), + period_end = table.Column(type: "date", nullable: false), + source_count = table.Column(type: "integer", nullable: false), + paid_user_count = table.Column(type: "integer", nullable: false), + gross_amount_cents = table.Column(type: "integer", nullable: false), + commission_amount_cents = table.Column(type: "integer", nullable: false), + default_rate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), + effective_rate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: true), + reviewed_at = table.Column(type: "timestamp with time zone", nullable: true), + paid_at = table.Column(type: "timestamp with time zone", nullable: true), + payment_method = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + payment_account = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + remark = table.Column(type: "text", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_commission_settlements", x => x.id); + table.UniqueConstraint("ak_commission_settlements_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_commission_settlements_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); + table.CheckConstraint("ck_commission_settlements_counts", "source_count >= 0 and paid_user_count >= 0"); + table.CheckConstraint("ck_commission_settlements_period", "period_end >= period_start"); + table.CheckConstraint("ck_commission_settlements_rates", "default_rate >= 0 and default_rate <= 1 and (effective_rate is null or (effective_rate >= 0 and effective_rate <= 1))"); + table.ForeignKey( + name: "fk_commission_settlements_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_commission_settlements_users_generated_by", + column: x => x.generated_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_commission_settlements_users_paid_by", + column: x => x.paid_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_commission_settlements_users_referrer_user_id", + column: x => x.referrer_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_commission_settlements_users_reviewed_by", + column: x => x.reviewed_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "crm_config", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + enabled = table.Column(type: "boolean", nullable: false), + url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + secret_ref = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + form_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + exam_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + timeout_seconds = table.Column(type: "integer", nullable: true), + delay_seconds = table.Column(type: "integer", nullable: true), + assignment_mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + assignment_pool = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + assignment_cursor = table.Column(type: "integer", nullable: false), + assignment_config = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_crm_config", x => x.id); + table.UniqueConstraint("ak_crm_config_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_crm_config_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "crm_webhook_log", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + record_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + lead_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + http_code = table.Column(type: "integer", nullable: true), + outcome = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + error_message = table.Column(type: "text", nullable: true), + request_body = table.Column(type: "text", nullable: true), + request_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + response_summary = table.Column(type: "character varying(2000)", maxLength: 2000, nullable: true), + signed_at = table.Column(type: "timestamp with time zone", nullable: true), + attempt = table.Column(type: "integer", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_crm_webhook_log", x => x.id); + table.UniqueConstraint("ak_crm_webhook_log_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_crm_webhook_log_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "crm_webhook_queue", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + record_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + lead_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + source = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + provider = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + scheduled_at = table.Column(type: "timestamp with time zone", nullable: true), + attempts = table.Column(type: "integer", nullable: false), + next_attempt_at = table.Column(type: "timestamp with time zone", nullable: true), + last_attempt_at = table.Column(type: "timestamp with time zone", nullable: true), + last_error = table.Column(type: "text", nullable: true), + last_http_code = table.Column(type: "integer", nullable: true), + last_response_summary = table.Column(type: "text", nullable: true), + sent_at = table.Column(type: "timestamp with time zone", nullable: true), + idempotency_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + target_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_crm_webhook_queue", x => x.id); + table.UniqueConstraint("ak_crm_webhook_queue_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_crm_webhook_queue_attempts", "attempts >= 0"); + table.ForeignKey( + name: "fk_crm_webhook_queue_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "entitlements", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + user_id = table.Column(type: "uuid", nullable: false), + entitlement_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + scope_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + scope_id = table.Column(type: "uuid", nullable: true), + source_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + source_id = table.Column(type: "uuid", nullable: true), + legacy_source_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + starts_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + expires_at = table.Column(type: "timestamp with time zone", nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + revoked_at = table.Column(type: "timestamp with time zone", nullable: true), + revoked_by = table.Column(type: "uuid", nullable: true), + revoked_reason = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_entitlements", x => x.id); + table.UniqueConstraint("ak_entitlements_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_entitlements_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_entitlements_users_revoked_by", + column: x => x.revoked_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_entitlements_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "images", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + title = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + category = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + file_name = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), + is_public = table.Column(type: "boolean", nullable: false), + cdn_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_images", x => x.id); + table.UniqueConstraint("ak_images_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_images_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "pb_import_runs", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + source_name = table.Column(type: "character varying(500)", maxLength: 500, nullable: false), + source_kind = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + stats = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + started_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + finished_at = table.Column(type: "timestamp with time zone", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("pk_pb_import_runs", x => x.id); + table.UniqueConstraint("ak_pb_import_runs_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_pb_import_runs_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "platform_audit_alert_rules", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: true), + code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + description = table.Column(type: "text", nullable: true), + enabled = table.Column(type: "boolean", nullable: false), + severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + action_patterns = table.Column(type: "text[]", nullable: false, defaultValueSql: "'{}'::text[]"), + target_types = table.Column(type: "text[]", nullable: false, defaultValueSql: "'{}'::text[]"), + conditions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_platform_audit_alert_rules", x => x.id); + table.ForeignKey( + name: "fk_platform_audit_alert_rules_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "practice_daily_usage", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: false), + usage_date = table.Column(type: "date", nullable: false, defaultValueSql: "current_date"), + scope_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + scope_id = table.Column(type: "uuid", nullable: true), + free_limit = table.Column(type: "integer", nullable: false), + used_count = table.Column(type: "integer", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_practice_daily_usage", x => x.id); + table.UniqueConstraint("ak_practice_daily_usage_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_practice_daily_usage_free_limit", "free_limit >= 0"); + table.CheckConstraint("ck_practice_daily_usage_used_count", "used_count >= 0"); + table.ForeignKey( + name: "fk_practice_daily_usage_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_practice_daily_usage_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "recent_practices", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + practice_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + target_legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + target_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + progress = table.Column(type: "integer", nullable: false), + color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + last_access_at = table.Column(type: "timestamp with time zone", nullable: true), + last_practice_at = table.Column(type: "timestamp with time zone", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_recent_practices", x => x.id); + table.UniqueConstraint("ak_recent_practices_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_recent_practices_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_recent_practices_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "referral_codes", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: false), + code = table.Column(type: "citext", maxLength: 100, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + channel = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + landing_path = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_referral_codes", x => x.id); + table.UniqueConstraint("ak_referral_codes_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_referral_codes_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_referral_codes_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "referral_qrcodes", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: true), + ref_code = table.Column(type: "citext", maxLength: 100, nullable: false), + scene = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + page = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + provider = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + qrcode_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + error_message = table.Column(type: "text", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_referral_qrcodes", x => x.id); + table.UniqueConstraint("ak_referral_qrcodes_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_referral_qrcodes_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_referral_qrcodes_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "referral_team_edges", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + member_user_id = table.Column(type: "uuid", nullable: false), + leader_user_id = table.Column(type: "uuid", nullable: true), + relation_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_referral_team_edges", x => x.id); + table.UniqueConstraint("ak_referral_team_edges_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_referral_team_edges_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_referral_team_edges_users_leader_user_id", + column: x => x.leader_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_referral_team_edges_users_member_user_id", + column: x => x.member_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "regions", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + code = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + short_name = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + full_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + icon = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + pinyin = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), + sort_order = table.Column(type: "integer", nullable: false), + is_hot = table.Column(type: "boolean", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + config = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_regions", x => x.id); + table.UniqueConstraint("ak_regions_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_regions_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "sms_send_rate_limits", + columns: table => new + { + tenant_id = table.Column(type: "uuid", nullable: false), + dimension = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + scope_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: false), + bucket_start = table.Column(type: "timestamp with time zone", nullable: false), + request_count = table.Column(type: "integer", nullable: false, defaultValue: 0), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_sms_send_rate_limits", x => new { x.tenant_id, x.dimension, x.scope_hash, x.bucket_start }); + table.CheckConstraint("ck_sms_send_rate_limits_request_count", "request_count >= 0"); + table.ForeignKey( + name: "fk_sms_send_rate_limits_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "sms_verification_codes", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + phone = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + purpose = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + code_hash = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), + provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + attempts = table.Column(type: "integer", nullable: false), + expires_at = table.Column(type: "timestamp with time zone", nullable: false), + consumed_at = table.Column(type: "timestamp with time zone", nullable: true), + ip_address = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + user_agent = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_sms_verification_codes", x => x.id); + table.UniqueConstraint("ak_sms_verification_codes_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_sms_verification_codes_attempts", "attempts >= 0"); + table.ForeignKey( + name: "fk_sms_verification_codes_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "tenant_auth_providers", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + display_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + config_public = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_auth_providers", x => x.id); + table.UniqueConstraint("ak_tenant_auth_providers_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_tenant_auth_providers_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "tenant_billing_profiles", + columns: table => new + { + tenant_id = table.Column(type: "uuid", nullable: false), + billing_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + tax_id = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + contact_name = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + contact_phone = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + contact_email = table.Column(type: "citext", maxLength: 300, nullable: true), + billing_address = table.Column(type: "text", nullable: true), + invoice_title = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + invoice_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + bank_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + bank_account_masked = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_billing_profiles", x => x.tenant_id); + table.ForeignKey( + name: "fk_tenant_billing_profiles_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "tenant_branding", + columns: table => new + { + tenant_id = table.Column(type: "uuid", nullable: false), + brand_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + short_name = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + slogan = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + organization_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + logo_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + favicon_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + service_wechat = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + service_account_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + theme = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + public_assets = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_branding", x => x.tenant_id); + table.ForeignKey( + name: "fk_tenant_branding_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "tenant_commission_settings", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + default_rate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), + min_settlement_cents = table.Column(type: "integer", nullable: false), + settlement_cycle = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + config = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + updated_by = table.Column(type: "uuid", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_commission_settings", x => x.id); + table.UniqueConstraint("ak_tenant_commission_settings_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_tenant_commission_settings_default_rate", "default_rate >= 0 and default_rate <= 1"); + table.CheckConstraint("ck_tenant_commission_settings_min_settlement", "min_settlement_cents >= 0"); + table.ForeignKey( + name: "fk_tenant_commission_settings_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_commission_settings_users_updated_by", + column: x => x.updated_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "tenant_domains", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + host = table.Column(type: "citext", maxLength: 253, nullable: false), + domain_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + is_primary = table.Column(type: "boolean", nullable: false), + verification_token = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + verified_at = table.Column(type: "timestamp with time zone", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_domains", x => x.id); + table.UniqueConstraint("ak_tenant_domains_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_tenant_domains_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "tenant_invoices", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + created_by = table.Column(type: "uuid", nullable: true), + invoice_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + invoice_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + currency = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), + subtotal_cents = table.Column(type: "integer", nullable: false), + discount_cents = table.Column(type: "integer", nullable: false), + tax_cents = table.Column(type: "integer", nullable: false), + total_cents = table.Column(type: "integer", nullable: false), + paid_cents = table.Column(type: "integer", nullable: false), + balance_cents = table.Column(type: "integer", nullable: false), + billing_period_start = table.Column(type: "date", nullable: true), + billing_period_end = table.Column(type: "date", nullable: true), + due_date = table.Column(type: "date", nullable: true), + issued_at = table.Column(type: "timestamp with time zone", nullable: true), + paid_at = table.Column(type: "timestamp with time zone", nullable: true), + note = table.Column(type: "text", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_invoices", x => x.id); + table.UniqueConstraint("ak_tenant_invoices_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_tenant_invoices_amounts", "subtotal_cents >= 0 and discount_cents >= 0 and tax_cents >= 0 and total_cents >= 0 and paid_cents >= 0 and balance_cents >= 0"); + table.CheckConstraint("ck_tenant_invoices_period", "billing_period_end is null or billing_period_start is null or billing_period_end >= billing_period_start"); + table.ForeignKey( + name: "fk_tenant_invoices_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_invoices_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "tenant_payment_accounts", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + display_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + config_public = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_payment_accounts", x => x.id); + table.UniqueConstraint("ak_tenant_payment_accounts_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_tenant_payment_accounts_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "tenant_role_templates", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + description = table.Column(type: "text", nullable: true), + base_role = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + permissions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + menu_permissions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + module_permissions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + field_permissions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + data_scope = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + is_system = table.Column(type: "boolean", nullable: false), + sort_order = table.Column(type: "integer", nullable: false), + created_by = table.Column(type: "uuid", nullable: true), + updated_by = table.Column(type: "uuid", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_role_templates", x => x.id); + table.UniqueConstraint("ak_tenant_role_templates_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_tenant_role_templates_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_role_templates_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_tenant_role_templates_users_updated_by", + column: x => x.updated_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "tenant_settings", + columns: table => new + { + tenant_id = table.Column(type: "uuid", nullable: false), + feature_flags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + admin_feature_flags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + public_config = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_settings", x => x.tenant_id); + table.ForeignKey( + name: "fk_tenant_settings_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "tenant_student_notes", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + student_user_id = table.Column(type: "uuid", nullable: false), + note_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + content = table.Column(type: "text", nullable: false), + visibility = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + is_pinned = table.Column(type: "boolean", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_by = table.Column(type: "uuid", nullable: true), + updated_by = table.Column(type: "uuid", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_student_notes", x => x.id); + table.UniqueConstraint("ak_tenant_student_notes_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_tenant_student_notes_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_student_notes_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_tenant_student_notes_users_student_user_id", + column: x => x.student_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_student_notes_users_updated_by", + column: x => x.updated_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "tenant_subscriptions", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + plan_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + starts_at = table.Column(type: "timestamp with time zone", nullable: true), + expires_at = table.Column(type: "timestamp with time zone", nullable: true), + billing_cycle = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + amount_cents = table.Column(type: "integer", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_subscriptions", x => x.id); + table.UniqueConstraint("ak_tenant_subscriptions_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_tenant_subscriptions_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "tenant_theme_configs", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + active_template_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + active_theme = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + active_public_assets = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + draft_template_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + draft_theme = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + draft_public_assets = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + published_at = table.Column(type: "timestamp with time zone", nullable: true), + published_by = table.Column(type: "uuid", nullable: true), + draft_updated_by = table.Column(type: "uuid", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_theme_configs", x => x.id); + table.UniqueConstraint("ak_tenant_theme_configs_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_tenant_theme_configs_tenant_theme_templates_active_template~", + column: x => x.active_template_code, + principalTable: "tenant_theme_templates", + principalColumn: "code", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_tenant_theme_configs_tenant_theme_templates_draft_template_~", + column: x => x.draft_template_code, + principalTable: "tenant_theme_templates", + principalColumn: "code", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_tenant_theme_configs_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_theme_configs_users_draft_updated_by", + column: x => x.draft_updated_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_tenant_theme_configs_users_published_by", + column: x => x.published_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "tenant_usage_records", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + metric_key = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + metric_value = table.Column(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false), + period_start = table.Column(type: "date", nullable: false), + period_end = table.Column(type: "date", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_usage_records", x => x.id); + table.UniqueConstraint("ak_tenant_usage_records_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_tenant_usage_records_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "user_notifications", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: false), + source_id = table.Column(type: "uuid", nullable: true), + created_by = table.Column(type: "uuid", nullable: true), + notification_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + title = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + message = table.Column(type: "text", nullable: false), + action_label = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + action_path = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + source_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + dedupe_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + read_at = table.Column(type: "timestamp with time zone", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_user_notifications", x => x.id); + table.UniqueConstraint("ak_user_notifications_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_user_notifications_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_user_notifications_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_user_notifications_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "user_score_events", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + user_id = table.Column(type: "uuid", nullable: false), + event_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + points = table.Column(type: "integer", nullable: false), + balance_after = table.Column(type: "integer", nullable: false), + source_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + source_id = table.Column(type: "uuid", nullable: true), + idempotency_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_user_score_events", x => x.id); + table.UniqueConstraint("ak_user_score_events_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_user_score_events_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_user_score_events_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "user_badges", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: true), + badge_id = table.Column(type: "uuid", nullable: true), + granted_by = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + note = table.Column(type: "text", nullable: true), + granted_at = table.Column(type: "timestamp with time zone", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_user_badges", x => x.id); + table.UniqueConstraint("ak_user_badges_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_user_badges_badges_tenant_id_badge_id", + columns: x => new { x.tenant_id, x.badge_id }, + principalTable: "badges", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_user_badges_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_user_badges_users_granted_by", + column: x => x.granted_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_user_badges_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "commission_settlement_items", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + settlement_id = table.Column(type: "uuid", nullable: true), + referrer_user_id = table.Column(type: "uuid", nullable: false), + student_user_id = table.Column(type: "uuid", nullable: true), + source_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + source_id = table.Column(type: "uuid", nullable: false), + source_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + source_paid_at = table.Column(type: "timestamp with time zone", nullable: true), + gross_amount_cents = table.Column(type: "integer", nullable: false), + commission_rate = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), + commission_amount_cents = table.Column(type: "integer", nullable: false), + rate_source = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + attribution_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_commission_settlement_items", x => x.id); + table.UniqueConstraint("ak_commission_settlement_items_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_commission_settlement_items_amounts", "gross_amount_cents >= 0 and commission_amount_cents >= 0"); + table.CheckConstraint("ck_commission_settlement_items_rate", "commission_rate >= 0 and commission_rate <= 1"); + table.ForeignKey( + name: "fk_commission_settlement_items_commission_settlements_tenant_i~", + columns: x => new { x.tenant_id, x.settlement_id }, + principalTable: "commission_settlements", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_commission_settlement_items_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_commission_settlement_items_users_referrer_user_id", + column: x => x.referrer_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_commission_settlement_items_users_student_user_id", + column: x => x.student_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "pb_import_issues", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + run_id = table.Column(type: "uuid", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + collection_name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + legacy_id = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + issue_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + message = table.Column(type: "text", nullable: false), + field_path = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), + raw_value_sample = table.Column(type: "character varying(2000)", maxLength: 2000, nullable: true), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_pb_import_issues", x => x.id); + table.UniqueConstraint("ak_pb_import_issues_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_pb_import_issues_pb_import_runs_tenant_id_run_id", + columns: x => new { x.tenant_id, x.run_id }, + principalTable: "pb_import_runs", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_pb_import_issues_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "pb_raw_records", + columns: table => new + { + run_id = table.Column(type: "uuid", nullable: false), + collection_name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + legacy_id = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + tenant_id = table.Column(type: "uuid", nullable: false), + record = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + normalized = table.Column(type: "boolean", nullable: false), + errors = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + imported_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_pb_raw_records", x => new { x.run_id, x.collection_name, x.legacy_id }); + table.ForeignKey( + name: "fk_pb_raw_records_pb_import_runs_tenant_id_run_id", + columns: x => new { x.tenant_id, x.run_id }, + principalTable: "pb_import_runs", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_pb_raw_records_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "platform_audit_alerts", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + rule_id = table.Column(type: "uuid", nullable: false), + audit_log_id = table.Column(type: "uuid", nullable: false), + tenant_id = table.Column(type: "uuid", nullable: true), + acknowledged_by = table.Column(type: "uuid", nullable: true), + resolved_by = table.Column(type: "uuid", nullable: true), + severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + action = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + target_type = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + target_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + title = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + summary = table.Column(type: "text", nullable: true), + details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + first_seen_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + last_seen_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + acknowledged_at = table.Column(type: "timestamp with time zone", nullable: true), + resolved_at = table.Column(type: "timestamp with time zone", nullable: true), + resolution_note = table.Column(type: "text", nullable: true), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_platform_audit_alerts", x => x.id); + table.ForeignKey( + name: "fk_platform_audit_alerts_audit_logs_audit_log_id", + column: x => x.audit_log_id, + principalTable: "audit_logs", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_platform_audit_alerts_platform_audit_alert_rules_rule_id", + column: x => x.rule_id, + principalTable: "platform_audit_alert_rules", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_platform_audit_alerts_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_platform_audit_alerts_users_acknowledged_by", + column: x => x.acknowledged_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_platform_audit_alerts_users_resolved_by", + column: x => x.resolved_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "ai_recommendation_reports", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: false), + region_id = table.Column(type: "uuid", nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + provider = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + model = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + prompt_version = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + input_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + context_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + result_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + error_message = table.Column(type: "text", nullable: true), + generated_at = table.Column(type: "timestamp with time zone", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_ai_recommendation_reports", x => x.id); + table.UniqueConstraint("ak_ai_recommendation_reports_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_ai_recommendation_reports_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_ai_recommendation_reports_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_ai_recommendation_reports_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "banners", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + title = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + subtitle = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), + content = table.Column(type: "text", nullable: true), + button_text = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + button_link = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + background_color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + border_color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_banners", x => x.id); + table.UniqueConstraint("ak_banners_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_banners_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_banners_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "content_entries", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + entry_key = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + entry_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + icon = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + route = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), + description = table.Column(type: "character varying(2000)", maxLength: 2000, nullable: true), + visibility = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + access_rules = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + layout_config = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + created_by = table.Column(type: "uuid", nullable: true), + updated_by = table.Column(type: "uuid", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_content_entries", x => x.id); + table.UniqueConstraint("ak_content_entries_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_content_entries_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_content_entries_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_content_entries_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_content_entries_users_updated_by", + column: x => x.updated_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "dashboard_daily_stats", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_region_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + stat_date = table.Column(type: "date", nullable: false), + new_users = table.Column(type: "integer", nullable: false), + new_questions = table.Column(type: "integer", nullable: false), + new_orders = table.Column(type: "integer", nullable: false), + new_revenue_cents = table.Column(type: "integer", nullable: false), + active_users = table.Column(type: "integer", nullable: false), + rebuilt_at = table.Column(type: "timestamp with time zone", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_dashboard_daily_stats", x => x.id); + table.UniqueConstraint("ak_dashboard_daily_stats_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_dashboard_daily_stats_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_dashboard_daily_stats_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "faqs", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + question = table.Column(type: "text", nullable: true), + answer = table.Column(type: "text", nullable: true), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_faqs", x => x.id); + table.UniqueConstraint("ak_faqs_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_faqs_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_faqs_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "products", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + title = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + legacy_price_text = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + link = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + tags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + sort_order = table.Column(type: "integer", nullable: false), + cover = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + preview_iframe = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + detail_images = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_products", x => x.id); + table.UniqueConstraint("ak_products_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_products_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_products_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "question_banks", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + source_scope = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_question_banks", x => x.id); + table.UniqueConstraint("ak_question_banks_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_question_banks_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_question_banks_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "region_modules", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + icon = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + text_color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + description = table.Column(type: "text", nullable: true), + route = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), + sort_order = table.Column(type: "integer", nullable: false), + is_primary_school_module = table.Column(type: "boolean", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_region_modules", x => x.id); + table.UniqueConstraint("ak_region_modules_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_region_modules_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_region_modules_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "revenue_daily_stats", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_region_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + stat_date = table.Column(type: "date", nullable: false), + sale_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + real_revenue_cents = table.Column(type: "integer", nullable: false), + order_count = table.Column(type: "integer", nullable: false), + code_count = table.Column(type: "integer", nullable: false), + code_used = table.Column(type: "integer", nullable: false), + code_estimated = table.Column(type: "integer", nullable: false), + estimated_revenue_cents = table.Column(type: "integer", nullable: false), + rebuilt_at = table.Column(type: "timestamp with time zone", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_revenue_daily_stats", x => x.id); + table.UniqueConstraint("ak_revenue_daily_stats_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_revenue_daily_stats_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_revenue_daily_stats_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "svip_plans", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + price_cents = table.Column(type: "integer", nullable: false), + original_price_cents = table.Column(type: "integer", nullable: true), + days = table.Column(type: "integer", nullable: false), + description = table.Column(type: "text", nullable: true), + per_day_label = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + badge = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + recommended = table.Column(type: "boolean", nullable: false), + coupon_only = table.Column(type: "boolean", nullable: false), + vp_product_id = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + vp_enabled = table.Column(type: "boolean", nullable: false), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_svip_plans", x => x.id); + table.UniqueConstraint("ak_svip_plans_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_svip_plans_days", "days >= 0"); + table.CheckConstraint("ck_svip_plans_price", "price_cents >= 0 and (original_price_cents is null or original_price_cents >= 0)"); + table.ForeignKey( + name: "fk_svip_plans_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_svip_plans_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "tenant_classes", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + description = table.Column(type: "text", nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + sort_order = table.Column(type: "integer", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_by = table.Column(type: "uuid", nullable: true), + updated_by = table.Column(type: "uuid", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_classes", x => x.id); + table.UniqueConstraint("ak_tenant_classes_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_tenant_classes_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_tenant_classes_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_classes_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_tenant_classes_users_updated_by", + column: x => x.updated_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "tenant_invoice_items", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + invoice_id = table.Column(type: "uuid", nullable: false), + item_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + item_ref_id = table.Column(type: "uuid", nullable: true), + description = table.Column(type: "character varying(500)", maxLength: 500, nullable: false), + quantity = table.Column(type: "numeric(12,2)", precision: 12, scale: 2, nullable: false), + unit_amount_cents = table.Column(type: "integer", nullable: false), + amount_cents = table.Column(type: "integer", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_invoice_items", x => x.id); + table.UniqueConstraint("ak_tenant_invoice_items_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_tenant_invoice_items_amounts", "unit_amount_cents >= 0 and amount_cents >= 0"); + table.CheckConstraint("ck_tenant_invoice_items_quantity", "quantity > 0"); + table.ForeignKey( + name: "fk_tenant_invoice_items_tenant_invoices_tenant_id_invoice_id", + columns: x => new { x.tenant_id, x.invoice_id }, + principalTable: "tenant_invoices", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_invoice_items_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "tenant_invoice_payments", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + invoice_id = table.Column(type: "uuid", nullable: false), + received_by = table.Column(type: "uuid", nullable: true), + payment_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + method = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + amount_cents = table.Column(type: "integer", nullable: false), + paid_at = table.Column(type: "timestamp with time zone", nullable: true), + provider_trade_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + raw_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_invoice_payments", x => x.id); + table.UniqueConstraint("ak_tenant_invoice_payments_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_tenant_invoice_payments_amount", "amount_cents >= 0"); + table.ForeignKey( + name: "fk_tenant_invoice_payments_tenant_invoices_tenant_id_invoice_id", + columns: x => new { x.tenant_id, x.invoice_id }, + principalTable: "tenant_invoices", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_invoice_payments_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_invoice_payments_users_received_by", + column: x => x.received_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "tenant_invoice_reminders", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + invoice_id = table.Column(type: "uuid", nullable: false), + created_by = table.Column(type: "uuid", nullable: true), + reminder_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + channel = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + reminder_date = table.Column(type: "date", nullable: false), + reminder_level = table.Column(type: "integer", nullable: false), + due_date = table.Column(type: "date", nullable: true), + balance_cents_snapshot = table.Column(type: "integer", nullable: false), + message = table.Column(type: "text", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + sent_at = table.Column(type: "timestamp with time zone", nullable: true), + acknowledged_at = table.Column(type: "timestamp with time zone", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_invoice_reminders", x => x.id); + table.UniqueConstraint("ak_tenant_invoice_reminders_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_tenant_invoice_reminders_balance", "balance_cents_snapshot >= 0"); + table.CheckConstraint("ck_tenant_invoice_reminders_level", "reminder_level between 1 and 20"); + table.ForeignKey( + name: "fk_tenant_invoice_reminders_tenant_invoices_tenant_id_invoice_~", + columns: x => new { x.tenant_id, x.invoice_id }, + principalTable: "tenant_invoices", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_invoice_reminders_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_invoice_reminders_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "tenant_memberships", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: false), + role_template_id = table.Column(type: "uuid", nullable: true), + role = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + permissions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + legacy_role = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_memberships", x => x.id); + table.UniqueConstraint("ak_tenant_memberships_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_tenant_memberships_tenant_role_templates_tenant_id_role_tem~", + columns: x => new { x.tenant_id, x.role_template_id }, + principalTable: "tenant_role_templates", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_tenant_memberships_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_memberships_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "content_nodes", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + entry_id = table.Column(type: "uuid", nullable: false), + region_id = table.Column(type: "uuid", nullable: true), + parent_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + node_key = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + node_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + marker_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + marker_config = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + path = table.Column(type: "ltree", nullable: true), + depth = table.Column(type: "integer", nullable: false), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + is_selectable = table.Column(type: "boolean", nullable: false), + is_leaf = table.Column(type: "boolean", nullable: false), + access_rules = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_by = table.Column(type: "uuid", nullable: true), + updated_by = table.Column(type: "uuid", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_content_nodes", x => x.id); + table.UniqueConstraint("ak_content_nodes_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_content_nodes_depth", "depth >= 0"); + table.ForeignKey( + name: "fk_content_nodes_content_entries_tenant_id_entry_id", + columns: x => new { x.tenant_id, x.entry_id }, + principalTable: "content_entries", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_content_nodes_content_nodes_tenant_id_parent_id", + columns: x => new { x.tenant_id, x.parent_id }, + principalTable: "content_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_content_nodes_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_content_nodes_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_content_nodes_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_content_nodes_users_updated_by", + column: x => x.updated_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "question_bank_grants", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + source_question_bank_id = table.Column(type: "uuid", nullable: false), + created_by = table.Column(type: "uuid", nullable: true), + updated_by = table.Column(type: "uuid", nullable: true), + grant_scope = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + allowed_plan_codes = table.Column(type: "text[]", nullable: false, defaultValueSql: "'{}'::text[]"), + allowed_tenant_ids = table.Column(type: "uuid[]", nullable: false, defaultValueSql: "'{}'::uuid[]"), + allowed_region_ids = table.Column(type: "uuid[]", nullable: false, defaultValueSql: "'{}'::uuid[]"), + allowed_subject_ids = table.Column(type: "uuid[]", nullable: false, defaultValueSql: "'{}'::uuid[]"), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + starts_at = table.Column(type: "timestamp with time zone", nullable: true), + expires_at = table.Column(type: "timestamp with time zone", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_question_bank_grants", x => x.id); + table.ForeignKey( + name: "fk_question_bank_grants_question_banks_source_question_bank_id", + column: x => x.source_question_bank_id, + principalTable: "question_banks", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_question_bank_grants_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_question_bank_grants_users_updated_by", + column: x => x.updated_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "tenant_content_notifications", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + adoption_id = table.Column(type: "uuid", nullable: true), + source_question_bank_id = table.Column(type: "uuid", nullable: true), + created_by = table.Column(type: "uuid", nullable: true), + read_by = table.Column(type: "uuid", nullable: true), + notification_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + title = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + message = table.Column(type: "text", nullable: false), + action_label = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + action_path = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + dedupe_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + read_at = table.Column(type: "timestamp with time zone", nullable: true), + resolved_at = table.Column(type: "timestamp with time zone", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_content_notifications", x => x.id); + table.UniqueConstraint("ak_tenant_content_notifications_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_tenant_content_notifications_question_banks_tenant_id_sourc~", + columns: x => new { x.tenant_id, x.source_question_bank_id }, + principalTable: "question_banks", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_content_notifications_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_content_notifications_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_tenant_content_notifications_users_read_by", + column: x => x.read_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "module_nodes", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + module_id = table.Column(type: "uuid", nullable: true), + parent_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_parent_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_module_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + path = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_module_nodes", x => x.id); + table.UniqueConstraint("ak_module_nodes_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_module_nodes_module_nodes_tenant_id_parent_id", + columns: x => new { x.tenant_id, x.parent_id }, + principalTable: "module_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_module_nodes_region_modules_tenant_id_module_id", + columns: x => new { x.tenant_id, x.module_id }, + principalTable: "region_modules", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_module_nodes_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_module_nodes_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "schools", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + module_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + professional_exam_date = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_schools", x => x.id); + table.UniqueConstraint("ak_schools_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_schools_region_modules_tenant_id_module_id", + columns: x => new { x.tenant_id, x.module_id }, + principalTable: "region_modules", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_schools_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_schools_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "coupons", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + plan_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + code = table.Column(type: "citext", maxLength: 100, nullable: false), + discount_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + discount_value = table.Column(type: "numeric(10,2)", precision: 10, scale: 2, nullable: true), + valid_from = table.Column(type: "timestamp with time zone", nullable: true), + valid_to = table.Column(type: "timestamp with time zone", nullable: true), + max_uses = table.Column(type: "integer", nullable: true), + used_count = table.Column(type: "integer", nullable: false), + source = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + remark = table.Column(type: "text", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_coupons", x => x.id); + table.UniqueConstraint("ak_coupons_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_coupons_svip_plans_tenant_id_plan_id", + columns: x => new { x.tenant_id, x.plan_id }, + principalTable: "svip_plans", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_coupons_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "orders", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: true), + plan_id = table.Column(type: "uuid", nullable: true), + region_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_user_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_plan_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_region_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + order_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + product_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + product_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + amount_cents = table.Column(type: "integer", nullable: false), + pay_method = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + pay_provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + trade_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + days = table.Column(type: "integer", nullable: true), + refunded_amount_cents = table.Column(type: "integer", nullable: false), + paid_at = table.Column(type: "timestamp with time zone", nullable: true), + raw_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_orders", x => x.id); + table.UniqueConstraint("ak_orders_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_orders_amount", "amount_cents >= 0"); + table.CheckConstraint("ck_orders_refunded_amount", "refunded_amount_cents >= 0"); + table.ForeignKey( + name: "fk_orders_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_orders_svip_plans_tenant_id_plan_id", + columns: x => new { x.tenant_id, x.plan_id }, + principalTable: "svip_plans", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_orders_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_orders_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "tenant_class_members", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + class_id = table.Column(type: "uuid", nullable: false), + user_id = table.Column(type: "uuid", nullable: false), + member_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + joined_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + left_at = table.Column(type: "timestamp with time zone", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_by = table.Column(type: "uuid", nullable: true), + updated_by = table.Column(type: "uuid", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_class_members", x => x.id); + table.UniqueConstraint("ak_tenant_class_members_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_tenant_class_members_tenant_classes_tenant_id_class_id", + columns: x => new { x.tenant_id, x.class_id }, + principalTable: "tenant_classes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_class_members_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_class_members_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "tenant_student_followups", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + student_user_id = table.Column(type: "uuid", nullable: false), + assigned_to_user_id = table.Column(type: "uuid", nullable: true), + class_id = table.Column(type: "uuid", nullable: true), + title = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + description = table.Column(type: "text", nullable: true), + followup_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + priority = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + due_at = table.Column(type: "timestamp with time zone", nullable: true), + completed_at = table.Column(type: "timestamp with time zone", nullable: true), + completed_by = table.Column(type: "uuid", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_by = table.Column(type: "uuid", nullable: true), + updated_by = table.Column(type: "uuid", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_student_followups", x => x.id); + table.UniqueConstraint("ak_tenant_student_followups_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_tenant_student_followups_tenant_classes_tenant_id_class_id", + columns: x => new { x.tenant_id, x.class_id }, + principalTable: "tenant_classes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_tenant_student_followups_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_student_followups_users_assigned_to_user_id", + column: x => x.assigned_to_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_tenant_student_followups_users_completed_by", + column: x => x.completed_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_tenant_student_followups_users_student_user_id", + column: x => x.student_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "platform_dunning_notification_events", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + channel_id = table.Column(type: "uuid", nullable: false), + reminder_id = table.Column(type: "uuid", nullable: false), + invoice_id = table.Column(type: "uuid", nullable: false), + provider = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + attempts = table.Column(type: "integer", nullable: false), + scheduled_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + next_attempt_at = table.Column(type: "timestamp with time zone", nullable: true), + last_attempt_at = table.Column(type: "timestamp with time zone", nullable: true), + sent_at = table.Column(type: "timestamp with time zone", nullable: true), + last_error = table.Column(type: "text", nullable: true), + last_http_code = table.Column(type: "integer", nullable: true), + last_response_summary = table.Column(type: "text", nullable: true), + request_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_platform_dunning_notification_events", x => x.id); + table.UniqueConstraint("ak_platform_dunning_notification_events_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_platform_dunning_events_attempts", "attempts >= 0"); + table.ForeignKey( + name: "fk_platform_dunning_notification_events_platform_dunning_notif~", + column: x => x.channel_id, + principalTable: "platform_dunning_notification_channels", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_platform_dunning_notification_events_tenant_invoice_reminde~", + columns: x => new { x.tenant_id, x.reminder_id }, + principalTable: "tenant_invoice_reminders", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_platform_dunning_notification_events_tenant_invoices_tenant~", + columns: x => new { x.tenant_id, x.invoice_id }, + principalTable: "tenant_invoices", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_platform_dunning_notification_events_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "vocabulary_units", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + entry_id = table.Column(type: "uuid", nullable: true), + content_node_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + description = table.Column(type: "text", nullable: true), + word_count = table.Column(type: "integer", nullable: true), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_vocabulary_units", x => x.id); + table.UniqueConstraint("ak_vocabulary_units_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_vocabulary_units_content_entries_tenant_id_entry_id", + columns: x => new { x.tenant_id, x.entry_id }, + principalTable: "content_entries", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_vocabulary_units_content_nodes_tenant_id_content_node_id", + columns: x => new { x.tenant_id, x.content_node_id }, + principalTable: "content_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_vocabulary_units_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_vocabulary_units_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "exam_dates", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + school_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + exam_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + exam_at = table.Column(type: "timestamp with time zone", nullable: true), + exam_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + description = table.Column(type: "text", nullable: true), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_exam_dates", x => x.id); + table.UniqueConstraint("ak_exam_dates_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_exam_dates_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_exam_dates_schools_tenant_id_school_id", + columns: x => new { x.tenant_id, x.school_id }, + principalTable: "schools", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_exam_dates_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "majors", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + school_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + description = table.Column(type: "text", nullable: true), + study_tips = table.Column(type: "text", nullable: true), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_majors", x => x.id); + table.UniqueConstraint("ak_majors_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_majors_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_majors_schools_tenant_id_school_id", + columns: x => new { x.tenant_id, x.school_id }, + principalTable: "schools", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_majors_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "coupon_redemptions", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + coupon_id = table.Column(type: "uuid", nullable: true), + user_id = table.Column(type: "uuid", nullable: true), + plan_id = table.Column(type: "uuid", nullable: true), + order_id = table.Column(type: "uuid", nullable: true), + region_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + coupon_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + discount_applied_cents = table.Column(type: "integer", nullable: true), + source = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + remark = table.Column(type: "text", nullable: true), + claimed_at = table.Column(type: "timestamp with time zone", nullable: true), + used_at = table.Column(type: "timestamp with time zone", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_coupon_redemptions", x => x.id); + table.UniqueConstraint("ak_coupon_redemptions_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_coupon_redemptions_coupons_tenant_id_coupon_id", + columns: x => new { x.tenant_id, x.coupon_id }, + principalTable: "coupons", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_coupon_redemptions_orders_tenant_id_order_id", + columns: x => new { x.tenant_id, x.order_id }, + principalTable: "orders", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_coupon_redemptions_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_coupon_redemptions_svip_plans_tenant_id_plan_id", + columns: x => new { x.tenant_id, x.plan_id }, + principalTable: "svip_plans", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_coupon_redemptions_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_coupon_redemptions_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "order_items", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + order_id = table.Column(type: "uuid", nullable: false), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + item_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + item_id = table.Column(type: "uuid", nullable: true), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + quantity = table.Column(type: "integer", nullable: false), + unit_amount_cents = table.Column(type: "integer", nullable: false), + total_amount_cents = table.Column(type: "integer", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_order_items", x => x.id); + table.UniqueConstraint("ak_order_items_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_order_items_amounts", "unit_amount_cents >= 0 and total_amount_cents >= 0"); + table.CheckConstraint("ck_order_items_quantity", "quantity > 0"); + table.ForeignKey( + name: "fk_order_items_orders_tenant_id_order_id", + columns: x => new { x.tenant_id, x.order_id }, + principalTable: "orders", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_order_items_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "payments", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + order_id = table.Column(type: "uuid", nullable: false), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_order_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + method = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + amount_cents = table.Column(type: "integer", nullable: false), + refunded_amount_cents = table.Column(type: "integer", nullable: false), + provider_trade_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + paid_at = table.Column(type: "timestamp with time zone", nullable: true), + raw_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_payments", x => x.id); + table.UniqueConstraint("ak_payments_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_payments_amount", "amount_cents >= 0"); + table.CheckConstraint("ck_payments_refunded_amount", "refunded_amount_cents >= 0"); + table.ForeignKey( + name: "fk_payments_orders_tenant_id_order_id", + columns: x => new { x.tenant_id, x.order_id }, + principalTable: "orders", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_payments_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "vocabulary_words", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + unit_id = table.Column(type: "uuid", nullable: true), + entry_id = table.Column(type: "uuid", nullable: true), + content_node_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + word = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + phonetic = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + meaning = table.Column(type: "text", nullable: true), + example = table.Column(type: "text", nullable: true), + example_translation = table.Column(type: "text", nullable: true), + difficulty = table.Column(type: "integer", nullable: true), + tags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_vocabulary_words", x => x.id); + table.UniqueConstraint("ak_vocabulary_words_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_vocabulary_words_content_entries_tenant_id_entry_id", + columns: x => new { x.tenant_id, x.entry_id }, + principalTable: "content_entries", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_vocabulary_words_content_nodes_tenant_id_content_node_id", + columns: x => new { x.tenant_id, x.content_node_id }, + principalTable: "content_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_vocabulary_words_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_vocabulary_words_vocabulary_units_tenant_id_unit_id", + columns: x => new { x.tenant_id, x.unit_id }, + principalTable: "vocabulary_units", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "handbook_subjects", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + school_id = table.Column(type: "uuid", nullable: true), + major_id = table.Column(type: "uuid", nullable: true), + entry_id = table.Column(type: "uuid", nullable: true), + content_node_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + icon = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + color = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + description = table.Column(type: "text", nullable: true), + major_legacy_ids = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_handbook_subjects", x => x.id); + table.UniqueConstraint("ak_handbook_subjects_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_handbook_subjects_content_entries_tenant_id_entry_id", + columns: x => new { x.tenant_id, x.entry_id }, + principalTable: "content_entries", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_handbook_subjects_content_nodes_tenant_id_content_node_id", + columns: x => new { x.tenant_id, x.content_node_id }, + principalTable: "content_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_handbook_subjects_majors_tenant_id_major_id", + columns: x => new { x.tenant_id, x.major_id }, + principalTable: "majors", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_handbook_subjects_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_handbook_subjects_schools_tenant_id_school_id", + columns: x => new { x.tenant_id, x.school_id }, + principalTable: "schools", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_handbook_subjects_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "student_profiles", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: false), + legacy_user_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + region_id = table.Column(type: "uuid", nullable: true), + selected_school_id = table.Column(type: "uuid", nullable: true), + selected_major_id = table.Column(type: "uuid", nullable: true), + questions_answered_today = table.Column(type: "integer", nullable: false), + mastered_words_count = table.Column(type: "integer", nullable: false), + last_check_in_date = table.Column(type: "date", nullable: true), + stats = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + progress = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + module_selections = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + recent_activities = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_student_profiles", x => x.id); + table.UniqueConstraint("ak_student_profiles_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_student_profiles_majors_tenant_id_selected_major_id", + columns: x => new { x.tenant_id, x.selected_major_id }, + principalTable: "majors", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_student_profiles_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_student_profiles_schools_tenant_id_selected_school_id", + columns: x => new { x.tenant_id, x.selected_school_id }, + principalTable: "schools", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_student_profiles_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_student_profiles_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "subjects", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + module_id = table.Column(type: "uuid", nullable: true), + school_id = table.Column(type: "uuid", nullable: true), + major_id = table.Column(type: "uuid", nullable: true), + node_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + major_legacy_ids = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + icon = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + description = table.Column(type: "text", nullable: true), + stats = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_subjects", x => x.id); + table.UniqueConstraint("ak_subjects_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_subjects_majors_tenant_id_major_id", + columns: x => new { x.tenant_id, x.major_id }, + principalTable: "majors", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_subjects_module_nodes_tenant_id_node_id", + columns: x => new { x.tenant_id, x.node_id }, + principalTable: "module_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_subjects_region_modules_tenant_id_module_id", + columns: x => new { x.tenant_id, x.module_id }, + principalTable: "region_modules", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_subjects_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_subjects_schools_tenant_id_school_id", + columns: x => new { x.tenant_id, x.school_id }, + principalTable: "schools", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_subjects_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "activation_codes", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + used_by = table.Column(type: "uuid", nullable: true), + agent_user_id = table.Column(type: "uuid", nullable: true), + batch_id = table.Column(type: "uuid", nullable: true), + used_region_id = table.Column(type: "uuid", nullable: true), + coupon_redemption_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + code = table.Column(type: "citext", maxLength: 100, nullable: false), + days = table.Column(type: "integer", nullable: false), + is_used = table.Column(type: "boolean", nullable: false), + used_at = table.Column(type: "timestamp with time zone", nullable: true), + sale_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + unit_price_cents = table.Column(type: "integer", nullable: true), + sold_to = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + coupon_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + remark = table.Column(type: "text", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_activation_codes", x => x.id); + table.UniqueConstraint("ak_activation_codes_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_activation_codes_code_batches_tenant_id_batch_id", + columns: x => new { x.tenant_id, x.batch_id }, + principalTable: "code_batches", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_activation_codes_coupon_redemptions_tenant_id_coupon_redemp~", + columns: x => new { x.tenant_id, x.coupon_redemption_id }, + principalTable: "coupon_redemptions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_activation_codes_regions_tenant_id_used_region_id", + columns: x => new { x.tenant_id, x.used_region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_activation_codes_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_activation_codes_users_agent_user_id", + column: x => x.agent_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_activation_codes_users_used_by", + column: x => x.used_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "commerce_refund_requests", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + order_id = table.Column(type: "uuid", nullable: false), + payment_id = table.Column(type: "uuid", nullable: true), + requested_by = table.Column(type: "uuid", nullable: true), + reviewed_by = table.Column(type: "uuid", nullable: true), + processed_by = table.Column(type: "uuid", nullable: true), + refund_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + provider_refund_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + amount_cents = table.Column(type: "integer", nullable: false), + reason = table.Column(type: "text", nullable: true), + entitlement_action = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + requested_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + reviewed_at = table.Column(type: "timestamp with time zone", nullable: true), + processed_at = table.Column(type: "timestamp with time zone", nullable: true), + succeeded_at = table.Column(type: "timestamp with time zone", nullable: true), + failed_at = table.Column(type: "timestamp with time zone", nullable: true), + cancelled_at = table.Column(type: "timestamp with time zone", nullable: true), + failure_reason = table.Column(type: "text", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_commerce_refund_requests", x => x.id); + table.UniqueConstraint("ak_commerce_refund_requests_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_commerce_refund_requests_amount", "amount_cents > 0"); + table.ForeignKey( + name: "fk_commerce_refund_requests_orders_tenant_id_order_id", + columns: x => new { x.tenant_id, x.order_id }, + principalTable: "orders", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_commerce_refund_requests_payments_tenant_id_payment_id", + columns: x => new { x.tenant_id, x.payment_id }, + principalTable: "payments", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_commerce_refund_requests_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_commerce_refund_requests_users_processed_by", + column: x => x.processed_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_commerce_refund_requests_users_requested_by", + column: x => x.requested_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_commerce_refund_requests_users_reviewed_by", + column: x => x.reviewed_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "payment_events", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + payment_id = table.Column(type: "uuid", nullable: true), + provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + event_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + event_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + signature_valid = table.Column(type: "boolean", nullable: true), + payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + processed_at = table.Column(type: "timestamp with time zone", nullable: true), + error = table.Column(type: "text", nullable: true), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_payment_events", x => x.id); + table.UniqueConstraint("ak_payment_events_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_payment_events_payments_tenant_id_payment_id", + columns: x => new { x.tenant_id, x.payment_id }, + principalTable: "payments", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_payment_events_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "user_word_favorites", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: false), + word_id = table.Column(type: "uuid", nullable: false), + legacy_id = table.Column(type: "text", nullable: true), + legacy_user_id = table.Column(type: "text", nullable: true), + legacy_word_id = table.Column(type: "text", nullable: true), + note = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + favorited_at = table.Column(type: "timestamp with time zone", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_user_word_favorites", x => x.id); + table.UniqueConstraint("ak_user_word_favorites_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_user_word_favorites_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_user_word_favorites_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_user_word_favorites_vocabulary_words_tenant_id_word_id", + columns: x => new { x.tenant_id, x.word_id }, + principalTable: "vocabulary_words", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "user_word_progress", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: false), + word_id = table.Column(type: "uuid", nullable: false), + legacy_id = table.Column(type: "text", nullable: true), + legacy_user_id = table.Column(type: "text", nullable: true), + legacy_word_id = table.Column(type: "text", nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + correct_count = table.Column(type: "integer", nullable: false), + wrong_count = table.Column(type: "integer", nullable: false), + last_review_at = table.Column(type: "timestamp with time zone", nullable: true), + next_review_at = table.Column(type: "timestamp with time zone", nullable: true), + review_count = table.Column(type: "integer", nullable: false), + correct_streak = table.Column(type: "integer", nullable: false), + ease_factor = table.Column(type: "numeric(4,2)", precision: 4, scale: 2, nullable: false, defaultValue: 2.50m), + last_result = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + due_level = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_user_word_progress", x => x.id); + table.UniqueConstraint("ak_user_word_progress_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_user_word_progress_correct_streak", "correct_streak >= 0"); + table.CheckConstraint("ck_user_word_progress_ease_factor", "ease_factor >= 1.30 and ease_factor <= 3.00"); + table.CheckConstraint("ck_user_word_progress_review_count", "review_count >= 0"); + table.ForeignKey( + name: "fk_user_word_progress_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_user_word_progress_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_user_word_progress_vocabulary_words_tenant_id_word_id", + columns: x => new { x.tenant_id, x.word_id }, + principalTable: "vocabulary_words", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "handbook_chapters", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + subject_id = table.Column(type: "uuid", nullable: true), + entry_id = table.Column(type: "uuid", nullable: true), + content_node_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + description = table.Column(type: "text", nullable: true), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_handbook_chapters", x => x.id); + table.UniqueConstraint("ak_handbook_chapters_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_handbook_chapters_content_entries_tenant_id_entry_id", + columns: x => new { x.tenant_id, x.entry_id }, + principalTable: "content_entries", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_handbook_chapters_content_nodes_tenant_id_content_node_id", + columns: x => new { x.tenant_id, x.content_node_id }, + principalTable: "content_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_handbook_chapters_handbook_subjects_tenant_id_subject_id", + columns: x => new { x.tenant_id, x.subject_id }, + principalTable: "handbook_subjects", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_handbook_chapters_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "categories", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + subject_id = table.Column(type: "uuid", nullable: true), + node_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + category_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + sort_order = table.Column(type: "integer", nullable: false), + svip_question_limit = table.Column(type: "integer", nullable: true), + is_active = table.Column(type: "boolean", nullable: false), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_categories", x => x.id); + table.UniqueConstraint("ak_categories_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_categories_module_nodes_tenant_id_node_id", + columns: x => new { x.tenant_id, x.node_id }, + principalTable: "module_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_categories_subjects_tenant_id_subject_id", + columns: x => new { x.tenant_id, x.subject_id }, + principalTable: "subjects", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_categories_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "question_type_groups", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + subject_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + display_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), + types = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_question_type_groups", x => x.id); + table.UniqueConstraint("ak_question_type_groups_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_question_type_groups_subjects_tenant_id_subject_id", + columns: x => new { x.tenant_id, x.subject_id }, + principalTable: "subjects", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_question_type_groups_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "subject_shares", + columns: table => new + { + tenant_id = table.Column(type: "uuid", nullable: false), + source_subject_id = table.Column(type: "uuid", nullable: false), + target_subject_id = table.Column(type: "uuid", nullable: false), + legacy_id = table.Column(type: "text", nullable: true), + legacy_source_subject_id = table.Column(type: "text", nullable: true), + legacy_target_subject_id = table.Column(type: "text", nullable: true), + id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_subject_shares", x => new { x.tenant_id, x.source_subject_id, x.target_subject_id }); + table.ForeignKey( + name: "fk_subject_shares_subjects_tenant_id_source_subject_id", + columns: x => new { x.tenant_id, x.source_subject_id }, + principalTable: "subjects", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_subject_shares_subjects_tenant_id_target_subject_id", + columns: x => new { x.tenant_id, x.target_subject_id }, + principalTable: "subjects", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_subject_shares_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "video_explanations", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + subject_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_subject_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + title = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + description = table.Column(type: "text", nullable: true), + video_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + thumbnail_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + duration_seconds = table.Column(type: "integer", nullable: true), + knowledge_tags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + is_general = table.Column(type: "boolean", nullable: false), + difficulty = table.Column(type: "integer", nullable: true), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_video_explanations", x => x.id); + table.UniqueConstraint("ak_video_explanations_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_video_explanations_subjects_tenant_id_subject_id", + columns: x => new { x.tenant_id, x.subject_id }, + principalTable: "subjects", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_video_explanations_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "commerce_reconciliation_items", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + batch_id = table.Column(type: "uuid", nullable: false), + order_id = table.Column(type: "uuid", nullable: true), + payment_id = table.Column(type: "uuid", nullable: true), + refund_request_id = table.Column(type: "uuid", nullable: true), + row_no = table.Column(type: "integer", nullable: false), + provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + transaction_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + provider_trade_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + provider_refund_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + order_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + refund_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + amount_cents = table.Column(type: "integer", nullable: false), + refund_amount_cents = table.Column(type: "integer", nullable: false), + fee_cents = table.Column(type: "integer", nullable: false), + paid_at = table.Column(type: "timestamp with time zone", nullable: true), + refunded_at = table.Column(type: "timestamp with time zone", nullable: true), + provider_status = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + local_status = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + match_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + issue_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_commerce_reconciliation_items", x => x.id); + table.UniqueConstraint("ak_commerce_reconciliation_items_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_commerce_reconciliation_items_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); + table.CheckConstraint("ck_commerce_reconciliation_items_row", "row_no > 0"); + table.ForeignKey( + name: "fk_commerce_reconciliation_items_commerce_reconciliation_batch~", + columns: x => new { x.tenant_id, x.batch_id }, + principalTable: "commerce_reconciliation_batches", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_commerce_reconciliation_items_commerce_refund_requests_tena~", + columns: x => new { x.tenant_id, x.refund_request_id }, + principalTable: "commerce_refund_requests", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_commerce_reconciliation_items_orders_tenant_id_order_id", + columns: x => new { x.tenant_id, x.order_id }, + principalTable: "orders", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_commerce_reconciliation_items_payments_tenant_id_payment_id", + columns: x => new { x.tenant_id, x.payment_id }, + principalTable: "payments", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_commerce_reconciliation_items_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "commerce_refund_events", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + refund_request_id = table.Column(type: "uuid", nullable: false), + from_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + to_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + event_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + actor_user_id = table.Column(type: "uuid", nullable: true), + details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_commerce_refund_events", x => x.id); + table.UniqueConstraint("ak_commerce_refund_events_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_commerce_refund_events_commerce_refund_requests_tenant_id_r~", + columns: x => new { x.tenant_id, x.refund_request_id }, + principalTable: "commerce_refund_requests", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_commerce_refund_events_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_commerce_refund_events_users_actor_user_id", + column: x => x.actor_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "handbook_entries", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + chapter_id = table.Column(type: "uuid", nullable: true), + entry_id = table.Column(type: "uuid", nullable: true), + content_node_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + title = table.Column(type: "character varying(500)", maxLength: 500, nullable: false), + summary = table.Column(type: "text", nullable: true), + content = table.Column(type: "text", nullable: true), + tags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + sort_order = table.Column(type: "integer", nullable: false), + is_active = table.Column(type: "boolean", nullable: false), + source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_handbook_entries", x => x.id); + table.UniqueConstraint("ak_handbook_entries_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_handbook_entries_content_entries_tenant_id_entry_id", + columns: x => new { x.tenant_id, x.entry_id }, + principalTable: "content_entries", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_handbook_entries_content_nodes_tenant_id_content_node_id", + columns: x => new { x.tenant_id, x.content_node_id }, + principalTable: "content_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_handbook_entries_handbook_chapters_tenant_id_chapter_id", + columns: x => new { x.tenant_id, x.chapter_id }, + principalTable: "handbook_chapters", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_handbook_entries_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "content_assets", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + subject_id = table.Column(type: "uuid", nullable: true), + category_id = table.Column(type: "uuid", nullable: true), + content_node_id = table.Column(type: "uuid", nullable: true), + created_by = table.Column(type: "uuid", nullable: true), + updated_by = table.Column(type: "uuid", nullable: true), + verified_by = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + asset_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + title = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + category = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + description = table.Column(type: "text", nullable: true), + file_name = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), + cdn_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + is_public = table.Column(type: "boolean", nullable: false), + asset_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + storage_provider = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + bucket = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + object_key = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + mime_type = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + file_size_bytes = table.Column(type: "bigint", nullable: true), + checksum_sha256 = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + visibility = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + preview_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + sort_order = table.Column(type: "integer", nullable: false), + access_rules = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + source = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + download_count = table.Column(type: "integer", nullable: false), + upload_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + verified_at = table.Column(type: "timestamp with time zone", nullable: true), + verified_size_bytes = table.Column(type: "bigint", nullable: true), + verified_checksum_sha256 = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + verification_details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + preview_object_key = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + preview_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + security_scan_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false, defaultValue: "not_required"), + security_scanned_at = table.Column(type: "timestamp with time zone", nullable: true), + security_scan_provider = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + security_scan_summary = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + security_flags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_content_assets", x => x.id); + table.UniqueConstraint("ak_content_assets_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_content_assets_download_count", "download_count >= 0"); + table.CheckConstraint("ck_content_assets_file_size", "file_size_bytes is null or file_size_bytes >= 0"); + table.CheckConstraint("ck_content_assets_verified_checksum", "verified_checksum_sha256 is null or verified_checksum_sha256 ~ '^[a-f0-9]{64}$'"); + table.CheckConstraint("ck_content_assets_verified_size", "verified_size_bytes is null or verified_size_bytes >= 0"); + table.ForeignKey( + name: "fk_content_assets_categories_tenant_id_category_id", + columns: x => new { x.tenant_id, x.category_id }, + principalTable: "categories", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_content_assets_content_nodes_tenant_id_content_node_id", + columns: x => new { x.tenant_id, x.content_node_id }, + principalTable: "content_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_content_assets_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_content_assets_subjects_tenant_id_subject_id", + columns: x => new { x.tenant_id, x.subject_id }, + principalTable: "subjects", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_content_assets_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_content_assets_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_content_assets_users_updated_by", + column: x => x.updated_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_content_assets_users_verified_by", + column: x => x.verified_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "content_import_jobs", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + created_by = table.Column(type: "uuid", nullable: true), + target_region_id = table.Column(type: "uuid", nullable: true), + target_subject_id = table.Column(type: "uuid", nullable: true), + target_category_id = table.Column(type: "uuid", nullable: true), + target_content_node_id = table.Column(type: "uuid", nullable: true), + target_question_bank_id = table.Column(type: "uuid", nullable: true), + import_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + source_format = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + source_name = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), + source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), + dry_run = table.Column(type: "boolean", nullable: false), + total_count = table.Column(type: "integer", nullable: false), + valid_count = table.Column(type: "integer", nullable: false), + error_count = table.Column(type: "integer", nullable: false), + warning_count = table.Column(type: "integer", nullable: false), + inserted_count = table.Column(type: "integer", nullable: false), + updated_count = table.Column(type: "integer", nullable: false), + skipped_count = table.Column(type: "integer", nullable: false), + summary = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + raw_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + normalized_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + error_message = table.Column(type: "text", nullable: true), + started_at = table.Column(type: "timestamp with time zone", nullable: true), + finished_at = table.Column(type: "timestamp with time zone", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_content_import_jobs", x => x.id); + table.UniqueConstraint("ak_content_import_jobs_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("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"); + table.ForeignKey( + name: "fk_content_import_jobs_categories_tenant_id_target_category_id", + columns: x => new { x.tenant_id, x.target_category_id }, + principalTable: "categories", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_content_import_jobs_content_nodes_tenant_id_target_content_~", + columns: x => new { x.tenant_id, x.target_content_node_id }, + principalTable: "content_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_content_import_jobs_question_banks_tenant_id_target_questio~", + columns: x => new { x.tenant_id, x.target_question_bank_id }, + principalTable: "question_banks", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_content_import_jobs_regions_tenant_id_target_region_id", + columns: x => new { x.tenant_id, x.target_region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_content_import_jobs_subjects_tenant_id_target_subject_id", + columns: x => new { x.tenant_id, x.target_subject_id }, + principalTable: "subjects", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_content_import_jobs_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_content_import_jobs_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "question_collections", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + entry_id = table.Column(type: "uuid", nullable: true), + node_id = table.Column(type: "uuid", nullable: true), + subject_id = table.Column(type: "uuid", nullable: true), + category_id = table.Column(type: "uuid", nullable: true), + question_bank_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + collection_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + source_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + filters = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + access_rules = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + question_count = table.Column(type: "integer", nullable: false), + total_score = table.Column(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true), + duration_minutes = table.Column(type: "integer", nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + sort_order = table.Column(type: "integer", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_by = table.Column(type: "uuid", nullable: true), + updated_by = table.Column(type: "uuid", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_question_collections", x => x.id); + table.UniqueConstraint("ak_question_collections_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_question_collections_duration", "duration_minutes is null or duration_minutes > 0"); + table.CheckConstraint("ck_question_collections_question_count", "question_count >= 0"); + table.ForeignKey( + name: "fk_question_collections_categories_tenant_id_category_id", + columns: x => new { x.tenant_id, x.category_id }, + principalTable: "categories", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_question_collections_content_entries_tenant_id_entry_id", + columns: x => new { x.tenant_id, x.entry_id }, + principalTable: "content_entries", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_question_collections_content_nodes_tenant_id_node_id", + columns: x => new { x.tenant_id, x.node_id }, + principalTable: "content_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_question_collections_question_banks_tenant_id_question_bank~", + columns: x => new { x.tenant_id, x.question_bank_id }, + principalTable: "question_banks", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_question_collections_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_question_collections_subjects_tenant_id_subject_id", + columns: x => new { x.tenant_id, x.subject_id }, + principalTable: "subjects", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_question_collections_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_question_collections_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_question_collections_users_updated_by", + column: x => x.updated_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "commerce_reconciliation_issues", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + batch_id = table.Column(type: "uuid", nullable: true), + item_id = table.Column(type: "uuid", nullable: true), + order_id = table.Column(type: "uuid", nullable: true), + payment_id = table.Column(type: "uuid", nullable: true), + refund_request_id = table.Column(type: "uuid", nullable: true), + assigned_to = table.Column(type: "uuid", nullable: true), + created_by = table.Column(type: "uuid", nullable: true), + resolved_by = table.Column(type: "uuid", nullable: true), + issue_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + transaction_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + issue_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + match_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + resolution_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + order_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + refund_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + provider_trade_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + provider_refund_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + amount_cents = table.Column(type: "integer", nullable: false), + refund_amount_cents = table.Column(type: "integer", nullable: false), + resolved_at = table.Column(type: "timestamp with time zone", nullable: true), + due_at = table.Column(type: "timestamp with time zone", nullable: true), + summary = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + resolution_note = table.Column(type: "text", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_commerce_reconciliation_issues", x => x.id); + table.UniqueConstraint("ak_commerce_reconciliation_issues_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_commerce_reconciliation_issues_amounts", "amount_cents >= 0 and refund_amount_cents >= 0"); + table.ForeignKey( + name: "fk_commerce_reconciliation_issues_commerce_reconciliation_batc~", + columns: x => new { x.tenant_id, x.batch_id }, + principalTable: "commerce_reconciliation_batches", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_commerce_reconciliation_issues_commerce_reconciliation_item~", + columns: x => new { x.tenant_id, x.item_id }, + principalTable: "commerce_reconciliation_items", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_commerce_reconciliation_issues_commerce_refund_requests_ten~", + columns: x => new { x.tenant_id, x.refund_request_id }, + principalTable: "commerce_refund_requests", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_commerce_reconciliation_issues_orders_tenant_id_order_id", + columns: x => new { x.tenant_id, x.order_id }, + principalTable: "orders", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_commerce_reconciliation_issues_payments_tenant_id_payment_id", + columns: x => new { x.tenant_id, x.payment_id }, + principalTable: "payments", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_commerce_reconciliation_issues_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_commerce_reconciliation_issues_users_assigned_to", + column: x => x.assigned_to, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_commerce_reconciliation_issues_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_commerce_reconciliation_issues_users_resolved_by", + column: x => x.resolved_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "content_asset_access_events", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + asset_id = table.Column(type: "uuid", nullable: true), + user_id = table.Column(type: "uuid", nullable: true), + actor_role = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + access_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + visibility = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + asset_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + storage_provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + disposition = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + expires_in_seconds = table.Column(type: "integer", nullable: true), + signature_mode = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + result = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + deny_code = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + ip_address = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + user_agent = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_content_asset_access_events", x => x.id); + table.UniqueConstraint("ak_content_asset_access_events_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_content_asset_access_events_expiry", "expires_in_seconds is null or expires_in_seconds > 0"); + table.ForeignKey( + name: "fk_content_asset_access_events_content_assets_tenant_id_asset_~", + columns: x => new { x.tenant_id, x.asset_id }, + principalTable: "content_assets", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_content_asset_access_events_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_content_asset_access_events_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "content_asset_security_scan_events", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + asset_id = table.Column(type: "uuid", nullable: true), + provider = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + scan_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + risk_level = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + issue_codes = table.Column(type: "text[]", nullable: false, defaultValueSql: "'{}'::text[]"), + details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_content_asset_security_scan_events", x => x.id); + table.UniqueConstraint("ak_content_asset_security_scan_events_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_content_asset_security_scan_events_content_assets_tenant_id~", + columns: x => new { x.tenant_id, x.asset_id }, + principalTable: "content_assets", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_content_asset_security_scan_events_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "content_import_items", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + job_id = table.Column(type: "uuid", nullable: false), + row_no = table.Column(type: "integer", nullable: false), + external_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + target_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + target_id = table.Column(type: "uuid", nullable: true), + source_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + normalized_payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + content_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), + issues_count = table.Column(type: "integer", nullable: false), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_content_import_items", x => x.id); + table.UniqueConstraint("ak_content_import_items_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_content_import_items_issues_count", "issues_count >= 0"); + table.CheckConstraint("ck_content_import_items_row_no", "row_no >= 0"); + table.ForeignKey( + name: "fk_content_import_items_content_import_jobs_tenant_id_job_id", + columns: x => new { x.tenant_id, x.job_id }, + principalTable: "content_import_jobs", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_content_import_items_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "practice_blueprints", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + region_id = table.Column(type: "uuid", nullable: true), + entry_id = table.Column(type: "uuid", nullable: true), + node_id = table.Column(type: "uuid", nullable: true), + collection_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), + mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + assembly_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + question_limit = table.Column(type: "integer", nullable: true), + duration_minutes = table.Column(type: "integer", nullable: true), + total_score = table.Column(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true), + pass_score = table.Column(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true), + sections = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + rules = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + access_rules = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + sort_order = table.Column(type: "integer", nullable: false), + created_by = table.Column(type: "uuid", nullable: true), + updated_by = table.Column(type: "uuid", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_practice_blueprints", x => x.id); + table.UniqueConstraint("ak_practice_blueprints_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_practice_blueprints_duration", "duration_minutes is null or duration_minutes > 0"); + table.CheckConstraint("ck_practice_blueprints_question_limit", "question_limit is null or question_limit > 0"); + table.ForeignKey( + name: "fk_practice_blueprints_content_entries_tenant_id_entry_id", + columns: x => new { x.tenant_id, x.entry_id }, + principalTable: "content_entries", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_practice_blueprints_content_nodes_tenant_id_node_id", + columns: x => new { x.tenant_id, x.node_id }, + principalTable: "content_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_practice_blueprints_question_collections_tenant_id_collecti~", + columns: x => new { x.tenant_id, x.collection_id }, + principalTable: "question_collections", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_practice_blueprints_regions_tenant_id_region_id", + columns: x => new { x.tenant_id, x.region_id }, + principalTable: "regions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_practice_blueprints_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_practice_blueprints_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_practice_blueprints_users_updated_by", + column: x => x.updated_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "tenant_question_bank_adoptions", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + source_question_bank_id = table.Column(type: "uuid", nullable: false), + grant_id = table.Column(type: "uuid", nullable: true), + target_question_bank_id = table.Column(type: "uuid", nullable: true), + target_entry_id = table.Column(type: "uuid", nullable: true), + target_collection_id = table.Column(type: "uuid", nullable: true), + created_by = table.Column(type: "uuid", nullable: true), + updated_by = table.Column(type: "uuid", nullable: true), + adoption_mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + sync_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + source_snapshot = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + copied_question_count = table.Column(type: "integer", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + last_synced_at = table.Column(type: "timestamp with time zone", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_tenant_question_bank_adoptions", x => x.id); + table.UniqueConstraint("ak_tenant_question_bank_adoptions_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_tenant_question_bank_adoptions_copied_count", "copied_question_count >= 0"); + table.ForeignKey( + name: "fk_tenant_question_bank_adoptions_content_entries_tenant_id_ta~", + columns: x => new { x.tenant_id, x.target_entry_id }, + principalTable: "content_entries", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_tenant_question_bank_adoptions_question_bank_grants_grant_id", + column: x => x.grant_id, + principalTable: "question_bank_grants", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_tenant_question_bank_adoptions_question_banks_source_questi~", + column: x => x.source_question_bank_id, + principalTable: "question_banks", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_question_bank_adoptions_question_banks_tenant_id_tar~", + columns: x => new { x.tenant_id, x.target_question_bank_id }, + principalTable: "question_banks", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_tenant_question_bank_adoptions_question_collections_tenant_~", + columns: x => new { x.tenant_id, x.target_collection_id }, + principalTable: "question_collections", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_tenant_question_bank_adoptions_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_tenant_question_bank_adoptions_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_tenant_question_bank_adoptions_users_updated_by", + column: x => x.updated_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "commerce_reconciliation_issue_events", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + issue_id = table.Column(type: "uuid", nullable: false), + from_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + to_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + event_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + actor_user_id = table.Column(type: "uuid", nullable: true), + note = table.Column(type: "text", nullable: true), + details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_commerce_reconciliation_issue_events", x => x.id); + table.UniqueConstraint("ak_commerce_reconciliation_issue_events_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_commerce_reconciliation_issue_events_commerce_reconciliatio~", + columns: x => new { x.tenant_id, x.issue_id }, + principalTable: "commerce_reconciliation_issues", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_commerce_reconciliation_issue_events_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_commerce_reconciliation_issue_events_users_actor_user_id", + column: x => x.actor_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "content_import_issues", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + job_id = table.Column(type: "uuid", nullable: false), + item_id = table.Column(type: "uuid", nullable: true), + row_no = table.Column(type: "integer", nullable: true), + severity = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + field_path = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), + message = table.Column(type: "character varying(2000)", maxLength: 2000, nullable: false), + details = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_content_import_issues", x => x.id); + table.UniqueConstraint("ak_content_import_issues_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_content_import_issues_content_import_items_tenant_id_item_id", + columns: x => new { x.tenant_id, x.item_id }, + principalTable: "content_import_items", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_content_import_issues_content_import_jobs_tenant_id_job_id", + columns: x => new { x.tenant_id, x.job_id }, + principalTable: "content_import_jobs", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_content_import_issues_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "practice_sessions", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: false), + blueprint_id = table.Column(type: "uuid", nullable: true), + collection_id = table.Column(type: "uuid", nullable: true), + entry_id = table.Column(type: "uuid", nullable: true), + content_node_id = table.Column(type: "uuid", nullable: true), + mode = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + target_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + target_id = table.Column(type: "uuid", nullable: true), + started_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + finished_at = table.Column(type: "timestamp with time zone", nullable: true), + question_ids = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + question_count = table.Column(type: "integer", nullable: false), + duration_minutes = table.Column(type: "integer", nullable: true), + total_score = table.Column(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true), + expires_at = table.Column(type: "timestamp with time zone", nullable: true), + access_mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false, defaultValue: "free"), + access_entitlement_id = table.Column(type: "uuid", nullable: true), + consumed_free_quota = table.Column(type: "integer", nullable: false), + access_snapshot = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_practice_sessions", x => x.id); + table.UniqueConstraint("ak_practice_sessions_tenant_id_id", x => new { x.tenant_id, x.id }); + table.UniqueConstraint("ak_practice_sessions_tenant_id_user_id_id", x => new { x.tenant_id, x.user_id, x.id }); + table.CheckConstraint("ck_practice_sessions_consumed_free_quota", "consumed_free_quota >= 0"); + table.ForeignKey( + name: "fk_practice_sessions_content_entries_tenant_id_entry_id", + columns: x => new { x.tenant_id, x.entry_id }, + principalTable: "content_entries", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_practice_sessions_content_nodes_tenant_id_content_node_id", + columns: x => new { x.tenant_id, x.content_node_id }, + principalTable: "content_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id", + columns: x => new { x.tenant_id, x.blueprint_id }, + principalTable: "practice_blueprints", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_practice_sessions_question_collections_tenant_id_collection~", + columns: x => new { x.tenant_id, x.collection_id }, + principalTable: "question_collections", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_practice_sessions_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_practice_sessions_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "practice_access_events", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + user_id = table.Column(type: "uuid", nullable: true), + practice_session_id = table.Column(type: "uuid", nullable: true), + event_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + access_mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + requested_count = table.Column(type: "integer", nullable: false), + granted_count = table.Column(type: "integer", nullable: false), + consumed_free_quota = table.Column(type: "integer", nullable: false), + reason = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), + scope_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + scope_id = table.Column(type: "uuid", nullable: true), + entitlement_id = table.Column(type: "uuid", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_practice_access_events", x => x.id); + table.UniqueConstraint("ak_practice_access_events_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_practice_access_events_consumed_free_quota", "consumed_free_quota >= 0"); + table.CheckConstraint("ck_practice_access_events_granted_count", "granted_count >= 0"); + table.CheckConstraint("ck_practice_access_events_requested_count", "requested_count >= 0"); + table.ForeignKey( + name: "fk_practice_access_events_practice_sessions_tenant_id_practice~", + columns: x => new { x.tenant_id, x.practice_session_id }, + principalTable: "practice_sessions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_practice_access_events_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_practice_access_events_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "practice_session_reports", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: false), + practice_session_id = table.Column(type: "uuid", nullable: false), + blueprint_id = table.Column(type: "uuid", nullable: true), + collection_id = table.Column(type: "uuid", nullable: true), + mode = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + total_questions = table.Column(type: "integer", nullable: false), + answered_count = table.Column(type: "integer", nullable: false), + correct_count = table.Column(type: "integer", nullable: false), + wrong_count = table.Column(type: "integer", nullable: false), + unanswered_count = table.Column(type: "integer", nullable: false), + score = table.Column(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false), + total_score = table.Column(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false), + accuracy = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), + duration_seconds = table.Column(type: "integer", nullable: false), + started_at = table.Column(type: "timestamp with time zone", nullable: true), + submitted_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + section_stats = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + question_results = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + wrong_question_ids = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_practice_session_reports", x => x.id); + table.UniqueConstraint("ak_practice_session_reports_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_practice_session_reports_accuracy", "accuracy >= 0 and accuracy <= 1"); + table.CheckConstraint("ck_practice_session_reports_counts", "total_questions >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); + table.CheckConstraint("ck_practice_session_reports_duration", "duration_seconds >= 0"); + table.CheckConstraint("ck_practice_session_reports_scores", "score >= 0 and total_score >= 0"); + table.ForeignKey( + name: "fk_practice_session_reports_practice_blueprints_tenant_id_blue~", + columns: x => new { x.tenant_id, x.blueprint_id }, + principalTable: "practice_blueprints", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_practice_session_reports_practice_sessions_tenant_id_practi~", + columns: x => new { x.tenant_id, x.practice_session_id }, + principalTable: "practice_sessions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_practice_session_reports_question_collections_tenant_id_col~", + columns: x => new { x.tenant_id, x.collection_id }, + principalTable: "question_collections", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_practice_session_reports_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_practice_session_reports_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "practice_session_report_sections", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + report_id = table.Column(type: "uuid", nullable: false), + practice_session_id = table.Column(type: "uuid", nullable: false), + section_key = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + section_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + question_type = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + question_count = table.Column(type: "integer", nullable: false), + answered_count = table.Column(type: "integer", nullable: false), + correct_count = table.Column(type: "integer", nullable: false), + wrong_count = table.Column(type: "integer", nullable: false), + unanswered_count = table.Column(type: "integer", nullable: false), + score = table.Column(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false), + total_score = table.Column(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false), + accuracy = table.Column(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false), + sort_order = table.Column(type: "integer", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_practice_session_report_sections", x => x.id); + table.UniqueConstraint("ak_practice_session_report_sections_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_practice_session_report_sections_accuracy", "accuracy >= 0 and accuracy <= 1"); + table.CheckConstraint("ck_practice_session_report_sections_counts", "question_count >= 0 and answered_count >= 0 and correct_count >= 0 and wrong_count >= 0 and unanswered_count >= 0"); + table.CheckConstraint("ck_practice_session_report_sections_scores", "score >= 0 and total_score >= 0"); + table.ForeignKey( + name: "fk_practice_session_report_sections_practice_session_reports_t~", + columns: x => new { x.tenant_id, x.report_id }, + principalTable: "practice_session_reports", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_practice_session_report_sections_practice_sessions_tenant_i~", + columns: x => new { x.tenant_id, x.practice_session_id }, + principalTable: "practice_sessions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_practice_session_report_sections_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "answer_records", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + user_id = table.Column(type: "uuid", nullable: false), + question_id = table.Column(type: "uuid", nullable: true), + question_version_id = table.Column(type: "uuid", nullable: true), + practice_session_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_question_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_category_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + selected_options = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + answer_text = table.Column(type: "text", nullable: true), + is_correct = table.Column(type: "boolean", nullable: true), + answered_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + tenant_id = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_answer_records", x => x.id); + table.UniqueConstraint("ak_answer_records_tenant_id_id", x => new { x.tenant_id, x.id }); + table.CheckConstraint("ck_answer_records_version_requires_question", "question_version_id is null or question_id is not null"); + table.ForeignKey( + name: "fk_answer_records_practice_sessions_tenant_id_user_id_practice~", + columns: x => new { x.tenant_id, x.user_id, x.practice_session_id }, + principalTable: "practice_sessions", + principalColumns: new[] { "tenant_id", "user_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_answer_records_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_answer_records_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "favorite_questions", + columns: table => new + { + tenant_id = table.Column(type: "uuid", nullable: false), + user_id = table.Column(type: "uuid", nullable: false), + question_id = table.Column(type: "uuid", nullable: false), + source = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_favorite_questions", x => new { x.tenant_id, x.user_id, x.question_id }); + table.ForeignKey( + name: "fk_favorite_questions_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_favorite_questions_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "question_collection_items", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + collection_id = table.Column(type: "uuid", nullable: false), + question_id = table.Column(type: "uuid", nullable: false), + section_key = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + sort_order = table.Column(type: "integer", nullable: false), + score = table.Column(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true), + required = table.Column(type: "boolean", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_question_collection_items", x => x.id); + table.UniqueConstraint("ak_question_collection_items_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_question_collection_items_question_collections_tenant_id_co~", + columns: x => new { x.tenant_id, x.collection_id }, + principalTable: "question_collections", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_question_collection_items_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "question_versions", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + question_id = table.Column(type: "uuid", nullable: false), + version_no = table.Column(type: "integer", nullable: false), + content = table.Column(type: "text", nullable: true), + options = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + correct_option_index = table.Column(type: "integer", nullable: true), + correct_option_indices = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + answer_text = table.Column(type: "text", nullable: true), + explanation = table.Column(type: "text", nullable: true), + sub_questions = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + code_lang = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + code_template = table.Column(type: "text", nullable: true), + source_hash = table.Column(type: "character varying(128)", maxLength: 128, nullable: true), + created_by = table.Column(type: "uuid", nullable: true), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_question_versions", x => x.id); + table.UniqueConstraint("ak_question_versions_tenant_id_id", x => new { x.tenant_id, x.id }); + table.UniqueConstraint("ak_question_versions_tenant_id_question_id_id", x => new { x.tenant_id, x.question_id, x.id }); + table.ForeignKey( + name: "fk_question_versions_users_created_by", + column: x => x.created_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "questions", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + question_bank_id = table.Column(type: "uuid", nullable: true), + subject_id = table.Column(type: "uuid", nullable: true), + category_id = table.Column(type: "uuid", nullable: true), + node_id = table.Column(type: "uuid", nullable: true), + entry_id = table.Column(type: "uuid", nullable: true), + content_node_id = table.Column(type: "uuid", nullable: true), + primary_collection_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_subject_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_category_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_node_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + type = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + type_label = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + difficulty = table.Column(type: "integer", nullable: true), + tags = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + exam_markers = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + media_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), + has_video_explanation = table.Column(type: "boolean", nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + current_version_id = table.Column(type: "uuid", nullable: true), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_questions", x => x.id); + table.UniqueConstraint("ak_questions_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_questions_categories_tenant_id_category_id", + columns: x => new { x.tenant_id, x.category_id }, + principalTable: "categories", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_questions_content_entries_tenant_id_entry_id", + columns: x => new { x.tenant_id, x.entry_id }, + principalTable: "content_entries", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_questions_content_nodes_tenant_id_content_node_id", + columns: x => new { x.tenant_id, x.content_node_id }, + principalTable: "content_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_questions_module_nodes_tenant_id_node_id", + columns: x => new { x.tenant_id, x.node_id }, + principalTable: "module_nodes", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_questions_question_banks_tenant_id_question_bank_id", + columns: x => new { x.tenant_id, x.question_bank_id }, + principalTable: "question_banks", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_questions_question_collections_tenant_id_primary_collection~", + columns: x => new { x.tenant_id, x.primary_collection_id }, + principalTable: "question_collections", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_questions_question_versions_tenant_id_id_current_version_id", + columns: x => new { x.tenant_id, x.id, x.current_version_id }, + principalTable: "question_versions", + principalColumns: new[] { "tenant_id", "question_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_questions_subjects_tenant_id_subject_id", + columns: x => new { x.tenant_id, x.subject_id }, + principalTable: "subjects", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_questions_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "question_videos", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + question_id = table.Column(type: "uuid", nullable: true), + video_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_question_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + legacy_video_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + video_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + sort_order = table.Column(type: "integer", nullable: false), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_question_videos", x => x.id); + table.UniqueConstraint("ak_question_videos_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_question_videos_questions_tenant_id_question_id", + columns: x => new { x.tenant_id, x.question_id }, + principalTable: "questions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_question_videos_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_question_videos_video_explanations_tenant_id_video_id", + columns: x => new { x.tenant_id, x.video_id }, + principalTable: "video_explanations", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "reports", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + question_id = table.Column(type: "uuid", nullable: true), + user_id = table.Column(type: "uuid", nullable: true), + handled_by = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + type = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + title = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + category = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + description = table.Column(type: "text", nullable: true), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + priority = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + handled_at = table.Column(type: "timestamp with time zone", nullable: true), + resolution = table.Column(type: "text", nullable: true), + contact = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), + attachments = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_reports", x => x.id); + table.UniqueConstraint("ak_reports_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_reports_questions_tenant_id_question_id", + columns: x => new { x.tenant_id, x.question_id }, + principalTable: "questions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "fk_reports_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_reports_users_handled_by", + column: x => x.handled_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_reports_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "wrong_questions", + columns: table => new + { + tenant_id = table.Column(type: "uuid", nullable: false), + user_id = table.Column(type: "uuid", nullable: false), + question_id = table.Column(type: "uuid", nullable: false), + wrong_count = table.Column(type: "integer", nullable: false, defaultValue: 1), + last_wrong_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + resolved_at = table.Column(type: "timestamp with time zone", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("pk_wrong_questions", x => new { x.tenant_id, x.user_id, x.question_id }); + table.ForeignKey( + name: "fk_wrong_questions_questions_tenant_id_question_id", + columns: x => new { x.tenant_id, x.question_id }, + principalTable: "questions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_wrong_questions_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_wrong_questions_users_user_id", + column: x => x.user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "report_status_events", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + tenant_id = table.Column(type: "uuid", nullable: false), + report_id = table.Column(type: "uuid", nullable: false), + from_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + to_status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + note = table.Column(type: "text", nullable: true), + actor_user_id = table.Column(type: "uuid", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_report_status_events", x => x.id); + table.UniqueConstraint("ak_report_status_events_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_report_status_events_reports_tenant_id_report_id", + columns: x => new { x.tenant_id, x.report_id }, + principalTable: "reports", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_report_status_events_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_report_status_events_users_actor_user_id", + column: x => x.actor_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateTable( + name: "referral_leads", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + student_user_id = table.Column(type: "uuid", nullable: false), + referrer_user_id = table.Column(type: "uuid", nullable: true), + first_track_id = table.Column(type: "uuid", nullable: true), + assigned_to_user_id = table.Column(type: "uuid", nullable: true), + assigned_by = table.Column(type: "uuid", nullable: true), + ref_code = table.Column(type: "citext", maxLength: 100, nullable: true), + source = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + bind_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + protected_until = table.Column(type: "timestamp with time zone", nullable: true), + assignment_mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + assigned_at = table.Column(type: "timestamp with time zone", nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + bound_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_referral_leads", x => x.id); + table.UniqueConstraint("ak_referral_leads_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_referral_leads_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_referral_leads_users_assigned_by", + column: x => x.assigned_by, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_referral_leads_users_assigned_to_user_id", + column: x => x.assigned_to_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_referral_leads_users_referrer_user_id", + column: x => x.referrer_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_referral_leads_users_student_user_id", + column: x => x.student_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "referral_tracks", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), + lead_id = table.Column(type: "uuid", nullable: true), + referrer_user_id = table.Column(type: "uuid", nullable: true), + target_user_id = table.Column(type: "uuid", nullable: true), + legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), + event_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + ref_code = table.Column(type: "citext", maxLength: 100, nullable: true), + source = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + ip_address = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), + user_agent = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: true), + metadata = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), + tenant_id = table.Column(type: "uuid", nullable: false), + created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), + updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") + }, + constraints: table => + { + table.PrimaryKey("pk_referral_tracks", x => x.id); + table.UniqueConstraint("ak_referral_tracks_tenant_id_id", x => new { x.tenant_id, x.id }); + table.ForeignKey( + name: "fk_referral_tracks_referral_leads_tenant_id_lead_id", + columns: x => new { x.tenant_id, x.lead_id }, + principalTable: "referral_leads", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_referral_tracks_tenants_tenant_id", + column: x => x.tenant_id, + principalTable: "tenants", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_referral_tracks_users_referrer_user_id", + column: x => x.referrer_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "fk_referral_tracks_users_target_user_id", + column: x => x.target_user_id, + principalTable: "users", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + }); + + migrationBuilder.CreateIndex( + name: "ix_activation_codes_agent_user_id", + table: "activation_codes", + column: "agent_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_activation_codes_tenant_id_batch_id", + table: "activation_codes", + columns: new[] { "tenant_id", "batch_id" }); + + migrationBuilder.CreateIndex( + name: "ix_activation_codes_tenant_id_code", + table: "activation_codes", + columns: new[] { "tenant_id", "code" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_activation_codes_tenant_id_coupon_redemption_id", + table: "activation_codes", + columns: new[] { "tenant_id", "coupon_redemption_id" }); + + migrationBuilder.CreateIndex( + name: "ix_activation_codes_tenant_id_legacy_id", + table: "activation_codes", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_activation_codes_tenant_id_used_region_id", + table: "activation_codes", + columns: new[] { "tenant_id", "used_region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_activation_codes_used_by", + table: "activation_codes", + column: "used_by"); + + migrationBuilder.CreateIndex( + name: "ix_ai_recommendation_reports_tenant_id_region_id_created_at", + table: "ai_recommendation_reports", + columns: new[] { "tenant_id", "region_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_ai_recommendation_reports_tenant_id_user_id_created_at", + table: "ai_recommendation_reports", + columns: new[] { "tenant_id", "user_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_ai_recommendation_reports_user_id", + table: "ai_recommendation_reports", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_announcements_tenant_id_is_active_sort_order", + table: "announcements", + columns: new[] { "tenant_id", "is_active", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_announcements_tenant_id_legacy_id", + table: "announcements", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_answer_records_tenant_id_legacy_id", + table: "answer_records", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_answer_records_tenant_id_question_id", + table: "answer_records", + columns: new[] { "tenant_id", "question_id" }); + + migrationBuilder.CreateIndex( + name: "ix_answer_records_tenant_id_question_id_question_version_id", + table: "answer_records", + columns: new[] { "tenant_id", "question_id", "question_version_id" }); + + migrationBuilder.CreateIndex( + name: "ix_answer_records_tenant_id_user_id_practice_session_id", + table: "answer_records", + columns: new[] { "tenant_id", "user_id", "practice_session_id" }); + + migrationBuilder.CreateIndex( + name: "ix_answer_records_user_id", + table: "answer_records", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_app_assets_tenant_id_asset_key", + table: "app_assets", + columns: new[] { "tenant_id", "asset_key" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_app_assets_tenant_id_legacy_id", + table: "app_assets", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_audit_logs_actor_user_id", + table: "audit_logs", + column: "actor_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_audit_logs_tenant_id_created_at", + table: "audit_logs", + columns: new[] { "tenant_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_audit_logs_tenant_id_target_type_target_id_created_at", + table: "audit_logs", + columns: new[] { "tenant_id", "target_type", "target_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_auth_login_events_tenant_id_user_id_created_at", + table: "auth_login_events", + columns: new[] { "tenant_id", "user_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_auth_login_events_user_id", + table: "auth_login_events", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_auth_sessions_tenant_id_user_id_expires_at", + table: "auth_sessions", + columns: new[] { "tenant_id", "user_id", "expires_at" }, + filter: "revoked_at is null"); + + migrationBuilder.CreateIndex( + name: "ix_auth_sessions_token_hash", + table: "auth_sessions", + column: "token_hash", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_auth_sessions_user_id", + table: "auth_sessions", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_badges_tenant_id_category_is_active_sort_order", + table: "badges", + columns: new[] { "tenant_id", "category", "is_active", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_badges_tenant_id_legacy_id", + table: "badges", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_banners_tenant_id_legacy_id", + table: "banners", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_banners_tenant_id_region_id_is_active_sort_order", + table: "banners", + columns: new[] { "tenant_id", "region_id", "is_active", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_categories_tenant_id_legacy_id", + table: "categories", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_categories_tenant_id_node_id", + table: "categories", + columns: new[] { "tenant_id", "node_id" }); + + migrationBuilder.CreateIndex( + name: "ix_categories_tenant_id_subject_id", + table: "categories", + columns: new[] { "tenant_id", "subject_id" }); + + migrationBuilder.CreateIndex( + name: "ix_code_batches_tenant_id_legacy_id", + table: "code_batches", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_batches_created_by", + table: "commerce_reconciliation_batches", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_batches_tenant_id_provider_bill_dat~", + table: "commerce_reconciliation_batches", + columns: new[] { "tenant_id", "provider", "bill_date", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_batches_tenant_id_status_created_at", + table: "commerce_reconciliation_batches", + columns: new[] { "tenant_id", "status", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issue_events_actor_user_id", + table: "commerce_reconciliation_issue_events", + column: "actor_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issue_events_tenant_id_issue_id_cre~", + table: "commerce_reconciliation_issue_events", + columns: new[] { "tenant_id", "issue_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issues_assigned_to", + table: "commerce_reconciliation_issues", + column: "assigned_to"); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issues_created_by", + table: "commerce_reconciliation_issues", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issues_resolved_by", + table: "commerce_reconciliation_issues", + column: "resolved_by"); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issues_tenant_id_assigned_to_status~", + table: "commerce_reconciliation_issues", + columns: new[] { "tenant_id", "assigned_to", "status", "due_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issues_tenant_id_batch_id_status_cr~", + table: "commerce_reconciliation_issues", + columns: new[] { "tenant_id", "batch_id", "status", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issues_tenant_id_issue_no", + table: "commerce_reconciliation_issues", + columns: new[] { "tenant_id", "issue_no" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issues_tenant_id_item_id", + table: "commerce_reconciliation_issues", + columns: new[] { "tenant_id", "item_id" }, + unique: true, + filter: "item_id is not null and status in ('open', 'investigating', 'escalated')"); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issues_tenant_id_order_id", + table: "commerce_reconciliation_issues", + columns: new[] { "tenant_id", "order_id" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issues_tenant_id_order_no_created_at", + table: "commerce_reconciliation_issues", + columns: new[] { "tenant_id", "order_no", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issues_tenant_id_payment_id_created~", + table: "commerce_reconciliation_issues", + columns: new[] { "tenant_id", "payment_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issues_tenant_id_refund_request_id", + table: "commerce_reconciliation_issues", + columns: new[] { "tenant_id", "refund_request_id" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_issues_tenant_id_status_severity_cr~", + table: "commerce_reconciliation_issues", + columns: new[] { "tenant_id", "status", "severity", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_items_batch_id_row_no", + table: "commerce_reconciliation_items", + columns: new[] { "batch_id", "row_no" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_items_tenant_id_batch_id_match_stat~", + table: "commerce_reconciliation_items", + columns: new[] { "tenant_id", "batch_id", "match_status", "row_no" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_items_tenant_id_order_id", + table: "commerce_reconciliation_items", + columns: new[] { "tenant_id", "order_id" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_items_tenant_id_order_no_created_at", + table: "commerce_reconciliation_items", + columns: new[] { "tenant_id", "order_no", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_items_tenant_id_payment_id", + table: "commerce_reconciliation_items", + columns: new[] { "tenant_id", "payment_id" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_items_tenant_id_provider_provider_t~", + table: "commerce_reconciliation_items", + columns: new[] { "tenant_id", "provider", "provider_trade_no", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_items_tenant_id_refund_no_provider_~", + table: "commerce_reconciliation_items", + columns: new[] { "tenant_id", "refund_no", "provider_refund_no", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_reconciliation_items_tenant_id_refund_request_id", + table: "commerce_reconciliation_items", + columns: new[] { "tenant_id", "refund_request_id" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_refund_events_actor_user_id", + table: "commerce_refund_events", + column: "actor_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_commerce_refund_events_tenant_id_refund_request_id_created_~", + table: "commerce_refund_events", + columns: new[] { "tenant_id", "refund_request_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_refund_requests_processed_by", + table: "commerce_refund_requests", + column: "processed_by"); + + migrationBuilder.CreateIndex( + name: "ix_commerce_refund_requests_requested_by", + table: "commerce_refund_requests", + column: "requested_by"); + + migrationBuilder.CreateIndex( + name: "ix_commerce_refund_requests_reviewed_by", + table: "commerce_refund_requests", + column: "reviewed_by"); + + migrationBuilder.CreateIndex( + name: "ix_commerce_refund_requests_tenant_id_order_id_created_at", + table: "commerce_refund_requests", + columns: new[] { "tenant_id", "order_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_refund_requests_tenant_id_payment_id", + table: "commerce_refund_requests", + columns: new[] { "tenant_id", "payment_id" }); + + migrationBuilder.CreateIndex( + name: "ix_commerce_refund_requests_tenant_id_refund_no", + table: "commerce_refund_requests", + columns: new[] { "tenant_id", "refund_no" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_commerce_refund_requests_tenant_id_status_created_at", + table: "commerce_refund_requests", + columns: new[] { "tenant_id", "status", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commission_settlement_items_referrer_user_id", + table: "commission_settlement_items", + column: "referrer_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_commission_settlement_items_student_user_id", + table: "commission_settlement_items", + column: "student_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_commission_settlement_items_tenant_id_referrer_user_id_sour~", + table: "commission_settlement_items", + columns: new[] { "tenant_id", "referrer_user_id", "source_paid_at" }); + + migrationBuilder.CreateIndex( + name: "ix_commission_settlement_items_tenant_id_settlement_id", + table: "commission_settlement_items", + columns: new[] { "tenant_id", "settlement_id" }); + + migrationBuilder.CreateIndex( + name: "ix_commission_settlement_items_tenant_id_source_type_source_id", + table: "commission_settlement_items", + columns: new[] { "tenant_id", "source_type", "source_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_commission_settlements_generated_by", + table: "commission_settlements", + column: "generated_by"); + + migrationBuilder.CreateIndex( + name: "ix_commission_settlements_paid_by", + table: "commission_settlements", + column: "paid_by"); + + migrationBuilder.CreateIndex( + name: "ix_commission_settlements_referrer_start", + table: "commission_settlements", + columns: new[] { "tenant_id", "referrer_user_id", "period_start" }); + + migrationBuilder.CreateIndex( + name: "ix_commission_settlements_referrer_user_id", + table: "commission_settlements", + column: "referrer_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_commission_settlements_reviewed_by", + table: "commission_settlements", + column: "reviewed_by"); + + migrationBuilder.CreateIndex( + name: "ix_commission_settlements_tenant_id_settlement_no", + table: "commission_settlements", + columns: new[] { "tenant_id", "settlement_no" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ux_commission_settlements_referrer_period", + table: "commission_settlements", + columns: new[] { "tenant_id", "referrer_user_id", "period_start", "period_end" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_content_asset_access_events_tenant_id_access_type_result_cr~", + table: "content_asset_access_events", + columns: new[] { "tenant_id", "access_type", "result", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_content_asset_access_events_tenant_id_asset_id_created_at", + table: "content_asset_access_events", + columns: new[] { "tenant_id", "asset_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_content_asset_access_events_tenant_id_user_id_created_at", + table: "content_asset_access_events", + columns: new[] { "tenant_id", "user_id", "created_at" }, + filter: "user_id is not null"); + + migrationBuilder.CreateIndex( + name: "ix_content_asset_access_events_user_id", + table: "content_asset_access_events", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_content_asset_security_scan_events_tenant_id_asset_id_creat~", + table: "content_asset_security_scan_events", + columns: new[] { "tenant_id", "asset_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_content_asset_security_scan_events_tenant_id_scan_status_ri~", + table: "content_asset_security_scan_events", + columns: new[] { "tenant_id", "scan_status", "risk_level", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_created_by", + table: "content_assets", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_tenant_id_category_id", + table: "content_assets", + columns: new[] { "tenant_id", "category_id" }); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_tenant_id_checksum_sha256", + table: "content_assets", + columns: new[] { "tenant_id", "checksum_sha256" }, + filter: "checksum_sha256 is not null"); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_tenant_id_content_node_id", + table: "content_assets", + columns: new[] { "tenant_id", "content_node_id" }); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_tenant_id_legacy_id", + table: "content_assets", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_tenant_id_preview_status", + table: "content_assets", + columns: new[] { "tenant_id", "preview_status" }, + filter: "preview_status <> 'none'"); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_tenant_id_region_id", + table: "content_assets", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_tenant_id_security_scan_status_upload_status~", + table: "content_assets", + columns: new[] { "tenant_id", "security_scan_status", "upload_status", "status", "updated_at" }); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_tenant_id_status_visibility_asset_type_regio~", + table: "content_assets", + columns: new[] { "tenant_id", "status", "visibility", "asset_type", "region_id", "subject_id", "category_id", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_tenant_id_storage_provider_bucket_object_key", + table: "content_assets", + columns: new[] { "tenant_id", "storage_provider", "bucket", "object_key" }); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_tenant_id_subject_id", + table: "content_assets", + columns: new[] { "tenant_id", "subject_id" }); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_tenant_id_upload_status_status_updated_at", + table: "content_assets", + columns: new[] { "tenant_id", "upload_status", "status", "updated_at" }); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_updated_by", + table: "content_assets", + column: "updated_by"); + + migrationBuilder.CreateIndex( + name: "ix_content_assets_verified_by", + table: "content_assets", + column: "verified_by"); + + migrationBuilder.CreateIndex( + name: "ix_content_entries_created_by", + table: "content_entries", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_content_entries_tenant_id_entry_key", + table: "content_entries", + columns: new[] { "tenant_id", "entry_key" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_content_entries_tenant_id_legacy_id", + table: "content_entries", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_content_entries_tenant_id_region_id_entry_type_is_active_so~", + table: "content_entries", + columns: new[] { "tenant_id", "region_id", "entry_type", "is_active", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_content_entries_updated_by", + table: "content_entries", + column: "updated_by"); + + migrationBuilder.CreateIndex( + name: "ix_content_import_issues_tenant_id_item_id", + table: "content_import_issues", + columns: new[] { "tenant_id", "item_id" }); + + migrationBuilder.CreateIndex( + name: "ix_content_import_issues_tenant_id_job_id_severity_row_no", + table: "content_import_issues", + columns: new[] { "tenant_id", "job_id", "severity", "row_no" }); + + migrationBuilder.CreateIndex( + name: "ix_content_import_items_job_id_row_no", + table: "content_import_items", + columns: new[] { "job_id", "row_no" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_content_import_items_tenant_id_job_id_status_row_no", + table: "content_import_items", + columns: new[] { "tenant_id", "job_id", "status", "row_no" }); + + migrationBuilder.CreateIndex( + name: "ix_content_import_jobs_created_by", + table: "content_import_jobs", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_content_import_jobs_tenant_id_import_type_status_created_at", + table: "content_import_jobs", + columns: new[] { "tenant_id", "import_type", "status", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_content_import_jobs_tenant_id_target_category_id", + table: "content_import_jobs", + columns: new[] { "tenant_id", "target_category_id" }); + + migrationBuilder.CreateIndex( + name: "ix_content_import_jobs_tenant_id_target_content_node_id", + table: "content_import_jobs", + columns: new[] { "tenant_id", "target_content_node_id" }); + + migrationBuilder.CreateIndex( + name: "ix_content_import_jobs_tenant_id_target_question_bank_id", + table: "content_import_jobs", + columns: new[] { "tenant_id", "target_question_bank_id" }); + + migrationBuilder.CreateIndex( + name: "ix_content_import_jobs_tenant_id_target_region_id", + table: "content_import_jobs", + columns: new[] { "tenant_id", "target_region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_content_import_jobs_tenant_id_target_subject_id", + table: "content_import_jobs", + columns: new[] { "tenant_id", "target_subject_id" }); + + migrationBuilder.CreateIndex( + name: "ix_content_nodes_created_by", + table: "content_nodes", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_content_nodes_path", + table: "content_nodes", + column: "path") + .Annotation("Npgsql:IndexMethod", "gist"); + + migrationBuilder.CreateIndex( + name: "ix_content_nodes_tenant_id_entry_id_node_key", + table: "content_nodes", + columns: new[] { "tenant_id", "entry_id", "node_key" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_content_nodes_tenant_id_entry_id_parent_id_sort_order", + table: "content_nodes", + columns: new[] { "tenant_id", "entry_id", "parent_id", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_content_nodes_tenant_id_legacy_id", + table: "content_nodes", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_content_nodes_tenant_id_marker_type", + table: "content_nodes", + columns: new[] { "tenant_id", "marker_type" }, + filter: "marker_type is not null"); + + migrationBuilder.CreateIndex( + name: "ix_content_nodes_tenant_id_parent_id", + table: "content_nodes", + columns: new[] { "tenant_id", "parent_id" }); + + migrationBuilder.CreateIndex( + name: "ix_content_nodes_tenant_id_region_id", + table: "content_nodes", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_content_nodes_updated_by", + table: "content_nodes", + column: "updated_by"); + + migrationBuilder.CreateIndex( + name: "ix_coupon_redemptions_tenant_id_coupon_id", + table: "coupon_redemptions", + columns: new[] { "tenant_id", "coupon_id" }); + + migrationBuilder.CreateIndex( + name: "ix_coupon_redemptions_tenant_id_legacy_id", + table: "coupon_redemptions", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_coupon_redemptions_tenant_id_order_id_user_id", + table: "coupon_redemptions", + columns: new[] { "tenant_id", "order_id", "user_id" }, + filter: "order_id is not null"); + + migrationBuilder.CreateIndex( + name: "ix_coupon_redemptions_tenant_id_plan_id", + table: "coupon_redemptions", + columns: new[] { "tenant_id", "plan_id" }); + + migrationBuilder.CreateIndex( + name: "ix_coupon_redemptions_tenant_id_region_id", + table: "coupon_redemptions", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_coupon_redemptions_tenant_id_user_id_coupon_id", + table: "coupon_redemptions", + columns: new[] { "tenant_id", "user_id", "coupon_id" }, + unique: true, + filter: "coupon_id is not null"); + + migrationBuilder.CreateIndex( + name: "ix_coupon_redemptions_user_id", + table: "coupon_redemptions", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_coupons_tenant_id_code", + table: "coupons", + columns: new[] { "tenant_id", "code" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_coupons_tenant_id_legacy_id", + table: "coupons", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_coupons_tenant_id_plan_id", + table: "coupons", + columns: new[] { "tenant_id", "plan_id" }); + + migrationBuilder.CreateIndex( + name: "ix_crm_config_tenant_id", + table: "crm_config", + column: "tenant_id", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_crm_config_tenant_id_assignment_mode", + table: "crm_config", + columns: new[] { "tenant_id", "assignment_mode" }); + + migrationBuilder.CreateIndex( + name: "ix_crm_webhook_log_tenant_id_legacy_id", + table: "crm_webhook_log", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_crm_webhook_log_tenant_id_record_id_created_at", + table: "crm_webhook_log", + columns: new[] { "tenant_id", "record_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_crm_webhook_queue_tenant_id_idempotency_key", + table: "crm_webhook_queue", + columns: new[] { "tenant_id", "idempotency_key" }, + unique: true, + filter: "idempotency_key is not null"); + + migrationBuilder.CreateIndex( + name: "ix_crm_webhook_queue_tenant_id_legacy_id", + table: "crm_webhook_queue", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_crm_webhook_queue_tenant_id_record_id", + table: "crm_webhook_queue", + columns: new[] { "tenant_id", "record_id" }, + unique: true, + filter: "record_id is not null"); + + migrationBuilder.CreateIndex( + name: "ix_crm_webhook_queue_tenant_id_record_id_created_at", + table: "crm_webhook_queue", + columns: new[] { "tenant_id", "record_id", "created_at" }, + filter: "record_id is not null"); + + migrationBuilder.CreateIndex( + name: "ix_crm_webhook_queue_tenant_id_source_created_at", + table: "crm_webhook_queue", + columns: new[] { "tenant_id", "source", "created_at" }, + filter: "source = 'tenant.student.crm_push'"); + + migrationBuilder.CreateIndex( + name: "ix_crm_webhook_queue_tenant_id_status_scheduled_at_next_attemp~", + table: "crm_webhook_queue", + columns: new[] { "tenant_id", "status", "scheduled_at", "next_attempt_at" }); + + migrationBuilder.CreateIndex( + name: "ix_dashboard_daily_stats_tenant_id_legacy_id", + table: "dashboard_daily_stats", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_dashboard_daily_stats_tenant_id_region_id", + table: "dashboard_daily_stats", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_dashboard_daily_stats_tenant_id_stat_date_region_id", + table: "dashboard_daily_stats", + columns: new[] { "tenant_id", "stat_date", "region_id" }, + unique: true) + .Annotation("Npgsql:NullsDistinct", false); + + migrationBuilder.CreateIndex( + name: "ix_entitlements_revoked_by", + table: "entitlements", + column: "revoked_by"); + + migrationBuilder.CreateIndex( + name: "ix_entitlements_tenant_id_user_id_status_expires_at", + table: "entitlements", + columns: new[] { "tenant_id", "user_id", "status", "expires_at" }); + + migrationBuilder.CreateIndex( + name: "ix_entitlements_user_id", + table: "entitlements", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_exam_dates_tenant_id_legacy_id", + table: "exam_dates", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_exam_dates_tenant_id_region_id", + table: "exam_dates", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_exam_dates_tenant_id_school_id_exam_at", + table: "exam_dates", + columns: new[] { "tenant_id", "school_id", "exam_at" }); + + migrationBuilder.CreateIndex( + name: "ix_faqs_tenant_id_legacy_id", + table: "faqs", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_faqs_tenant_id_region_id_is_active_sort_order", + table: "faqs", + columns: new[] { "tenant_id", "region_id", "is_active", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_favorite_questions_tenant_id_question_id", + table: "favorite_questions", + columns: new[] { "tenant_id", "question_id" }); + + migrationBuilder.CreateIndex( + name: "ix_favorite_questions_user_id", + table: "favorite_questions", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_handbook_chapters_tenant_id_content_node_id", + table: "handbook_chapters", + columns: new[] { "tenant_id", "content_node_id" }); + + migrationBuilder.CreateIndex( + name: "ix_handbook_chapters_tenant_id_entry_id_content_node_id_subjec~", + table: "handbook_chapters", + columns: new[] { "tenant_id", "entry_id", "content_node_id", "subject_id", "is_active", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_handbook_chapters_tenant_id_legacy_id", + table: "handbook_chapters", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_handbook_chapters_tenant_id_subject_id", + table: "handbook_chapters", + columns: new[] { "tenant_id", "subject_id" }); + + migrationBuilder.CreateIndex( + name: "ix_handbook_entries_tenant_id_chapter_id", + table: "handbook_entries", + columns: new[] { "tenant_id", "chapter_id" }); + + migrationBuilder.CreateIndex( + name: "ix_handbook_entries_tenant_id_content_node_id", + table: "handbook_entries", + columns: new[] { "tenant_id", "content_node_id" }); + + migrationBuilder.CreateIndex( + name: "ix_handbook_entries_tenant_id_entry_id_content_node_id_chapter~", + table: "handbook_entries", + columns: new[] { "tenant_id", "entry_id", "content_node_id", "chapter_id", "is_active", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_handbook_entries_tenant_id_legacy_id", + table: "handbook_entries", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_handbook_subjects_tenant_id_content_node_id", + table: "handbook_subjects", + columns: new[] { "tenant_id", "content_node_id" }); + + migrationBuilder.CreateIndex( + name: "ix_handbook_subjects_tenant_id_entry_id_content_node_id_region~", + table: "handbook_subjects", + columns: new[] { "tenant_id", "entry_id", "content_node_id", "region_id", "is_active", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_handbook_subjects_tenant_id_legacy_id", + table: "handbook_subjects", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_handbook_subjects_tenant_id_major_id", + table: "handbook_subjects", + columns: new[] { "tenant_id", "major_id" }); + + migrationBuilder.CreateIndex( + name: "ix_handbook_subjects_tenant_id_region_id", + table: "handbook_subjects", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_handbook_subjects_tenant_id_school_id", + table: "handbook_subjects", + columns: new[] { "tenant_id", "school_id" }); + + migrationBuilder.CreateIndex( + name: "ix_images_tenant_id_category_is_public", + table: "images", + columns: new[] { "tenant_id", "category", "is_public" }); + + migrationBuilder.CreateIndex( + name: "ix_images_tenant_id_legacy_id", + table: "images", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_majors_tenant_id_legacy_id", + table: "majors", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_majors_tenant_id_region_id", + table: "majors", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_majors_tenant_id_school_id", + table: "majors", + columns: new[] { "tenant_id", "school_id" }); + + migrationBuilder.CreateIndex( + name: "ix_module_nodes_tenant_id_legacy_id", + table: "module_nodes", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_module_nodes_tenant_id_module_id", + table: "module_nodes", + columns: new[] { "tenant_id", "module_id" }); + + migrationBuilder.CreateIndex( + name: "ix_module_nodes_tenant_id_parent_id", + table: "module_nodes", + columns: new[] { "tenant_id", "parent_id" }); + + migrationBuilder.CreateIndex( + name: "ix_module_nodes_tenant_id_region_id", + table: "module_nodes", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_order_items_tenant_id_legacy_id", + table: "order_items", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_order_items_tenant_id_order_id", + table: "order_items", + columns: new[] { "tenant_id", "order_id" }); + + migrationBuilder.CreateIndex( + name: "ix_orders_tenant_id_legacy_id", + table: "orders", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_orders_tenant_id_order_no", + table: "orders", + columns: new[] { "tenant_id", "order_no" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_orders_tenant_id_plan_id", + table: "orders", + columns: new[] { "tenant_id", "plan_id" }); + + migrationBuilder.CreateIndex( + name: "ix_orders_tenant_id_region_id", + table: "orders", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_orders_tenant_id_user_id_created_at", + table: "orders", + columns: new[] { "tenant_id", "user_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_orders_user_id", + table: "orders", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_payment_events_provider_event_id", + table: "payment_events", + columns: new[] { "provider", "event_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_payment_events_tenant_id_payment_id", + table: "payment_events", + columns: new[] { "tenant_id", "payment_id" }); + + migrationBuilder.CreateIndex( + name: "ix_payments_provider_provider_trade_no", + table: "payments", + columns: new[] { "provider", "provider_trade_no" }, + unique: true, + filter: "provider_trade_no is not null"); + + migrationBuilder.CreateIndex( + name: "ix_payments_tenant_id_legacy_id", + table: "payments", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_payments_tenant_id_order_id_updated_at", + table: "payments", + columns: new[] { "tenant_id", "order_id", "updated_at" }); + + migrationBuilder.CreateIndex( + name: "ix_pb_import_issues_run_id_severity_collection_name", + table: "pb_import_issues", + columns: new[] { "run_id", "severity", "collection_name" }); + + migrationBuilder.CreateIndex( + name: "ix_pb_import_issues_tenant_id_collection_name_legacy_id", + table: "pb_import_issues", + columns: new[] { "tenant_id", "collection_name", "legacy_id" }); + + migrationBuilder.CreateIndex( + name: "ix_pb_import_issues_tenant_id_run_id", + table: "pb_import_issues", + columns: new[] { "tenant_id", "run_id" }); + + migrationBuilder.CreateIndex( + name: "ix_pb_import_runs_tenant_id_status_started_at", + table: "pb_import_runs", + columns: new[] { "tenant_id", "status", "started_at" }); + + migrationBuilder.CreateIndex( + name: "ix_pb_raw_records_tenant_id_collection_name_legacy_id", + table: "pb_raw_records", + columns: new[] { "tenant_id", "collection_name", "legacy_id" }); + + migrationBuilder.CreateIndex( + name: "ix_pb_raw_records_tenant_id_run_id", + table: "pb_raw_records", + columns: new[] { "tenant_id", "run_id" }); + + migrationBuilder.CreateIndex( + name: "ix_platform_audit_alert_rules_code", + table: "platform_audit_alert_rules", + column: "code", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_platform_audit_alert_rules_enabled_severity_code", + table: "platform_audit_alert_rules", + columns: new[] { "enabled", "severity", "code" }); + + migrationBuilder.CreateIndex( + name: "ix_platform_audit_alert_rules_tenant_id", + table: "platform_audit_alert_rules", + column: "tenant_id"); + + migrationBuilder.CreateIndex( + name: "ix_platform_audit_alerts_acknowledged_by", + table: "platform_audit_alerts", + column: "acknowledged_by"); + + migrationBuilder.CreateIndex( + name: "ix_platform_audit_alerts_audit_log_id", + table: "platform_audit_alerts", + column: "audit_log_id"); + + migrationBuilder.CreateIndex( + name: "ix_platform_audit_alerts_resolved_by", + table: "platform_audit_alerts", + column: "resolved_by"); + + migrationBuilder.CreateIndex( + name: "ix_platform_audit_alerts_rule_id_audit_log_id", + table: "platform_audit_alerts", + columns: new[] { "rule_id", "audit_log_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_platform_audit_alerts_status_severity_created_at", + table: "platform_audit_alerts", + columns: new[] { "status", "severity", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_platform_audit_alerts_tenant_id_status_created_at", + table: "platform_audit_alerts", + columns: new[] { "tenant_id", "status", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_platform_dunning_notification_channels_channel_code", + table: "platform_dunning_notification_channels", + column: "channel_code", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_platform_dunning_notification_channels_enabled_min_reminder~", + table: "platform_dunning_notification_channels", + columns: new[] { "enabled", "min_reminder_level", "channel_code" }); + + migrationBuilder.CreateIndex( + name: "ix_platform_dunning_notification_events_channel_id_reminder_id", + table: "platform_dunning_notification_events", + columns: new[] { "channel_id", "reminder_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_platform_dunning_notification_events_invoice_id_status_crea~", + table: "platform_dunning_notification_events", + columns: new[] { "invoice_id", "status", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_platform_dunning_notification_events_reminder_id_status_cre~", + table: "platform_dunning_notification_events", + columns: new[] { "reminder_id", "status", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_platform_dunning_notification_events_status_next_attempt_at~", + table: "platform_dunning_notification_events", + columns: new[] { "status", "next_attempt_at", "scheduled_at", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_platform_dunning_notification_events_tenant_id_invoice_id", + table: "platform_dunning_notification_events", + columns: new[] { "tenant_id", "invoice_id" }); + + migrationBuilder.CreateIndex( + name: "ix_platform_dunning_notification_events_tenant_id_reminder_id", + table: "platform_dunning_notification_events", + columns: new[] { "tenant_id", "reminder_id" }); + + migrationBuilder.CreateIndex( + name: "ix_platform_dunning_notification_events_tenant_id_status_creat~", + table: "platform_dunning_notification_events", + columns: new[] { "tenant_id", "status", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_platform_saas_plans_code", + table: "platform_saas_plans", + column: "code", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_platform_saas_plans_status_sort_order", + table: "platform_saas_plans", + columns: new[] { "status", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_access_events_tenant_id_practice_session_id", + table: "practice_access_events", + columns: new[] { "tenant_id", "practice_session_id" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_access_events_tenant_id_user_id_created_at", + table: "practice_access_events", + columns: new[] { "tenant_id", "user_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_access_events_user_id", + table: "practice_access_events", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_practice_blueprints_created_by", + table: "practice_blueprints", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_practice_blueprints_tenant_id_collection_id", + table: "practice_blueprints", + columns: new[] { "tenant_id", "collection_id" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_blueprints_tenant_id_entry_id", + table: "practice_blueprints", + columns: new[] { "tenant_id", "entry_id" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_blueprints_tenant_id_legacy_id", + table: "practice_blueprints", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_practice_blueprints_tenant_id_node_id_collection_id_mode_st~", + table: "practice_blueprints", + columns: new[] { "tenant_id", "node_id", "collection_id", "mode", "status", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_blueprints_tenant_id_region_id", + table: "practice_blueprints", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_blueprints_updated_by", + table: "practice_blueprints", + column: "updated_by"); + + migrationBuilder.CreateIndex( + name: "ix_practice_daily_usage_tenant_id_user_id_usage_date", + table: "practice_daily_usage", + columns: new[] { "tenant_id", "user_id", "usage_date" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_daily_usage_tenant_id_user_id_usage_date_scope_typ~", + table: "practice_daily_usage", + columns: new[] { "tenant_id", "user_id", "usage_date", "scope_type", "scope_id" }, + unique: true) + .Annotation("Npgsql:NullsDistinct", false); + + migrationBuilder.CreateIndex( + name: "ix_practice_daily_usage_user_id", + table: "practice_daily_usage", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_practice_session_report_sections_tenant_id_practice_session~", + table: "practice_session_report_sections", + columns: new[] { "tenant_id", "practice_session_id" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_session_report_sections_tenant_id_report_id_sectio~", + table: "practice_session_report_sections", + columns: new[] { "tenant_id", "report_id", "section_key" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_practice_session_report_sections_tenant_id_report_id_sort_o~", + table: "practice_session_report_sections", + columns: new[] { "tenant_id", "report_id", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_session_reports_tenant_id_blueprint_id_submitted_at", + table: "practice_session_reports", + columns: new[] { "tenant_id", "blueprint_id", "submitted_at" }, + filter: "blueprint_id is not null"); + + migrationBuilder.CreateIndex( + name: "ix_practice_session_reports_tenant_id_collection_id", + table: "practice_session_reports", + columns: new[] { "tenant_id", "collection_id" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_session_reports_tenant_id_practice_session_id", + table: "practice_session_reports", + columns: new[] { "tenant_id", "practice_session_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_practice_session_reports_tenant_id_user_id_submitted_at", + table: "practice_session_reports", + columns: new[] { "tenant_id", "user_id", "submitted_at" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_session_reports_user_id", + table: "practice_session_reports", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_practice_sessions_tenant_id_blueprint_id", + table: "practice_sessions", + columns: new[] { "tenant_id", "blueprint_id" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_sessions_tenant_id_collection_id", + table: "practice_sessions", + columns: new[] { "tenant_id", "collection_id" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_sessions_tenant_id_content_node_id", + table: "practice_sessions", + columns: new[] { "tenant_id", "content_node_id" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_sessions_tenant_id_entry_id", + table: "practice_sessions", + columns: new[] { "tenant_id", "entry_id" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_sessions_tenant_id_user_id_started_at", + table: "practice_sessions", + columns: new[] { "tenant_id", "user_id", "started_at" }); + + migrationBuilder.CreateIndex( + name: "ix_practice_sessions_user_id", + table: "practice_sessions", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_products_tenant_id_legacy_id", + table: "products", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_products_tenant_id_region_id_type_sort_order", + table: "products", + columns: new[] { "tenant_id", "region_id", "type", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_question_bank_grants_allowed_plan_codes", + table: "question_bank_grants", + column: "allowed_plan_codes") + .Annotation("Npgsql:IndexMethod", "gin"); + + migrationBuilder.CreateIndex( + name: "ix_question_bank_grants_allowed_tenant_ids", + table: "question_bank_grants", + column: "allowed_tenant_ids") + .Annotation("Npgsql:IndexMethod", "gin"); + + migrationBuilder.CreateIndex( + name: "ix_question_bank_grants_created_by", + table: "question_bank_grants", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_question_bank_grants_source_question_bank_id_status_starts_~", + table: "question_bank_grants", + columns: new[] { "source_question_bank_id", "status", "starts_at", "expires_at" }); + + migrationBuilder.CreateIndex( + name: "ix_question_bank_grants_updated_by", + table: "question_bank_grants", + column: "updated_by"); + + migrationBuilder.CreateIndex( + name: "ix_question_banks_tenant_id_region_id", + table: "question_banks", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_question_collection_items_tenant_id_collection_id_question_~", + table: "question_collection_items", + columns: new[] { "tenant_id", "collection_id", "question_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_question_collection_items_tenant_id_collection_id_section_k~", + table: "question_collection_items", + columns: new[] { "tenant_id", "collection_id", "section_key", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_question_collection_items_tenant_id_question_id", + table: "question_collection_items", + columns: new[] { "tenant_id", "question_id" }); + + migrationBuilder.CreateIndex( + name: "ix_question_collections_created_by", + table: "question_collections", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_question_collections_tenant_id_category_id", + table: "question_collections", + columns: new[] { "tenant_id", "category_id" }); + + migrationBuilder.CreateIndex( + name: "ix_question_collections_tenant_id_entry_id", + table: "question_collections", + columns: new[] { "tenant_id", "entry_id" }); + + migrationBuilder.CreateIndex( + name: "ix_question_collections_tenant_id_legacy_id", + table: "question_collections", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_question_collections_tenant_id_node_id_status_sort_order", + table: "question_collections", + columns: new[] { "tenant_id", "node_id", "status", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_question_collections_tenant_id_question_bank_id", + table: "question_collections", + columns: new[] { "tenant_id", "question_bank_id" }); + + migrationBuilder.CreateIndex( + name: "ix_question_collections_tenant_id_region_id", + table: "question_collections", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_question_collections_tenant_id_subject_id", + table: "question_collections", + columns: new[] { "tenant_id", "subject_id" }); + + migrationBuilder.CreateIndex( + name: "ix_question_collections_updated_by", + table: "question_collections", + column: "updated_by"); + + migrationBuilder.CreateIndex( + name: "ix_question_type_groups_tenant_id_legacy_id", + table: "question_type_groups", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_question_type_groups_tenant_id_subject_id_is_active_sort_or~", + table: "question_type_groups", + columns: new[] { "tenant_id", "subject_id", "is_active", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_question_versions_created_by", + table: "question_versions", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_question_versions_question_id_version_no", + table: "question_versions", + columns: new[] { "question_id", "version_no" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_question_videos_tenant_id_legacy_id", + table: "question_videos", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_question_videos_tenant_id_question_id_video_id_video_type", + table: "question_videos", + columns: new[] { "tenant_id", "question_id", "video_id", "video_type" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_question_videos_tenant_id_video_id", + table: "question_videos", + columns: new[] { "tenant_id", "video_id" }); + + migrationBuilder.CreateIndex( + name: "ix_questions_tenant_id_category_id", + table: "questions", + columns: new[] { "tenant_id", "category_id" }); + + migrationBuilder.CreateIndex( + name: "ix_questions_tenant_id_content_node_id", + table: "questions", + columns: new[] { "tenant_id", "content_node_id" }); + + migrationBuilder.CreateIndex( + name: "ix_questions_tenant_id_entry_id", + table: "questions", + columns: new[] { "tenant_id", "entry_id" }); + + migrationBuilder.CreateIndex( + name: "ix_questions_tenant_id_id_current_version_id", + table: "questions", + columns: new[] { "tenant_id", "id", "current_version_id" }); + + migrationBuilder.CreateIndex( + name: "ix_questions_tenant_id_legacy_id", + table: "questions", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_questions_tenant_id_node_id", + table: "questions", + columns: new[] { "tenant_id", "node_id" }); + + migrationBuilder.CreateIndex( + name: "ix_questions_tenant_id_primary_collection_id", + table: "questions", + columns: new[] { "tenant_id", "primary_collection_id" }); + + migrationBuilder.CreateIndex( + name: "ix_questions_tenant_id_question_bank_id", + table: "questions", + columns: new[] { "tenant_id", "question_bank_id" }); + + migrationBuilder.CreateIndex( + name: "ix_questions_tenant_id_subject_id", + table: "questions", + columns: new[] { "tenant_id", "subject_id" }); + + migrationBuilder.CreateIndex( + name: "ix_recent_practices_tenant_id_legacy_id", + table: "recent_practices", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_recent_practices_tenant_id_user_id_last_access_at", + table: "recent_practices", + columns: new[] { "tenant_id", "user_id", "last_access_at" }); + + migrationBuilder.CreateIndex( + name: "ix_recent_practices_user_id", + table: "recent_practices", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_referral_codes_tenant_id_code", + table: "referral_codes", + columns: new[] { "tenant_id", "code" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_referral_codes_tenant_id_code_status", + table: "referral_codes", + columns: new[] { "tenant_id", "code", "status" }); + + migrationBuilder.CreateIndex( + name: "ix_referral_codes_tenant_id_user_id", + table: "referral_codes", + columns: new[] { "tenant_id", "user_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_referral_codes_user_id", + table: "referral_codes", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_referral_leads_assigned_by", + table: "referral_leads", + column: "assigned_by"); + + migrationBuilder.CreateIndex( + name: "ix_referral_leads_assigned_to_user_id", + table: "referral_leads", + column: "assigned_to_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_referral_leads_referrer_user_id", + table: "referral_leads", + column: "referrer_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_referral_leads_student_user_id", + table: "referral_leads", + column: "student_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_referral_leads_tenant_id_assigned_to_user_id_status_bound_at", + table: "referral_leads", + columns: new[] { "tenant_id", "assigned_to_user_id", "status", "bound_at" }); + + migrationBuilder.CreateIndex( + name: "ix_referral_leads_tenant_id_first_track_id", + table: "referral_leads", + columns: new[] { "tenant_id", "first_track_id" }); + + migrationBuilder.CreateIndex( + name: "ix_referral_leads_tenant_id_referrer_user_id_bound_at", + table: "referral_leads", + columns: new[] { "tenant_id", "referrer_user_id", "bound_at" }); + + migrationBuilder.CreateIndex( + name: "ix_referral_leads_tenant_id_student_user_id", + table: "referral_leads", + columns: new[] { "tenant_id", "student_user_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_referral_qrcodes_tenant_id_provider_scene_page", + table: "referral_qrcodes", + columns: new[] { "tenant_id", "provider", "scene", "page" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_referral_qrcodes_tenant_id_ref_code_status", + table: "referral_qrcodes", + columns: new[] { "tenant_id", "ref_code", "status" }); + + migrationBuilder.CreateIndex( + name: "ix_referral_qrcodes_user_id", + table: "referral_qrcodes", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_referral_team_edges_leader_user_id", + table: "referral_team_edges", + column: "leader_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_referral_team_edges_member_user_id", + table: "referral_team_edges", + column: "member_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_referral_team_edges_tenant_id_leader_user_id_status", + table: "referral_team_edges", + columns: new[] { "tenant_id", "leader_user_id", "status" }); + + migrationBuilder.CreateIndex( + name: "ix_referral_team_edges_tenant_id_member_user_id_relation_type", + table: "referral_team_edges", + columns: new[] { "tenant_id", "member_user_id", "relation_type" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_referral_tracks_referrer_user_id", + table: "referral_tracks", + column: "referrer_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_referral_tracks_target_user_id", + table: "referral_tracks", + column: "target_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_referral_tracks_tenant_id_lead_id_created_at", + table: "referral_tracks", + columns: new[] { "tenant_id", "lead_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_referral_tracks_tenant_id_legacy_id", + table: "referral_tracks", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_referral_tracks_tenant_id_ref_code_event_type_created_at", + table: "referral_tracks", + columns: new[] { "tenant_id", "ref_code", "event_type", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_region_modules_tenant_id_legacy_id", + table: "region_modules", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_region_modules_tenant_id_region_id", + table: "region_modules", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_regions_tenant_id_legacy_id", + table: "regions", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_report_status_events_actor_user_id", + table: "report_status_events", + column: "actor_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_report_status_events_tenant_id_report_id_created_at", + table: "report_status_events", + columns: new[] { "tenant_id", "report_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_reports_handled_by", + table: "reports", + column: "handled_by"); + + migrationBuilder.CreateIndex( + name: "ix_reports_tenant_id_legacy_id", + table: "reports", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_reports_tenant_id_question_id_created_at", + table: "reports", + columns: new[] { "tenant_id", "question_id", "created_at" }, + filter: "question_id is not null"); + + migrationBuilder.CreateIndex( + name: "ix_reports_tenant_id_status_created_at", + table: "reports", + columns: new[] { "tenant_id", "status", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_reports_user_id", + table: "reports", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_revenue_daily_stats_tenant_id_legacy_id", + table: "revenue_daily_stats", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_revenue_daily_stats_tenant_id_region_id", + table: "revenue_daily_stats", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_revenue_daily_stats_tenant_id_stat_date_region_id_sale_type", + table: "revenue_daily_stats", + columns: new[] { "tenant_id", "stat_date", "region_id", "sale_type" }, + unique: true) + .Annotation("Npgsql:NullsDistinct", false); + + migrationBuilder.CreateIndex( + name: "ix_schools_tenant_id_legacy_id", + table: "schools", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_schools_tenant_id_module_id", + table: "schools", + columns: new[] { "tenant_id", "module_id" }); + + migrationBuilder.CreateIndex( + name: "ix_schools_tenant_id_region_id", + table: "schools", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_sms_send_rate_limits_updated_at", + table: "sms_send_rate_limits", + column: "updated_at"); + + migrationBuilder.CreateIndex( + name: "ix_sms_verification_codes_tenant_id_phone_purpose", + table: "sms_verification_codes", + columns: new[] { "tenant_id", "phone", "purpose" }, + unique: true, + filter: "consumed_at is null and status in ('pending', 'sent')"); + + migrationBuilder.CreateIndex( + name: "ix_sms_verification_codes_tenant_id_phone_purpose_created_at", + table: "sms_verification_codes", + columns: new[] { "tenant_id", "phone", "purpose", "created_at" }, + filter: "consumed_at is null and status in ('pending', 'sent')"); + + migrationBuilder.CreateIndex( + name: "ix_sms_verification_codes_tenant_id_phone_purpose_expires_at", + table: "sms_verification_codes", + columns: new[] { "tenant_id", "phone", "purpose", "expires_at" }); + + migrationBuilder.CreateIndex( + name: "ix_student_profiles_tenant_id_region_id", + table: "student_profiles", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_student_profiles_tenant_id_selected_major_id", + table: "student_profiles", + columns: new[] { "tenant_id", "selected_major_id" }); + + migrationBuilder.CreateIndex( + name: "ix_student_profiles_tenant_id_selected_school_id", + table: "student_profiles", + columns: new[] { "tenant_id", "selected_school_id" }); + + migrationBuilder.CreateIndex( + name: "ix_student_profiles_tenant_id_user_id", + table: "student_profiles", + columns: new[] { "tenant_id", "user_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_student_profiles_user_id", + table: "student_profiles", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_subject_shares_tenant_id_target_subject_id", + table: "subject_shares", + columns: new[] { "tenant_id", "target_subject_id" }); + + migrationBuilder.CreateIndex( + name: "ix_subjects_tenant_id_legacy_id", + table: "subjects", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_subjects_tenant_id_major_id", + table: "subjects", + columns: new[] { "tenant_id", "major_id" }); + + migrationBuilder.CreateIndex( + name: "ix_subjects_tenant_id_module_id", + table: "subjects", + columns: new[] { "tenant_id", "module_id" }); + + migrationBuilder.CreateIndex( + name: "ix_subjects_tenant_id_node_id", + table: "subjects", + columns: new[] { "tenant_id", "node_id" }); + + migrationBuilder.CreateIndex( + name: "ix_subjects_tenant_id_region_id", + table: "subjects", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_subjects_tenant_id_school_id", + table: "subjects", + columns: new[] { "tenant_id", "school_id" }); + + migrationBuilder.CreateIndex( + name: "ix_svip_plans_tenant_id_legacy_id", + table: "svip_plans", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_svip_plans_tenant_id_region_id_is_active_sort_order", + table: "svip_plans", + columns: new[] { "tenant_id", "region_id", "is_active", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_auth_providers_tenant_id_provider", + table: "tenant_auth_providers", + columns: new[] { "tenant_id", "provider" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_auth_providers_tenant_id_provider_status", + table: "tenant_auth_providers", + columns: new[] { "tenant_id", "provider", "status" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_class_members_tenant_id_class_id_status_member_type", + table: "tenant_class_members", + columns: new[] { "tenant_id", "class_id", "status", "member_type" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_class_members_tenant_id_class_id_user_id_member_type", + table: "tenant_class_members", + columns: new[] { "tenant_id", "class_id", "user_id", "member_type" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_class_members_tenant_id_user_id_status_member_type", + table: "tenant_class_members", + columns: new[] { "tenant_id", "user_id", "status", "member_type" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_class_members_user_id", + table: "tenant_class_members", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_classes_created_by", + table: "tenant_classes", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_classes_tenant_id_code", + table: "tenant_classes", + columns: new[] { "tenant_id", "code" }, + unique: true, + filter: "code is not null and code <> ''"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_classes_tenant_id_legacy_id", + table: "tenant_classes", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_classes_tenant_id_region_id", + table: "tenant_classes", + columns: new[] { "tenant_id", "region_id" }, + filter: "region_id is not null"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_classes_tenant_id_status_sort_order_created_at", + table: "tenant_classes", + columns: new[] { "tenant_id", "status", "sort_order", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_classes_updated_by", + table: "tenant_classes", + column: "updated_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_commission_settings_tenant_id", + table: "tenant_commission_settings", + column: "tenant_id", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_commission_settings_updated_by", + table: "tenant_commission_settings", + column: "updated_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_content_notifications_created_by", + table: "tenant_content_notifications", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_content_notifications_read_by", + table: "tenant_content_notifications", + column: "read_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_content_notifications_tenant_id_adoption_id_notifica~", + table: "tenant_content_notifications", + columns: new[] { "tenant_id", "adoption_id", "notification_type", "status" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_content_notifications_tenant_id_notification_type_de~", + table: "tenant_content_notifications", + columns: new[] { "tenant_id", "notification_type", "dedupe_key" }, + unique: true, + filter: "dedupe_key is not null"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_content_notifications_tenant_id_source_question_bank~", + table: "tenant_content_notifications", + columns: new[] { "tenant_id", "source_question_bank_id" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_content_notifications_tenant_id_status_created_at", + table: "tenant_content_notifications", + columns: new[] { "tenant_id", "status", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_domains_host", + table: "tenant_domains", + column: "host", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_domains_tenant_id_is_primary", + table: "tenant_domains", + columns: new[] { "tenant_id", "is_primary" }, + unique: true, + filter: "is_primary"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoice_items_invoice_id", + table: "tenant_invoice_items", + column: "invoice_id"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoice_items_tenant_id_invoice_id", + table: "tenant_invoice_items", + columns: new[] { "tenant_id", "invoice_id" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoice_payments_invoice_id_status", + table: "tenant_invoice_payments", + columns: new[] { "invoice_id", "status" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoice_payments_payment_no", + table: "tenant_invoice_payments", + column: "payment_no", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoice_payments_received_by", + table: "tenant_invoice_payments", + column: "received_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoice_payments_tenant_id_invoice_id", + table: "tenant_invoice_payments", + columns: new[] { "tenant_id", "invoice_id" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoice_reminders_created_by", + table: "tenant_invoice_reminders", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoice_reminders_invoice_id_reminder_date", + table: "tenant_invoice_reminders", + columns: new[] { "invoice_id", "reminder_date" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoice_reminders_tenant_id_invoice_id_reminder_type~", + table: "tenant_invoice_reminders", + columns: new[] { "tenant_id", "invoice_id", "reminder_type", "channel", "reminder_date" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoice_reminders_tenant_id_status_reminder_date", + table: "tenant_invoice_reminders", + columns: new[] { "tenant_id", "status", "reminder_date" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoices_created_by", + table: "tenant_invoices", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoices_invoice_no", + table: "tenant_invoices", + column: "invoice_no", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoices_tenant_id_billing_period_start_billing_peri~", + table: "tenant_invoices", + columns: new[] { "tenant_id", "billing_period_start", "billing_period_end" }, + unique: true, + filter: "invoice_type = 'usage_overage' and status <> 'void' and metadata->>'source' = 'usage_overage_auto'"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_invoices_tenant_id_status_due_date", + table: "tenant_invoices", + columns: new[] { "tenant_id", "status", "due_date" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_memberships_tenant_id_role_template_id", + table: "tenant_memberships", + columns: new[] { "tenant_id", "role_template_id" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_memberships_tenant_id_user_id_role", + table: "tenant_memberships", + columns: new[] { "tenant_id", "user_id", "role" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_memberships_user_id", + table: "tenant_memberships", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_payment_accounts_tenant_id_provider", + table: "tenant_payment_accounts", + columns: new[] { "tenant_id", "provider" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_question_bank_adoptions_created_by", + table: "tenant_question_bank_adoptions", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_question_bank_adoptions_grant_id", + table: "tenant_question_bank_adoptions", + column: "grant_id"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_question_bank_adoptions_source_question_bank_id", + table: "tenant_question_bank_adoptions", + column: "source_question_bank_id"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_question_bank_adoptions_tenant_id_source_question_ba~", + table: "tenant_question_bank_adoptions", + columns: new[] { "tenant_id", "source_question_bank_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_question_bank_adoptions_tenant_id_status_updated_at", + table: "tenant_question_bank_adoptions", + columns: new[] { "tenant_id", "status", "updated_at" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_question_bank_adoptions_tenant_id_target_collection_~", + table: "tenant_question_bank_adoptions", + columns: new[] { "tenant_id", "target_collection_id" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_question_bank_adoptions_tenant_id_target_entry_id", + table: "tenant_question_bank_adoptions", + columns: new[] { "tenant_id", "target_entry_id" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_question_bank_adoptions_tenant_id_target_question_ba~", + table: "tenant_question_bank_adoptions", + columns: new[] { "tenant_id", "target_question_bank_id" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_question_bank_adoptions_updated_by", + table: "tenant_question_bank_adoptions", + column: "updated_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_role_templates_created_by", + table: "tenant_role_templates", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_role_templates_tenant_id_code", + table: "tenant_role_templates", + columns: new[] { "tenant_id", "code" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_role_templates_tenant_id_status_sort_order", + table: "tenant_role_templates", + columns: new[] { "tenant_id", "status", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_role_templates_updated_by", + table: "tenant_role_templates", + column: "updated_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_student_followups_assigned_to_user_id", + table: "tenant_student_followups", + column: "assigned_to_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_student_followups_completed_by", + table: "tenant_student_followups", + column: "completed_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_student_followups_student_user_id", + table: "tenant_student_followups", + column: "student_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_student_followups_tenant_id_assigned_to_user_id_stat~", + table: "tenant_student_followups", + columns: new[] { "tenant_id", "assigned_to_user_id", "status", "due_at" }, + filter: "assigned_to_user_id is not null"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_student_followups_tenant_id_class_id_status_due_at", + table: "tenant_student_followups", + columns: new[] { "tenant_id", "class_id", "status", "due_at" }, + filter: "class_id is not null"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_student_followups_tenant_id_student_user_id_status_d~", + table: "tenant_student_followups", + columns: new[] { "tenant_id", "student_user_id", "status", "due_at", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_student_notes_created_by", + table: "tenant_student_notes", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_student_notes_student_user_id", + table: "tenant_student_notes", + column: "student_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_student_notes_tenant_id_created_by_created_at", + table: "tenant_student_notes", + columns: new[] { "tenant_id", "created_by", "created_at" }, + filter: "created_by is not null"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_student_notes_tenant_id_student_user_id_is_pinned_cr~", + table: "tenant_student_notes", + columns: new[] { "tenant_id", "student_user_id", "is_pinned", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_student_notes_updated_by", + table: "tenant_student_notes", + column: "updated_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_subscriptions_tenant_id_status_expires_at", + table: "tenant_subscriptions", + columns: new[] { "tenant_id", "status", "expires_at" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_theme_configs_active_template_code", + table: "tenant_theme_configs", + column: "active_template_code"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_theme_configs_draft_template_code", + table: "tenant_theme_configs", + column: "draft_template_code"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_theme_configs_draft_updated_by", + table: "tenant_theme_configs", + column: "draft_updated_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_theme_configs_published_by", + table: "tenant_theme_configs", + column: "published_by"); + + migrationBuilder.CreateIndex( + name: "ix_tenant_theme_configs_tenant_id", + table: "tenant_theme_configs", + column: "tenant_id", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_theme_templates_code", + table: "tenant_theme_templates", + column: "code", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenant_theme_templates_status_sort_order_code", + table: "tenant_theme_templates", + columns: new[] { "status", "sort_order", "code" }); + + migrationBuilder.CreateIndex( + name: "ix_tenant_usage_records_tenant_id_metric_key_period_start_peri~", + table: "tenant_usage_records", + columns: new[] { "tenant_id", "metric_key", "period_start", "period_end" }); + + migrationBuilder.CreateIndex( + name: "ix_tenants_legacy_id", + table: "tenants", + column: "legacy_id", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_tenants_owner_user_id", + table: "tenants", + column: "owner_user_id"); + + migrationBuilder.CreateIndex( + name: "ix_tenants_slug", + table: "tenants", + column: "slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_user_badges_granted_by", + table: "user_badges", + column: "granted_by"); + + migrationBuilder.CreateIndex( + name: "ix_user_badges_tenant_id_badge_id", + table: "user_badges", + columns: new[] { "tenant_id", "badge_id" }); + + migrationBuilder.CreateIndex( + name: "ix_user_badges_tenant_id_legacy_id", + table: "user_badges", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_user_badges_tenant_id_user_id_badge_id", + table: "user_badges", + columns: new[] { "tenant_id", "user_id", "badge_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_user_badges_user_id", + table: "user_badges", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_user_identities_provider_provider_subject", + table: "user_identities", + columns: new[] { "provider", "provider_subject" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_user_identities_user_id", + table: "user_identities", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_user_notifications_created_by", + table: "user_notifications", + column: "created_by"); + + migrationBuilder.CreateIndex( + name: "ix_user_notifications_tenant_id_source_type_source_id", + table: "user_notifications", + columns: new[] { "tenant_id", "source_type", "source_id" }); + + migrationBuilder.CreateIndex( + name: "ix_user_notifications_tenant_id_user_id_notification_type_dedu~", + table: "user_notifications", + columns: new[] { "tenant_id", "user_id", "notification_type", "dedupe_key" }, + unique: true, + filter: "dedupe_key is not null"); + + migrationBuilder.CreateIndex( + name: "ix_user_notifications_tenant_id_user_id_status_created_at", + table: "user_notifications", + columns: new[] { "tenant_id", "user_id", "status", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_user_notifications_user_id", + table: "user_notifications", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_user_score_events_tenant_id_idempotency_key", + table: "user_score_events", + columns: new[] { "tenant_id", "idempotency_key" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_user_score_events_tenant_id_user_id_created_at", + table: "user_score_events", + columns: new[] { "tenant_id", "user_id", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_user_score_events_user_id", + table: "user_score_events", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_user_word_favorites_tenant_id_user_id_word_id", + table: "user_word_favorites", + columns: new[] { "tenant_id", "user_id", "word_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_user_word_favorites_tenant_id_word_id", + table: "user_word_favorites", + columns: new[] { "tenant_id", "word_id" }); + + migrationBuilder.CreateIndex( + name: "ix_user_word_favorites_user_id", + table: "user_word_favorites", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_user_word_progress_tenant_id_user_id_next_review_at_status_~", + table: "user_word_progress", + columns: new[] { "tenant_id", "user_id", "next_review_at", "status", "due_level" }); + + migrationBuilder.CreateIndex( + name: "ix_user_word_progress_tenant_id_user_id_word_id", + table: "user_word_progress", + columns: new[] { "tenant_id", "user_id", "word_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_user_word_progress_tenant_id_word_id", + table: "user_word_progress", + columns: new[] { "tenant_id", "word_id" }); + + migrationBuilder.CreateIndex( + name: "ix_user_word_progress_user_id", + table: "user_word_progress", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_users_email", + table: "users", + column: "email", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_users_legacy_id", + table: "users", + column: "legacy_id", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_users_phone", + table: "users", + column: "phone", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_users_username", + table: "users", + column: "username", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_video_explanations_tenant_id_legacy_id", + table: "video_explanations", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_video_explanations_tenant_id_source_hash", + table: "video_explanations", + columns: new[] { "tenant_id", "source_hash" }, + filter: "source_hash is not null"); + + migrationBuilder.CreateIndex( + name: "ix_video_explanations_tenant_id_subject_id_is_active_sort_order", + table: "video_explanations", + columns: new[] { "tenant_id", "subject_id", "is_active", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_vocabulary_units_tenant_id_content_node_id", + table: "vocabulary_units", + columns: new[] { "tenant_id", "content_node_id" }); + + migrationBuilder.CreateIndex( + name: "ix_vocabulary_units_tenant_id_entry_id_content_node_id_region_~", + table: "vocabulary_units", + columns: new[] { "tenant_id", "entry_id", "content_node_id", "region_id", "is_active", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_vocabulary_units_tenant_id_legacy_id", + table: "vocabulary_units", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_vocabulary_units_tenant_id_region_id", + table: "vocabulary_units", + columns: new[] { "tenant_id", "region_id" }); + + migrationBuilder.CreateIndex( + name: "ix_vocabulary_words_tenant_id_content_node_id", + table: "vocabulary_words", + columns: new[] { "tenant_id", "content_node_id" }); + + migrationBuilder.CreateIndex( + name: "ix_vocabulary_words_tenant_id_entry_id_content_node_id_unit_id~", + table: "vocabulary_words", + columns: new[] { "tenant_id", "entry_id", "content_node_id", "unit_id", "is_active", "sort_order" }); + + migrationBuilder.CreateIndex( + name: "ix_vocabulary_words_tenant_id_legacy_id", + table: "vocabulary_words", + columns: new[] { "tenant_id", "legacy_id" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_vocabulary_words_tenant_id_unit_id_is_active_sort_order_cre~", + table: "vocabulary_words", + columns: new[] { "tenant_id", "unit_id", "is_active", "sort_order", "created_at" }); + + migrationBuilder.CreateIndex( + name: "ix_wrong_questions_tenant_id_question_id", + table: "wrong_questions", + columns: new[] { "tenant_id", "question_id" }); + + migrationBuilder.CreateIndex( + name: "ix_wrong_questions_user_id", + table: "wrong_questions", + column: "user_id"); + + migrationBuilder.AddForeignKey( + name: "fk_answer_records_question_versions_tenant_id_question_id_ques~", + table: "answer_records", + columns: new[] { "tenant_id", "question_id", "question_version_id" }, + principalTable: "question_versions", + principalColumns: new[] { "tenant_id", "question_id", "id" }, + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "fk_answer_records_questions_tenant_id_question_id", + table: "answer_records", + columns: new[] { "tenant_id", "question_id" }, + principalTable: "questions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "fk_favorite_questions_questions_tenant_id_question_id", + table: "favorite_questions", + columns: new[] { "tenant_id", "question_id" }, + principalTable: "questions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "fk_question_collection_items_questions_tenant_id_question_id", + table: "question_collection_items", + columns: new[] { "tenant_id", "question_id" }, + principalTable: "questions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "fk_question_versions_questions_tenant_id_question_id", + table: "question_versions", + columns: new[] { "tenant_id", "question_id" }, + principalTable: "questions", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "fk_referral_leads_referral_tracks_tenant_id_first_track_id", + table: "referral_leads", + columns: new[] { "tenant_id", "first_track_id" }, + principalTable: "referral_tracks", + principalColumns: new[] { "tenant_id", "id" }, + onDelete: ReferentialAction.SetNull); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "fk_content_entries_regions_tenant_id_region_id", + table: "content_entries"); + + migrationBuilder.DropForeignKey( + name: "fk_content_nodes_regions_tenant_id_region_id", + table: "content_nodes"); + + migrationBuilder.DropForeignKey( + name: "fk_majors_regions_tenant_id_region_id", + table: "majors"); + + migrationBuilder.DropForeignKey( + name: "fk_module_nodes_regions_tenant_id_region_id", + table: "module_nodes"); + + migrationBuilder.DropForeignKey( + name: "fk_question_banks_regions_tenant_id_region_id", + table: "question_banks"); + + migrationBuilder.DropForeignKey( + name: "fk_question_collections_regions_tenant_id_region_id", + table: "question_collections"); + + migrationBuilder.DropForeignKey( + name: "fk_region_modules_regions_tenant_id_region_id", + table: "region_modules"); + + migrationBuilder.DropForeignKey( + name: "fk_schools_regions_tenant_id_region_id", + table: "schools"); + + migrationBuilder.DropForeignKey( + name: "fk_subjects_regions_tenant_id_region_id", + table: "subjects"); + + migrationBuilder.DropForeignKey( + name: "fk_categories_tenants_tenant_id", + table: "categories"); + + migrationBuilder.DropForeignKey( + name: "fk_content_entries_tenants_tenant_id", + table: "content_entries"); + + migrationBuilder.DropForeignKey( + name: "fk_content_nodes_tenants_tenant_id", + table: "content_nodes"); + + migrationBuilder.DropForeignKey( + name: "fk_majors_tenants_tenant_id", + table: "majors"); + + migrationBuilder.DropForeignKey( + name: "fk_module_nodes_tenants_tenant_id", + table: "module_nodes"); + + migrationBuilder.DropForeignKey( + name: "fk_question_banks_tenants_tenant_id", + table: "question_banks"); + + migrationBuilder.DropForeignKey( + name: "fk_question_collections_tenants_tenant_id", + table: "question_collections"); + + migrationBuilder.DropForeignKey( + name: "fk_questions_tenants_tenant_id", + table: "questions"); + + migrationBuilder.DropForeignKey( + name: "fk_referral_leads_tenants_tenant_id", + table: "referral_leads"); + + migrationBuilder.DropForeignKey( + name: "fk_referral_tracks_tenants_tenant_id", + table: "referral_tracks"); + + migrationBuilder.DropForeignKey( + name: "fk_region_modules_tenants_tenant_id", + table: "region_modules"); + + migrationBuilder.DropForeignKey( + name: "fk_schools_tenants_tenant_id", + table: "schools"); + + migrationBuilder.DropForeignKey( + name: "fk_subjects_tenants_tenant_id", + table: "subjects"); + + migrationBuilder.DropForeignKey( + name: "fk_content_entries_users_created_by", + table: "content_entries"); + + migrationBuilder.DropForeignKey( + name: "fk_content_entries_users_updated_by", + table: "content_entries"); + + migrationBuilder.DropForeignKey( + name: "fk_content_nodes_users_created_by", + table: "content_nodes"); + + migrationBuilder.DropForeignKey( + name: "fk_content_nodes_users_updated_by", + table: "content_nodes"); + + migrationBuilder.DropForeignKey( + name: "fk_question_collections_users_created_by", + table: "question_collections"); + + migrationBuilder.DropForeignKey( + name: "fk_question_collections_users_updated_by", + table: "question_collections"); + + migrationBuilder.DropForeignKey( + name: "fk_question_versions_users_created_by", + table: "question_versions"); + + migrationBuilder.DropForeignKey( + name: "fk_referral_leads_users_assigned_by", + table: "referral_leads"); + + migrationBuilder.DropForeignKey( + name: "fk_referral_leads_users_assigned_to_user_id", + table: "referral_leads"); + + migrationBuilder.DropForeignKey( + name: "fk_referral_leads_users_referrer_user_id", + table: "referral_leads"); + + migrationBuilder.DropForeignKey( + name: "fk_referral_leads_users_student_user_id", + table: "referral_leads"); + + migrationBuilder.DropForeignKey( + name: "fk_referral_tracks_users_referrer_user_id", + table: "referral_tracks"); + + migrationBuilder.DropForeignKey( + name: "fk_referral_tracks_users_target_user_id", + table: "referral_tracks"); + + migrationBuilder.DropForeignKey( + name: "fk_questions_question_versions_tenant_id_id_current_version_id", + table: "questions"); + + migrationBuilder.DropForeignKey( + name: "fk_referral_leads_referral_tracks_tenant_id_first_track_id", + table: "referral_leads"); + + migrationBuilder.DropTable( + name: "activation_codes"); + + migrationBuilder.DropTable( + name: "ai_recommendation_reports"); + + migrationBuilder.DropTable( + name: "announcements"); + + migrationBuilder.DropTable( + name: "answer_records"); + + migrationBuilder.DropTable( + name: "app_assets"); + + migrationBuilder.DropTable( + name: "auth_login_events"); + + migrationBuilder.DropTable( + name: "auth_sessions"); + + migrationBuilder.DropTable( + name: "banners"); + + migrationBuilder.DropTable( + name: "commerce_reconciliation_issue_events"); + + migrationBuilder.DropTable( + name: "commerce_refund_events"); + + migrationBuilder.DropTable( + name: "commission_settlement_items"); + + migrationBuilder.DropTable( + name: "content_asset_access_events"); + + migrationBuilder.DropTable( + name: "content_asset_security_scan_events"); + + migrationBuilder.DropTable( + name: "content_import_issues"); + + migrationBuilder.DropTable( + name: "crm_config"); + + migrationBuilder.DropTable( + name: "crm_webhook_log"); + + migrationBuilder.DropTable( + name: "crm_webhook_queue"); + + migrationBuilder.DropTable( + name: "dashboard_daily_stats"); + + migrationBuilder.DropTable( + name: "entitlements"); + + migrationBuilder.DropTable( + name: "exam_dates"); + + migrationBuilder.DropTable( + name: "faqs"); + + migrationBuilder.DropTable( + name: "favorite_questions"); + + migrationBuilder.DropTable( + name: "handbook_entries"); + + migrationBuilder.DropTable( + name: "images"); + + migrationBuilder.DropTable( + name: "order_items"); + + migrationBuilder.DropTable( + name: "payment_events"); + + migrationBuilder.DropTable( + name: "pb_import_issues"); + + migrationBuilder.DropTable( + name: "pb_raw_records"); + + migrationBuilder.DropTable( + name: "platform_audit_alerts"); + + migrationBuilder.DropTable( + name: "platform_dunning_notification_events"); + + migrationBuilder.DropTable( + name: "platform_saas_plans"); + + migrationBuilder.DropTable( + name: "practice_access_events"); + + migrationBuilder.DropTable( + name: "practice_daily_usage"); + + migrationBuilder.DropTable( + name: "practice_session_report_sections"); + + migrationBuilder.DropTable( + name: "products"); + + migrationBuilder.DropTable( + name: "question_collection_items"); + + migrationBuilder.DropTable( + name: "question_type_groups"); + + migrationBuilder.DropTable( + name: "question_videos"); + + migrationBuilder.DropTable( + name: "recent_practices"); + + migrationBuilder.DropTable( + name: "referral_codes"); + + migrationBuilder.DropTable( + name: "referral_qrcodes"); + + migrationBuilder.DropTable( + name: "referral_team_edges"); + + migrationBuilder.DropTable( + name: "report_status_events"); + + migrationBuilder.DropTable( + name: "revenue_daily_stats"); + + migrationBuilder.DropTable( + name: "sms_send_rate_limits"); + + migrationBuilder.DropTable( + name: "sms_verification_codes"); + + migrationBuilder.DropTable( + name: "student_profiles"); + + migrationBuilder.DropTable( + name: "subject_shares"); + + migrationBuilder.DropTable( + name: "tenant_auth_providers"); + + migrationBuilder.DropTable( + name: "tenant_billing_profiles"); + + migrationBuilder.DropTable( + name: "tenant_branding"); + + migrationBuilder.DropTable( + name: "tenant_class_members"); + + migrationBuilder.DropTable( + name: "tenant_commission_settings"); + + migrationBuilder.DropTable( + name: "tenant_content_notifications"); + + migrationBuilder.DropTable( + name: "tenant_domains"); + + migrationBuilder.DropTable( + name: "tenant_invoice_items"); + + migrationBuilder.DropTable( + name: "tenant_invoice_payments"); + + migrationBuilder.DropTable( + name: "tenant_memberships"); + + migrationBuilder.DropTable( + name: "tenant_payment_accounts"); + + migrationBuilder.DropTable( + name: "tenant_question_bank_adoptions"); + + migrationBuilder.DropTable( + name: "tenant_settings"); + + migrationBuilder.DropTable( + name: "tenant_student_followups"); + + migrationBuilder.DropTable( + name: "tenant_student_notes"); + + migrationBuilder.DropTable( + name: "tenant_subscriptions"); + + migrationBuilder.DropTable( + name: "tenant_theme_configs"); + + migrationBuilder.DropTable( + name: "tenant_usage_records"); + + migrationBuilder.DropTable( + name: "user_badges"); + + migrationBuilder.DropTable( + name: "user_identities"); + + migrationBuilder.DropTable( + name: "user_notifications"); + + migrationBuilder.DropTable( + name: "user_score_events"); + + migrationBuilder.DropTable( + name: "user_word_favorites"); + + migrationBuilder.DropTable( + name: "user_word_progress"); + + migrationBuilder.DropTable( + name: "wrong_questions"); + + migrationBuilder.DropTable( + name: "code_batches"); + + migrationBuilder.DropTable( + name: "coupon_redemptions"); + + migrationBuilder.DropTable( + name: "commerce_reconciliation_issues"); + + migrationBuilder.DropTable( + name: "commission_settlements"); + + migrationBuilder.DropTable( + name: "content_assets"); + + migrationBuilder.DropTable( + name: "content_import_items"); + + migrationBuilder.DropTable( + name: "handbook_chapters"); + + migrationBuilder.DropTable( + name: "pb_import_runs"); + + migrationBuilder.DropTable( + name: "audit_logs"); + + migrationBuilder.DropTable( + name: "platform_audit_alert_rules"); + + migrationBuilder.DropTable( + name: "platform_dunning_notification_channels"); + + migrationBuilder.DropTable( + name: "tenant_invoice_reminders"); + + migrationBuilder.DropTable( + name: "practice_session_reports"); + + migrationBuilder.DropTable( + name: "video_explanations"); + + migrationBuilder.DropTable( + name: "reports"); + + migrationBuilder.DropTable( + name: "tenant_role_templates"); + + migrationBuilder.DropTable( + name: "question_bank_grants"); + + migrationBuilder.DropTable( + name: "tenant_classes"); + + migrationBuilder.DropTable( + name: "tenant_theme_templates"); + + migrationBuilder.DropTable( + name: "badges"); + + migrationBuilder.DropTable( + name: "vocabulary_words"); + + migrationBuilder.DropTable( + name: "coupons"); + + migrationBuilder.DropTable( + name: "commerce_reconciliation_items"); + + migrationBuilder.DropTable( + name: "content_import_jobs"); + + migrationBuilder.DropTable( + name: "handbook_subjects"); + + migrationBuilder.DropTable( + name: "tenant_invoices"); + + migrationBuilder.DropTable( + name: "practice_sessions"); + + migrationBuilder.DropTable( + name: "vocabulary_units"); + + migrationBuilder.DropTable( + name: "commerce_reconciliation_batches"); + + migrationBuilder.DropTable( + name: "commerce_refund_requests"); + + migrationBuilder.DropTable( + name: "practice_blueprints"); + + migrationBuilder.DropTable( + name: "payments"); + + migrationBuilder.DropTable( + name: "orders"); + + migrationBuilder.DropTable( + name: "svip_plans"); + + migrationBuilder.DropTable( + name: "regions"); + + migrationBuilder.DropTable( + name: "tenants"); + + migrationBuilder.DropTable( + name: "users"); + + migrationBuilder.DropTable( + name: "question_versions"); + + migrationBuilder.DropTable( + name: "questions"); + + migrationBuilder.DropTable( + name: "question_collections"); + + migrationBuilder.DropTable( + name: "categories"); + + migrationBuilder.DropTable( + name: "content_nodes"); + + migrationBuilder.DropTable( + name: "question_banks"); + + migrationBuilder.DropTable( + name: "subjects"); + + migrationBuilder.DropTable( + name: "content_entries"); + + migrationBuilder.DropTable( + name: "majors"); + + migrationBuilder.DropTable( + name: "module_nodes"); + + migrationBuilder.DropTable( + name: "schools"); + + migrationBuilder.DropTable( + name: "region_modules"); + + migrationBuilder.DropTable( + name: "referral_tracks"); + + migrationBuilder.DropTable( + name: "referral_leads"); + } + } +}