//
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