using System; using System.Text.Json; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; #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: "data_protection_keys", columns: table => new { id = table.Column(type: "integer", nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), friendly_name = table.Column(type: "text", nullable: true), xml = table.Column(type: "text", nullable: true) }, constraints: table => { table.PrimaryKey("pk_data_protection_keys", x => x.id); }); migrationBuilder.CreateTable( name: "inbox_state", columns: table => new { id = table.Column(type: "bigint", nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), message_id = table.Column(type: "uuid", nullable: false), consumer_id = table.Column(type: "uuid", nullable: false), lock_id = table.Column(type: "uuid", nullable: false), row_version = table.Column(type: "bytea", rowVersion: true, nullable: true), received = table.Column(type: "timestamp with time zone", nullable: false), receive_count = table.Column(type: "integer", nullable: false), expiration_time = table.Column(type: "timestamp with time zone", nullable: true), consumed = table.Column(type: "timestamp with time zone", nullable: true), delivered = table.Column(type: "timestamp with time zone", nullable: true), last_sequence_number = table.Column(type: "bigint", nullable: true) }, constraints: table => { table.PrimaryKey("pk_inbox_state", x => x.id); table.UniqueConstraint("ak_inbox_state_message_id_consumer_id", x => new { x.message_id, x.consumer_id }); }); migrationBuilder.CreateTable( name: "outbox_state", columns: table => new { outbox_id = table.Column(type: "uuid", nullable: false), lock_id = table.Column(type: "uuid", nullable: false), row_version = table.Column(type: "bytea", rowVersion: true, nullable: true), created = table.Column(type: "timestamp with time zone", nullable: false), delivered = table.Column(type: "timestamp with time zone", nullable: true), last_sequence_number = table.Column(type: "bigint", nullable: true) }, constraints: table => { table.PrimaryKey("pk_outbox_state", x => x.outbox_id); }); migrationBuilder.CreateTable( name: "platform_backend_roles", 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), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), is_system = table.Column(type: "boolean", nullable: false), description = table.Column(type: "character varying(1000)", maxLength: 1000, 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_backend_roles", x => x.id); }); migrationBuilder.CreateTable( name: "platform_billing_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_billing_dunning_notification_channels", x => x.id); table.CheckConstraint("ck_platform_billing_dunning_channels_level", "min_reminder_level between 1 and 20"); table.CheckConstraint("ck_platform_billing_dunning_channels_timeout", "timeout_seconds between 1 and 60"); }); migrationBuilder.CreateTable( name: "saas_features", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), code = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), category = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), reference_price_cents = table.Column(type: "integer", nullable: false), currency = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), is_core = table.Column(type: "boolean", 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_saas_features", x => x.id); table.UniqueConstraint("ak_saas_features_code", x => x.code); table.CheckConstraint("ck_saas_features_reference_price", "reference_price_cents >= 0"); }); migrationBuilder.CreateTable( name: "saas_offerings", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), code = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), 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_saas_offerings", x => x.id); }); 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), 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), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), force_password_change = 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()"), user_name = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), normalized_user_name = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), email = table.Column(type: "citext", maxLength: 320, nullable: true), normalized_email = table.Column(type: "character varying(320)", maxLength: 320, nullable: true), email_confirmed = table.Column(type: "boolean", nullable: false), password_hash = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: true), security_stamp = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), concurrency_stamp = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), phone_number = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), phone_number_confirmed = table.Column(type: "boolean", nullable: false), two_factor_enabled = table.Column(type: "boolean", nullable: false), lockout_end = table.Column(type: "timestamp with time zone", nullable: true), lockout_enabled = table.Column(type: "boolean", nullable: false), access_failed_count = table.Column(type: "integer", nullable: false) }, constraints: table => { table.PrimaryKey("pk_users", x => x.id); }); migrationBuilder.CreateTable( name: "outbox_message", columns: table => new { sequence_number = table.Column(type: "bigint", nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), enqueue_time = table.Column(type: "timestamp with time zone", nullable: true), sent_time = table.Column(type: "timestamp with time zone", nullable: false), headers = table.Column(type: "text", nullable: true), properties = table.Column(type: "text", nullable: true), inbox_message_id = table.Column(type: "uuid", nullable: true), inbox_consumer_id = table.Column(type: "uuid", nullable: true), outbox_id = table.Column(type: "uuid", nullable: true), message_id = table.Column(type: "uuid", nullable: false), content_type = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), message_type = table.Column(type: "text", nullable: false), body = table.Column(type: "text", nullable: false), conversation_id = table.Column(type: "uuid", nullable: true), correlation_id = table.Column(type: "uuid", nullable: true), initiator_id = table.Column(type: "uuid", nullable: true), request_id = table.Column(type: "uuid", nullable: true), source_address = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), destination_address = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), response_address = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), fault_address = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), expiration_time = table.Column(type: "timestamp with time zone", nullable: true) }, constraints: table => { table.PrimaryKey("pk_outbox_message", x => x.sequence_number); table.ForeignKey( name: "fk_outbox_message_inbox_state_inbox_message_id_inbox_consumer_~", columns: x => new { x.inbox_message_id, x.inbox_consumer_id }, principalTable: "inbox_state", principalColumns: new[] { "message_id", "consumer_id" }); table.ForeignKey( name: "fk_outbox_message_outbox_state_outbox_id", column: x => x.outbox_id, principalTable: "outbox_state", principalColumn: "outbox_id"); }); migrationBuilder.CreateTable( name: "permission_modules", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), code = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), area = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), required_feature_code = table.Column(type: "character varying(120)", maxLength: 120, nullable: true), description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), 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_permission_modules", x => x.id); table.UniqueConstraint("ak_permission_modules_code", x => x.code); table.ForeignKey( name: "fk_permission_modules_saas_features_required_feature_code", column: x => x.required_feature_code, principalTable: "saas_features", principalColumn: "code", onDelete: ReferentialAction.Restrict); }); migrationBuilder.CreateTable( name: "saas_feature_limit_definitions", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), metric_code = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), feature_code = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), unit = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), kind = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), warning_percent = table.Column(type: "integer", nullable: false), is_hard_limit = table.Column(type: "boolean", 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_saas_feature_limit_definitions", x => x.id); table.UniqueConstraint("ak_saas_feature_limit_definitions_metric_code", x => x.metric_code); table.CheckConstraint("ck_saas_feature_limit_warning", "warning_percent between 1 and 100"); table.ForeignKey( name: "fk_saas_feature_limit_definitions_saas_features_feature_code", column: x => x.feature_code, principalTable: "saas_features", principalColumn: "code", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "saas_offering_versions", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), offering_id = table.Column(type: "uuid", nullable: false), version = table.Column(type: "integer", nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), billing_cycle = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), original_amount_cents = table.Column(type: "integer", nullable: false), amount_cents = table.Column(type: "integer", nullable: false), currency = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), effective_at = table.Column(type: "timestamp with time zone", nullable: true), published_at = table.Column(type: "timestamp with time zone", nullable: true), retired_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_saas_offering_versions", x => x.id); table.CheckConstraint("ck_saas_offering_versions_amount", "original_amount_cents >= 0 and amount_cents >= 0 and amount_cents <= original_amount_cents"); table.CheckConstraint("ck_saas_offering_versions_version", "version > 0"); table.ForeignKey( name: "fk_saas_offering_versions_saas_offerings_offering_id", column: x => x.offering_id, principalTable: "saas_offerings", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "platform_backend_user_roles", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), user_id = table.Column(type: "uuid", nullable: false), role_id = table.Column(type: "uuid", nullable: false), created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") }, constraints: table => { table.PrimaryKey("pk_platform_backend_user_roles", x => x.id); table.ForeignKey( name: "fk_platform_backend_user_roles_platform_backend_roles_role_id", column: x => x.role_id, principalTable: "platform_backend_roles", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_platform_backend_user_roles_users_user_id", column: x => x.user_id, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "tenants", columns: table => new { 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_claims", columns: table => new { id = table.Column(type: "integer", nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), user_id = table.Column(type: "uuid", nullable: false), claim_type = table.Column(type: "text", nullable: true), claim_value = table.Column(type: "text", nullable: true) }, constraints: table => { table.PrimaryKey("pk_user_claims", x => x.id); table.ForeignKey( name: "fk_user_claims_users_user_id", column: x => x.user_id, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); 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), 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: "user_logins", columns: table => new { login_provider = table.Column(type: "text", nullable: false), provider_key = table.Column(type: "text", nullable: false), provider_display_name = table.Column(type: "text", nullable: true), user_id = table.Column(type: "uuid", nullable: false) }, constraints: table => { table.PrimaryKey("pk_user_logins", x => new { x.login_provider, x.provider_key }); table.ForeignKey( name: "fk_user_logins_users_user_id", column: x => x.user_id, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "user_tokens", columns: table => new { user_id = table.Column(type: "uuid", nullable: false), login_provider = table.Column(type: "text", nullable: false), name = table.Column(type: "text", nullable: false), value = table.Column(type: "text", nullable: true) }, constraints: table => { table.PrimaryKey("pk_user_tokens", x => new { x.user_id, x.login_provider, x.name }); table.ForeignKey( name: "fk_user_tokens_users_user_id", column: x => x.user_id, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "backend_permissions", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), code = table.Column(type: "character varying(160)", maxLength: 160, nullable: false), name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), area = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), permission_module_code = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), is_system = table.Column(type: "boolean", 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_backend_permissions", x => x.id); table.UniqueConstraint("ak_backend_permissions_code", x => x.code); table.ForeignKey( name: "fk_backend_permissions_permission_modules_permission_module_co~", column: x => x.permission_module_code, principalTable: "permission_modules", principalColumn: "code", onDelete: ReferentialAction.Restrict); }); migrationBuilder.CreateTable( name: "saas_offering_version_features", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), offering_version_id = table.Column(type: "uuid", nullable: false), feature_code = table.Column(type: "character varying(120)", maxLength: 120, nullable: false) }, constraints: table => { table.PrimaryKey("pk_saas_offering_version_features", x => x.id); table.ForeignKey( name: "fk_saas_offering_version_features_saas_features_feature_code", column: x => x.feature_code, principalTable: "saas_features", principalColumn: "code", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_saas_offering_version_features_saas_offering_versions_offer~", column: x => x.offering_version_id, principalTable: "saas_offering_versions", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "saas_offering_version_limits", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), offering_version_id = table.Column(type: "uuid", nullable: false), metric_code = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), limit_value = table.Column(type: "bigint", nullable: false) }, constraints: table => { table.PrimaryKey("pk_saas_offering_version_limits", x => x.id); table.CheckConstraint("ck_saas_offering_version_limits_value", "limit_value >= 0"); table.ForeignKey( name: "fk_saas_offering_version_limits_saas_feature_limit_definitions~", column: x => x.metric_code, principalTable: "saas_feature_limit_definitions", principalColumn: "metric_code", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_saas_offering_version_limits_saas_offering_versions_offerin~", column: x => x.offering_version_id, principalTable: "saas_offering_versions", 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_challenges", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), user_id = table.Column(type: "uuid", nullable: false), realm = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), tenant_id = table.Column(type: "uuid", nullable: true), purpose = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), token_hash = table.Column(type: "character varying(64)", maxLength: 64, nullable: false), security_stamp = table.Column(type: "character varying(128)", maxLength: 128, nullable: false), provider = table.Column(type: "character varying(50)", maxLength: 50, 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(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_auth_challenges", x => x.id); table.CheckConstraint("ck_auth_challenges_realm_tenant", "(realm = 'tenant' and tenant_id is not null) or (realm = 'platform' and tenant_id is null)"); table.ForeignKey( name: "fk_auth_challenges_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_auth_challenges_users_user_id", column: x => x.user_id, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); 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: true), 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.ForeignKey( name: "fk_auth_login_events_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.SetNull); 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()"), realm = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), tenant_id = table.Column(type: "uuid", nullable: true), user_id = table.Column(type: "uuid", nullable: false), token_family_id = table.Column(type: "uuid", nullable: false), parent_session_id = table.Column(type: "uuid", nullable: true), replaced_by_session_id = table.Column(type: "uuid", nullable: true), token_hash = table.Column(type: "character varying(256)", maxLength: 256, nullable: false), security_stamp = table.Column(type: "character varying(128)", maxLength: 128, 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), revoked_reason = 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()"), updated_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") }, constraints: table => { table.PrimaryKey("pk_auth_sessions", x => x.id); table.CheckConstraint("ck_auth_sessions_realm_tenant", "(realm = 'tenant' and tenant_id is not null) or (realm = 'platform' and tenant_id is null)"); 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: "platform_billing_quotes", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), quote_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), idempotency_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), purpose = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), original_amount_cents = table.Column(type: "integer", nullable: false), discount_amount_cents = table.Column(type: "integer", nullable: false), total_amount_cents = table.Column(type: "integer", nullable: false), currency = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), expires_at = table.Column(type: "timestamp with time zone", nullable: false), feature_snapshot = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), limit_snapshot = 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_billing_quotes", x => x.id); table.UniqueConstraint("ak_platform_billing_quotes_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_platform_billing_quotes_amounts", "original_amount_cents >= 0 and discount_amount_cents >= 0 and total_amount_cents >= 0 and total_amount_cents = original_amount_cents - discount_amount_cents"); table.ForeignKey( name: "fk_platform_billing_quotes_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "point_activity_tasks", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), task_key = table.Column(type: "citext", maxLength: 100, nullable: false), title = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), task_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), points = table.Column(type: "integer", nullable: false), max_claims_per_user = table.Column(type: "integer", nullable: false), starts_at = table.Column(type: "timestamp with time zone", nullable: true), ends_at = table.Column(type: "timestamp with time zone", nullable: true), sort_order = table.Column(type: "integer", nullable: false), rules = 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_point_activity_tasks", x => x.id); table.UniqueConstraint("ak_point_activity_tasks_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_point_activity_tasks_max_claims", "max_claims_per_user > 0"); table.CheckConstraint("ck_point_activity_tasks_points", "points > 0"); table.ForeignKey( name: "fk_point_activity_tasks_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.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: "taxonomy_nodes", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), parent_owner_tenant_id = table.Column(type: "uuid", nullable: true), parent_id = table.Column(type: "uuid", nullable: true), node_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), code = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), name = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), 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), 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_taxonomy_nodes", x => x.id); table.UniqueConstraint("ak_taxonomy_nodes_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_taxonomy_nodes_parent_pair", "(parent_owner_tenant_id is null) = (parent_id is null)"); table.ForeignKey( name: "fk_taxonomy_nodes_taxonomy_nodes_parent_owner_tenant_id_parent~", columns: x => new { x.parent_owner_tenant_id, x.parent_id }, principalTable: "taxonomy_nodes", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_taxonomy_nodes_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "tenant_auth_policies", columns: table => new { tenant_id = table.Column(type: "uuid", nullable: false), allow_external_student_self_registration = table.Column(type: "boolean", nullable: false, defaultValue: false), allowed_student_login_methods = table.Column(type: "text[]", nullable: false, defaultValueSql: "ARRAY['password']::text[]"), 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_policies", x => x.tenant_id); table.ForeignKey( name: "fk_tenant_auth_policies_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "tenant_backend_roles", 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), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), is_system = table.Column(type: "boolean", nullable: false), description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), data_scope = 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_backend_roles", x => x.id); table.UniqueConstraint("ak_tenant_backend_roles_tenant_id_id", x => new { x.tenant_id, x.id }); table.ForeignKey( name: "fk_tenant_backend_roles_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "tenant_billing_profiles", columns: table => new { 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), last_checked_at = table.Column(type: "timestamp with time zone", nullable: true), dns_verified_at = table.Column(type: "timestamp with time zone", nullable: true), tls_ready_at = table.Column(type: "timestamp with time zone", nullable: true), last_failure_reason = table.Column(type: "character varying(2000)", maxLength: 2000, 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_external_providers", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), capability = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), 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), secret_ref = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), priority = table.Column(type: "integer", nullable: false), config_public = 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_tenant_external_providers", x => x.id); table.UniqueConstraint("ak_tenant_external_providers_tenant_id_id", x => new { x.tenant_id, x.id }); table.ForeignKey( name: "fk_tenant_external_providers_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "tenant_feature_overrides", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), feature_code = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), mode = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), expires_at = table.Column(type: "timestamp with time zone", nullable: true), reason = table.Column(type: "character varying(1000)", maxLength: 1000, 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_tenant_feature_overrides", x => x.id); table.UniqueConstraint("ak_tenant_feature_overrides_tenant_id_id", x => new { x.tenant_id, x.id }); table.ForeignKey( name: "fk_tenant_feature_overrides_saas_features_feature_code", column: x => x.feature_code, principalTable: "saas_features", principalColumn: "code", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_tenant_feature_overrides_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "tenant_feature_usage", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), metric_code = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), period_start = table.Column(type: "timestamp with time zone", nullable: false), period_end = table.Column(type: "timestamp with time zone", nullable: false), used_value = table.Column(type: "bigint", nullable: false), limit_value_snapshot = table.Column(type: "bigint", nullable: false), warning_issued = table.Column(type: "boolean", nullable: false), version = table.Column(type: "bigint", 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_tenant_feature_usage", x => x.id); table.UniqueConstraint("ak_tenant_feature_usage_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_tenant_feature_usage_period", "period_end > period_start"); table.CheckConstraint("ck_tenant_feature_usage_values", "used_value >= 0 and limit_value_snapshot >= 0"); table.ForeignKey( name: "fk_tenant_feature_usage_saas_feature_limit_definitions_metric_~", column: x => x.metric_code, principalTable: "saas_feature_limit_definitions", principalColumn: "metric_code", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_tenant_feature_usage_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "tenant_frontend_configs", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), schema_version = table.Column(type: "integer", nullable: false), config_version = table.Column(type: "integer", nullable: false), published_branding = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), published_theme = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), published_features = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), published_navigation = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), published_home_modules = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), draft_branding = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), draft_theme = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), draft_features = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), draft_navigation = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), draft_home_modules = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), published_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_frontend_configs", x => x.id); table.UniqueConstraint("ak_tenant_frontend_configs_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_tenant_frontend_configs_config_version", "config_version > 0"); table.CheckConstraint("ck_tenant_frontend_configs_schema_version", "schema_version > 0"); table.ForeignKey( name: "fk_tenant_frontend_configs_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), 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: "tenant_saas_subscriptions", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), base_offering_version_id = table.Column(type: "uuid", nullable: false), scheduled_base_offering_version_id = table.Column(type: "uuid", nullable: true), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), starts_at = table.Column(type: "timestamp with time zone", nullable: false), current_period_start = table.Column(type: "timestamp with time zone", nullable: false), current_period_end = table.Column(type: "timestamp with time zone", nullable: false), cancel_at_period_end = table.Column(type: "boolean", nullable: false), cancelled_at = table.Column(type: "timestamp with time zone", nullable: true), lifecycle_version = table.Column(type: "bigint", 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_saas_subscriptions", x => x.id); table.UniqueConstraint("ak_tenant_saas_subscriptions_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_tenant_saas_subscriptions_period", "current_period_end > current_period_start and current_period_start >= starts_at"); table.ForeignKey( name: "fk_tenant_saas_subscriptions_saas_offering_versions_base_offer~", column: x => x.base_offering_version_id, principalTable: "saas_offering_versions", principalColumn: "id", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_tenant_saas_subscriptions_saas_offering_versions_scheduled_~", column: x => x.scheduled_base_offering_version_id, principalTable: "saas_offering_versions", principalColumn: "id", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_tenant_saas_subscriptions_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "tenant_secrets", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), purpose = table.Column(type: "character varying(80)", maxLength: 80, nullable: false), provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), secret_key = table.Column(type: "character varying(120)", maxLength: 120, nullable: false), secret_ref = table.Column(type: "character varying(300)", maxLength: 300, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), encryption_key_id = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), encrypted_payload = table.Column(type: "bytea", nullable: false), encryption_nonce = table.Column(type: "bytea", nullable: false), encryption_tag = table.Column(type: "bytea", nullable: false), rotated_at = table.Column(type: "timestamp with time zone", nullable: true), expires_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_secrets", x => x.id); table.UniqueConstraint("ak_tenant_secrets_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_tenant_secrets_encryption_envelope", "octet_length(encrypted_payload) > 0 and octet_length(encryption_nonce) = 12 and octet_length(encryption_tag) = 16 and encryption_key_id <> ''"); table.ForeignKey( name: "fk_tenant_secrets_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: "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_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: "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: "backend_menus", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), code = table.Column(type: "character varying(160)", maxLength: 160, nullable: false), parent_code = table.Column(type: "character varying(160)", maxLength: 160, nullable: true), title = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), area = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), path = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: true), icon = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), permission_code = table.Column(type: "character varying(160)", maxLength: 160, nullable: true), sort_order = table.Column(type: "integer", nullable: false), is_active = table.Column(type: "boolean", 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_backend_menus", x => x.id); table.UniqueConstraint("ak_backend_menus_code", x => x.code); table.ForeignKey( name: "fk_backend_menus_backend_permissions_permission_code", column: x => x.permission_code, principalTable: "backend_permissions", principalColumn: "code", onDelete: ReferentialAction.SetNull); }); migrationBuilder.CreateTable( name: "platform_backend_role_permissions", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), role_id = table.Column(type: "uuid", nullable: false), permission_code = table.Column(type: "character varying(160)", maxLength: 160, nullable: false), created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") }, constraints: table => { table.PrimaryKey("pk_platform_backend_role_permissions", x => x.id); table.ForeignKey( name: "fk_platform_backend_role_permissions_backend_permissions_permi~", column: x => x.permission_code, principalTable: "backend_permissions", principalColumn: "code", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_platform_backend_role_permissions_platform_backend_roles_ro~", column: x => x.role_id, principalTable: "platform_backend_roles", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "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_export_events", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), tenant_id = table.Column(type: "uuid", nullable: false), settlement_id = table.Column(type: "uuid", nullable: false), exported_by = table.Column(type: "uuid", nullable: true), export_format = table.Column(type: "character varying(20)", maxLength: 20, nullable: false), filename = table.Column(type: "character varying(500)", maxLength: 500, nullable: false), row_count = table.Column(type: "integer", nullable: false), content_sha256 = table.Column(type: "character varying(128)", maxLength: 128, 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_commission_settlement_export_events", x => x.id); table.CheckConstraint("ck_commission_export_events_rows", "row_count >= 0"); table.ForeignKey( name: "fk_commission_settlement_export_events_commission_settlements_~", columns: x => new { x.tenant_id, x.settlement_id }, principalTable: "commission_settlements", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_commission_settlement_export_events_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_commission_settlement_export_events_users_exported_by", column: x => x.exported_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: "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: "platform_billing_orders", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), quote_id = table.Column(type: "uuid", nullable: false), order_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), idempotency_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), purpose = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), original_amount_cents = table.Column(type: "integer", nullable: false), discount_amount_cents = table.Column(type: "integer", nullable: false), total_amount_cents = table.Column(type: "integer", nullable: false), currency = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), expires_at = table.Column(type: "timestamp with time zone", nullable: false), paid_at = table.Column(type: "timestamp with time zone", nullable: true), cancelled_at = table.Column(type: "timestamp with time zone", nullable: true), snapshot = 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_billing_orders", x => x.id); table.UniqueConstraint("ak_platform_billing_orders_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_platform_billing_orders_amounts", "original_amount_cents >= 0 and discount_amount_cents >= 0 and total_amount_cents >= 0 and total_amount_cents = original_amount_cents - discount_amount_cents"); table.ForeignKey( name: "fk_platform_billing_orders_platform_billing_quotes_tenant_id_q~", columns: x => new { x.tenant_id, x.quote_id }, principalTable: "platform_billing_quotes", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_platform_billing_orders_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "platform_billing_quote_items", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), tenant_id = table.Column(type: "uuid", nullable: false), quote_id = table.Column(type: "uuid", nullable: false), offering_version_id = table.Column(type: "uuid", nullable: false), item_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), quantity = table.Column(type: "integer", nullable: false), unit_amount_cents = table.Column(type: "integer", nullable: false), amount_cents = table.Column(type: "integer", nullable: false), snapshot = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb") }, constraints: table => { table.PrimaryKey("pk_platform_billing_quote_items", x => x.id); table.UniqueConstraint("ak_platform_billing_quote_items_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_platform_billing_quote_items_amounts", "quantity > 0 and unit_amount_cents >= 0 and amount_cents >= 0"); table.ForeignKey( name: "fk_platform_billing_quote_items_platform_billing_quotes_tenant~", columns: x => new { x.tenant_id, x.quote_id }, principalTable: "platform_billing_quotes", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_platform_billing_quote_items_saas_offering_versions_offerin~", column: x => x.offering_version_id, principalTable: "saas_offering_versions", principalColumn: "id", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_platform_billing_quote_items_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "point_activity_claims", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), task_id = table.Column(type: "uuid", nullable: false), user_id = table.Column(type: "uuid", nullable: false), task_key = table.Column(type: "citext", maxLength: 100, nullable: false), points = table.Column(type: "integer", nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), source_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), source_id = table.Column(type: "uuid", nullable: true), claimed_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), 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_point_activity_claims", x => x.id); table.UniqueConstraint("ak_point_activity_claims_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_point_activity_claims_points", "points > 0"); table.ForeignKey( name: "fk_point_activity_claims_point_activity_tasks_tenant_id_task_id", columns: x => new { x.tenant_id, x.task_id }, principalTable: "point_activity_tasks", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_point_activity_claims_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_point_activity_claims_users_user_id", column: x => x.user_id, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); 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: "point_exchange_items", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), region_id = table.Column(type: "uuid", nullable: true), item_key = table.Column(type: "citext", maxLength: 100, nullable: false), name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), item_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), points_cost = table.Column(type: "integer", nullable: false), stock = table.Column(type: "integer", nullable: true), days = table.Column(type: "integer", nullable: true), sort_order = table.Column(type: "integer", nullable: false), starts_at = table.Column(type: "timestamp with time zone", nullable: true), ends_at = table.Column(type: "timestamp with time zone", nullable: true), fulfillment_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_point_exchange_items", x => x.id); table.UniqueConstraint("ak_point_exchange_items_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_point_exchange_items_days", "days is null or days >= 0"); table.CheckConstraint("ck_point_exchange_items_points_cost", "points_cost > 0"); table.CheckConstraint("ck_point_exchange_items_stock", "stock is null or stock >= 0"); table.ForeignKey( name: "fk_point_exchange_items_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_point_exchange_items_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"), is_active = table.Column(type: "boolean", nullable: false, defaultValue: 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_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), 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: "scoreline_fields", 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), field_key = table.Column(type: "character varying(64)", maxLength: 64, nullable: false), field_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), field_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), unit = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), is_filter = table.Column(type: "boolean", nullable: false), is_required = table.Column(type: "boolean", nullable: false), is_visible = table.Column(type: "boolean", nullable: false), is_trend = table.Column(type: "boolean", nullable: false), options = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"), placeholder = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: true), sort_order = 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_scoreline_fields", x => x.id); table.UniqueConstraint("ak_scoreline_fields_tenant_id_id", x => new { x.tenant_id, x.id }); table.ForeignKey( name: "fk_scoreline_fields_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_scoreline_fields_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_backend_role_permissions", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), tenant_id = table.Column(type: "uuid", nullable: false), role_id = table.Column(type: "uuid", nullable: false), permission_code = table.Column(type: "character varying(160)", maxLength: 160, nullable: false), created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") }, constraints: table => { table.PrimaryKey("pk_tenant_backend_role_permissions", x => x.id); table.UniqueConstraint("ak_tenant_backend_role_permissions_tenant_id_id", x => new { x.tenant_id, x.id }); table.ForeignKey( name: "fk_tenant_backend_role_permissions_backend_permissions_permiss~", column: x => x.permission_code, principalTable: "backend_permissions", principalColumn: "code", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_tenant_backend_role_permissions_tenant_backend_roles_tenant~", columns: x => new { x.tenant_id, x.role_id }, principalTable: "tenant_backend_roles", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "tenant_backend_user_roles", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), tenant_id = table.Column(type: "uuid", nullable: false), user_id = table.Column(type: "uuid", nullable: false), role_id = table.Column(type: "uuid", nullable: false), created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") }, constraints: table => { table.PrimaryKey("pk_tenant_backend_user_roles", x => x.id); table.UniqueConstraint("ak_tenant_backend_user_roles_tenant_id_id", x => new { x.tenant_id, x.id }); table.ForeignKey( name: "fk_tenant_backend_user_roles_tenant_backend_roles_tenant_id_ro~", columns: x => new { x.tenant_id, x.role_id }, principalTable: "tenant_backend_roles", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_tenant_backend_user_roles_users_user_id", column: x => x.user_id, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "platform_backend_role_menus", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), role_id = table.Column(type: "uuid", nullable: false), menu_code = table.Column(type: "character varying(160)", maxLength: 160, nullable: false), created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") }, constraints: table => { table.PrimaryKey("pk_platform_backend_role_menus", x => x.id); table.ForeignKey( name: "fk_platform_backend_role_menus_backend_menus_menu_code", column: x => x.menu_code, principalTable: "backend_menus", principalColumn: "code", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_platform_backend_role_menus_platform_backend_roles_role_id", column: x => x.role_id, principalTable: "platform_backend_roles", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "tenant_backend_role_menus", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), tenant_id = table.Column(type: "uuid", nullable: false), role_id = table.Column(type: "uuid", nullable: false), menu_code = table.Column(type: "character varying(160)", maxLength: 160, nullable: false), created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") }, constraints: table => { table.PrimaryKey("pk_tenant_backend_role_menus", x => x.id); table.UniqueConstraint("ak_tenant_backend_role_menus_tenant_id_id", x => new { x.tenant_id, x.id }); table.ForeignKey( name: "fk_tenant_backend_role_menus_backend_menus_menu_code", column: x => x.menu_code, principalTable: "backend_menus", principalColumn: "code", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_tenant_backend_role_menus_tenant_backend_roles_tenant_id_ro~", columns: x => new { x.tenant_id, x.role_id }, principalTable: "tenant_backend_roles", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "platform_billing_invoices", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), order_id = table.Column(type: "uuid", nullable: true), invoice_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), total_amount_cents = table.Column(type: "integer", nullable: false), currency = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), 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), billing_profile_snapshot = 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_billing_invoices", x => x.id); table.UniqueConstraint("ak_platform_billing_invoices_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_platform_billing_invoices_amount", "total_amount_cents >= 0"); table.ForeignKey( name: "fk_platform_billing_invoices_platform_billing_orders_tenant_id~", columns: x => new { x.tenant_id, x.order_id }, principalTable: "platform_billing_orders", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_platform_billing_invoices_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "platform_billing_order_items", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), tenant_id = table.Column(type: "uuid", nullable: false), order_id = table.Column(type: "uuid", nullable: false), offering_version_id = table.Column(type: "uuid", nullable: false), item_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), quantity = table.Column(type: "integer", nullable: false), unit_amount_cents = table.Column(type: "integer", nullable: false), amount_cents = table.Column(type: "integer", nullable: false), snapshot = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb") }, constraints: table => { table.PrimaryKey("pk_platform_billing_order_items", x => x.id); table.UniqueConstraint("ak_platform_billing_order_items_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_platform_billing_order_items_amounts", "quantity > 0 and unit_amount_cents >= 0 and amount_cents >= 0"); table.ForeignKey( name: "fk_platform_billing_order_items_platform_billing_orders_tenant~", columns: x => new { x.tenant_id, x.order_id }, principalTable: "platform_billing_orders", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_platform_billing_order_items_saas_offering_versions_offerin~", column: x => x.offering_version_id, principalTable: "saas_offering_versions", principalColumn: "id", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_platform_billing_order_items_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "platform_billing_payments", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), order_id = table.Column(type: "uuid", nullable: false), payment_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), idempotency_key = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), method = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), 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), client_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_platform_billing_payments", x => x.id); table.UniqueConstraint("ak_platform_billing_payments_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_platform_billing_payments_amount", "amount_cents >= 0"); table.ForeignKey( name: "fk_platform_billing_payments_platform_billing_orders_tenant_id~", columns: x => new { x.tenant_id, x.order_id }, principalTable: "platform_billing_orders", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_platform_billing_payments_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), 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: "point_exchange_orders", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), item_id = table.Column(type: "uuid", nullable: false), user_id = table.Column(type: "uuid", nullable: false), order_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), item_name = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), item_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), points_cost = table.Column(type: "integer", nullable: false), ordered_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), completed_at = table.Column(type: "timestamp with time zone", nullable: true), cancelled_at = table.Column(type: "timestamp with time zone", nullable: true), fulfillment_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), 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_point_exchange_orders", x => x.id); table.UniqueConstraint("ak_point_exchange_orders_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_point_exchange_orders_points_cost", "points_cost > 0"); table.ForeignKey( name: "fk_point_exchange_orders_point_exchange_items_tenant_id_item_id", columns: x => new { x.tenant_id, x.item_id }, principalTable: "point_exchange_items", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_point_exchange_orders_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_point_exchange_orders_users_user_id", column: x => x.user_id, principalTable: "users", 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_question_bank_preferences", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), question_bank_owner_tenant_id = table.Column(type: "uuid", nullable: false), question_bank_id = table.Column(type: "uuid", nullable: false), is_visible = table.Column(type: "boolean", nullable: false), alias = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), sort_order = table.Column(type: "integer", nullable: false), navigation_location = table.Column(type: "character varying(100)", maxLength: 100, nullable: true), created_by = table.Column(type: "uuid", nullable: true), updated_by = table.Column(type: "uuid", 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_question_bank_preferences", x => x.id); table.UniqueConstraint("ak_tenant_question_bank_preferences_tenant_id_id", x => new { x.tenant_id, x.id }); table.ForeignKey( name: "fk_tenant_question_bank_preferences_question_banks_question_ba~", columns: x => new { x.question_bank_owner_tenant_id, x.question_bank_id }, principalTable: "question_banks", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_tenant_question_bank_preferences_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_tenant_question_bank_preferences_users_created_by", column: x => x.created_by, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.SetNull); table.ForeignKey( name: "fk_tenant_question_bank_preferences_users_updated_by", column: x => x.updated_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_billing_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_platform_billing_invoice_reminders", x => x.id); table.UniqueConstraint("ak_platform_billing_invoice_reminders_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_platform_billing_invoice_reminders_balance", "balance_cents_snapshot >= 0"); table.CheckConstraint("ck_platform_billing_invoice_reminders_level", "reminder_level between 1 and 20"); table.ForeignKey( name: "fk_platform_billing_invoice_reminders_platform_billing_invoice~", columns: x => new { x.tenant_id, x.invoice_id }, principalTable: "platform_billing_invoices", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_platform_billing_invoice_reminders_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_platform_billing_invoice_reminders_users_created_by", column: x => x.created_by, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.SetNull); }); migrationBuilder.CreateTable( name: "tenant_saas_subscription_items", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), subscription_id = table.Column(type: "uuid", nullable: false), offering_version_id = table.Column(type: "uuid", nullable: false), source_order_item_id = table.Column(type: "uuid", nullable: true), item_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), starts_at = table.Column(type: "timestamp with time zone", nullable: false), ends_at = table.Column(type: "timestamp with time zone", 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_tenant_saas_subscription_items", x => x.id); table.UniqueConstraint("ak_tenant_saas_subscription_items_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_tenant_saas_subscription_items_period", "ends_at > starts_at"); table.ForeignKey( name: "fk_tenant_saas_subscription_items_platform_billing_order_items~", columns: x => new { x.tenant_id, x.source_order_item_id }, principalTable: "platform_billing_order_items", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_tenant_saas_subscription_items_saas_offering_versions_offer~", column: x => x.offering_version_id, principalTable: "saas_offering_versions", principalColumn: "id", onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_tenant_saas_subscription_items_tenant_saas_subscriptions_te~", columns: x => new { x.tenant_id, x.subscription_id }, principalTable: "tenant_saas_subscriptions", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_tenant_saas_subscription_items_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "platform_billing_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: false), provider = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), provider_event_id = table.Column(type: "character varying(200)", maxLength: 200, nullable: false), event_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), payload = 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_platform_billing_payment_events", x => x.id); table.UniqueConstraint("ak_platform_billing_payment_events_tenant_id_id", x => new { x.tenant_id, x.id }); table.ForeignKey( name: "fk_platform_billing_payment_events_platform_billing_payments_t~", columns: x => new { x.tenant_id, x.payment_id }, principalTable: "platform_billing_payments", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_platform_billing_payment_events_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "platform_billing_refunds", 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), refund_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), amount_cents = table.Column(type: "integer", nullable: false), reason = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: false), provider_refund_no = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), completed_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_platform_billing_refunds", x => x.id); table.UniqueConstraint("ak_platform_billing_refunds_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_platform_billing_refunds_amount", "amount_cents > 0"); table.ForeignKey( name: "fk_platform_billing_refunds_platform_billing_orders_tenant_id_~", columns: x => new { x.tenant_id, x.order_id }, principalTable: "platform_billing_orders", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_platform_billing_refunds_platform_billing_payments_tenant_i~", columns: x => new { x.tenant_id, x.payment_id }, principalTable: "platform_billing_payments", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_platform_billing_refunds_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: "platform_billing_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_billing_dunning_notification_events", x => x.id); table.UniqueConstraint("ak_platform_billing_dunning_notification_events_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_platform_billing_dunning_events_attempts", "attempts >= 0"); table.ForeignKey( name: "fk_platform_billing_dunning_events_channel", column: x => x.channel_id, principalTable: "platform_billing_dunning_notification_channels", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_platform_billing_dunning_events_invoice", columns: x => new { x.tenant_id, x.invoice_id }, principalTable: "platform_billing_invoices", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_platform_billing_dunning_events_reminder", columns: x => new { x.tenant_id, x.reminder_id }, principalTable: "platform_billing_invoice_reminders", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_platform_billing_dunning_notification_events_tenants_tenant~", 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: "scoreline_records", 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), legacy_id = table.Column(type: "character varying(64)", maxLength: 64, nullable: true), year = table.Column(type: "integer", nullable: false), school_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), major_name = table.Column(type: "character varying(300)", maxLength: 300, nullable: true), field_values = 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_scoreline_records", x => x.id); table.UniqueConstraint("ak_scoreline_records_tenant_id_id", x => new { x.tenant_id, x.id }); table.ForeignKey( name: "fk_scoreline_records_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_scoreline_records_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_scoreline_records_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_scoreline_records_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), avatar_preset = table.Column(type: "character varying(32)", maxLength: 32, nullable: false, defaultValue: "male"), 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: "background_jobs", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), job_type = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), payload = table.Column(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"), retry_count = table.Column(type: "integer", nullable: false), max_retries = table.Column(type: "integer", nullable: false), locked_by = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), lock_expires_at = table.Column(type: "timestamp with time zone", nullable: true), run_after = table.Column(type: "timestamp with time zone", nullable: true), started_at = table.Column(type: "timestamp with time zone", nullable: true), completed_at = table.Column(type: "timestamp with time zone", nullable: true), last_error = table.Column(type: "character varying(4000)", maxLength: 4000, nullable: true), output_asset_id = table.Column(type: "uuid", nullable: true), result = 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_background_jobs", x => x.id); table.UniqueConstraint("ak_background_jobs_tenant_id_id", x => new { x.tenant_id, x.id }); table.ForeignKey( name: "fk_background_jobs_content_assets_tenant_id_output_asset_id", columns: x => new { x.tenant_id, x.output_asset_id }, principalTable: "content_assets", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.SetNull); table.ForeignKey( name: "fk_background_jobs_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( name: "commission_settlement_proofs", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), settlement_id = table.Column(type: "uuid", nullable: false), asset_id = table.Column(type: "uuid", nullable: true), submitted_by = table.Column(type: "uuid", nullable: true), reviewed_by = table.Column(type: "uuid", nullable: true), proof_type = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), title = table.Column(type: "character varying(200)", maxLength: 200, nullable: true), description = table.Column(type: "text", nullable: true), external_url = table.Column(type: "character varying(2048)", maxLength: 2048, nullable: true), amount_cents = table.Column(type: "integer", 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), paid_at = table.Column(type: "timestamp with time zone", nullable: true), reviewed_at = table.Column(type: "timestamp with time zone", nullable: true), review_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_commission_settlement_proofs", x => x.id); table.UniqueConstraint("ak_commission_settlement_proofs_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_commission_settlement_proofs_amount", "amount_cents is null or amount_cents >= 0"); table.ForeignKey( name: "fk_commission_settlement_proofs_commission_settlements_tenant_~", columns: x => new { x.tenant_id, x.settlement_id }, principalTable: "commission_settlements", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_commission_settlement_proofs_content_assets_tenant_id_asset~", columns: x => new { x.tenant_id, x.asset_id }, principalTable: "content_assets", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.SetNull); table.ForeignKey( name: "fk_commission_settlement_proofs_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_commission_settlement_proofs_users_reviewed_by", column: x => x.reviewed_by, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.SetNull); table.ForeignKey( name: "fk_commission_settlement_proofs_users_submitted_by", column: x => x.submitted_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: "commerce_adjustment_vouchers", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), issue_id = table.Column(type: "uuid", nullable: true), 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), created_by = table.Column(type: "uuid", nullable: true), reviewed_by = table.Column(type: "uuid", nullable: true), voucher_no = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), status = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), direction = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), amount_cents = table.Column(type: "integer", nullable: false), currency = table.Column(type: "character varying(10)", maxLength: 10, nullable: false), reason = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: false), proof_asset_key = table.Column(type: "character varying(500)", maxLength: 500, nullable: true), reviewed_at = table.Column(type: "timestamp with time zone", nullable: true), closed_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_commerce_adjustment_vouchers", x => x.id); table.UniqueConstraint("ak_commerce_adjustment_vouchers_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_commerce_adjustment_vouchers_amount", "amount_cents > 0"); table.ForeignKey( name: "fk_commerce_adjustment_vouchers_commerce_reconciliation_batche~", columns: x => new { x.tenant_id, x.batch_id }, principalTable: "commerce_reconciliation_batches", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.SetNull); table.ForeignKey( name: "fk_commerce_adjustment_vouchers_commerce_reconciliation_issues~", columns: x => new { x.tenant_id, x.issue_id }, principalTable: "commerce_reconciliation_issues", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.SetNull); table.ForeignKey( name: "fk_commerce_adjustment_vouchers_commerce_reconciliation_items_~", columns: x => new { x.tenant_id, x.item_id }, principalTable: "commerce_reconciliation_items", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.SetNull); table.ForeignKey( name: "fk_commerce_adjustment_vouchers_commerce_refund_requests_tenan~", columns: x => new { x.tenant_id, x.refund_request_id }, principalTable: "commerce_refund_requests", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.SetNull); table.ForeignKey( name: "fk_commerce_adjustment_vouchers_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_commerce_adjustment_vouchers_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_commerce_adjustment_vouchers_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_commerce_adjustment_vouchers_users_created_by", column: x => x.created_by, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.SetNull); table.ForeignKey( name: "fk_commerce_adjustment_vouchers_users_reviewed_by", column: x => x.reviewed_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_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: "commerce_adjustment_voucher_events", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), tenant_id = table.Column(type: "uuid", nullable: false), voucher_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), actor_user_id = table.Column(type: "uuid", nullable: true), note = table.Column(type: "character varying(1000)", maxLength: 1000, 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_adjustment_voucher_events", x => x.id); table.UniqueConstraint("ak_commerce_adjustment_voucher_events_tenant_id_id", x => new { x.tenant_id, x.id }); table.ForeignKey( name: "fk_commerce_adjustment_voucher_events_commerce_adjustment_vouc~", columns: x => new { x.tenant_id, x.voucher_id }, principalTable: "commerce_adjustment_vouchers", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_commerce_adjustment_voucher_events_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_commerce_adjustment_voucher_events_users_actor_user_id", column: x => x.actor_user_id, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.SetNull); }); 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), practice_session_id = table.Column(type: "uuid", nullable: false), session_question_id = table.Column(type: "uuid", nullable: false), 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.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_reference_id = table.Column(type: "uuid", nullable: false), question_owner_tenant_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_reference_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: "practice_session_questions", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), practice_session_id = table.Column(type: "uuid", nullable: false), question_reference_id = table.Column(type: "uuid", nullable: false), question_owner_tenant_id = table.Column(type: "uuid", nullable: false), question_id = table.Column(type: "uuid", nullable: false), question_version_id = table.Column(type: "uuid", nullable: false), position = table.Column(type: "integer", nullable: false), score = table.Column(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true), tenant_id = table.Column(type: "uuid", nullable: false) }, constraints: table => { table.PrimaryKey("pk_practice_session_questions", x => x.id); table.UniqueConstraint("ak_practice_session_questions_tenant_id_id", x => new { x.tenant_id, x.id }); table.UniqueConstraint("ak_practice_session_questions_tenant_id_practice_session_id_id", x => new { x.tenant_id, x.practice_session_id, x.id }); table.ForeignKey( name: "fk_practice_session_questions_practice_sessions_tenant_id_prac~", 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_questions_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", 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_reference_id = table.Column(type: "uuid", nullable: false), question_owner_tenant_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_taxonomy_assignments", 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), taxonomy_owner_tenant_id = table.Column(type: "uuid", nullable: false), taxonomy_node_id = table.Column(type: "uuid", nullable: false), is_primary = table.Column(type: "boolean", nullable: false), created_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()") }, constraints: table => { table.PrimaryKey("pk_question_taxonomy_assignments", x => x.id); table.UniqueConstraint("ak_question_taxonomy_assignments_tenant_id_id", x => new { x.tenant_id, x.id }); table.ForeignKey( name: "fk_question_taxonomy_assignments_taxonomy_nodes_taxonomy_owner~", columns: x => new { x.taxonomy_owner_tenant_id, x.taxonomy_node_id }, principalTable: "taxonomy_nodes", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); }); 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: "tenant_question_references", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), question_owner_tenant_id = table.Column(type: "uuid", nullable: false), question_id = table.Column(type: "uuid", nullable: false), source = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), created_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_question_references", x => x.id); table.UniqueConstraint("ak_tenant_question_references_tenant_id_id", x => new { x.tenant_id, x.id }); table.UniqueConstraint("ak_tenant_question_references_tenant_id_question_owner_tenant_~", x => new { x.tenant_id, x.question_owner_tenant_id, x.question_id }); table.ForeignKey( name: "fk_tenant_question_references_questions_question_owner_tenant_~", columns: x => new { x.question_owner_tenant_id, x.question_id }, principalTable: "questions", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_tenant_question_references_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_tenant_question_references_users_created_by", column: x => x.created_by, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.SetNull); }); migrationBuilder.CreateTable( name: "video_playback_progress", columns: table => new { id = table.Column(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"), user_id = table.Column(type: "uuid", nullable: false), video_id = table.Column(type: "uuid", nullable: false), question_id = table.Column(type: "uuid", nullable: true), position_seconds = table.Column(type: "integer", nullable: false), duration_seconds = table.Column(type: "integer", nullable: true), watched_seconds = table.Column(type: "integer", nullable: false), is_completed = table.Column(type: "boolean", nullable: false), completed_at = table.Column(type: "timestamp with time zone", nullable: true), last_played_at = table.Column(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"), play_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_video_playback_progress", x => x.id); table.UniqueConstraint("ak_video_playback_progress_tenant_id_id", x => new { x.tenant_id, x.id }); table.CheckConstraint("ck_video_playback_progress_duration", "duration_seconds is null or duration_seconds >= 0"); table.CheckConstraint("ck_video_playback_progress_play_count", "play_count >= 0"); table.CheckConstraint("ck_video_playback_progress_position", "position_seconds >= 0"); table.CheckConstraint("ck_video_playback_progress_watched", "watched_seconds >= 0"); table.ForeignKey( name: "fk_video_playback_progress_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_video_playback_progress_tenants_tenant_id", column: x => x.tenant_id, principalTable: "tenants", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_video_playback_progress_users_user_id", column: x => x.user_id, principalTable: "users", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "fk_video_playback_progress_video_explanations_tenant_id_video_~", columns: x => new { x.tenant_id, x.video_id }, principalTable: "video_explanations", principalColumns: new[] { "tenant_id", "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: "wrong_questions", columns: table => new { tenant_id = table.Column(type: "uuid", nullable: false), user_id = table.Column(type: "uuid", nullable: false), question_reference_id = table.Column(type: "uuid", nullable: false), question_owner_tenant_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_reference_id }); table.ForeignKey( name: "fk_wrong_questions_questions_question_owner_tenant_id_question~", columns: x => new { x.question_owner_tenant_id, x.question_id }, principalTable: "questions", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); table.ForeignKey( name: "fk_wrong_questions_tenant_question_references_tenant_id_questi~", columns: x => new { x.tenant_id, x.question_reference_id }, principalTable: "tenant_question_references", 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: "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_practice_session_id_session_questi~", table: "answer_records", columns: new[] { "tenant_id", "practice_session_id", "session_question_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_challenges_tenant_id", table: "auth_challenges", column: "tenant_id"); migrationBuilder.CreateIndex( name: "ix_auth_challenges_token_hash", table: "auth_challenges", column: "token_hash", unique: true); migrationBuilder.CreateIndex( name: "ix_auth_challenges_user_id_purpose_expires_at", table: "auth_challenges", columns: new[] { "user_id", "purpose", "expires_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_realm_tenant_id_user_id_expires_at", table: "auth_sessions", columns: new[] { "realm", "tenant_id", "user_id", "expires_at" }, filter: "revoked_at is null"); migrationBuilder.CreateIndex( name: "ix_auth_sessions_tenant_id", table: "auth_sessions", column: "tenant_id"); migrationBuilder.CreateIndex( name: "ix_auth_sessions_token_family_id_revoked_at", table: "auth_sessions", columns: new[] { "token_family_id", "revoked_at" }); 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_backend_menus_area_parent_code_sort_order", table: "backend_menus", columns: new[] { "area", "parent_code", "sort_order" }); migrationBuilder.CreateIndex( name: "ix_backend_menus_code", table: "backend_menus", column: "code", unique: true); migrationBuilder.CreateIndex( name: "ix_backend_menus_permission_code", table: "backend_menus", column: "permission_code"); migrationBuilder.CreateIndex( name: "ix_backend_permissions_area_permission_module_code_sort_order", table: "backend_permissions", columns: new[] { "area", "permission_module_code", "sort_order" }); migrationBuilder.CreateIndex( name: "ix_backend_permissions_code", table: "backend_permissions", column: "code", unique: true); migrationBuilder.CreateIndex( name: "ix_backend_permissions_permission_module_code", table: "backend_permissions", column: "permission_module_code"); migrationBuilder.CreateIndex( name: "ix_background_jobs_tenant_id_job_type_status_created_at", table: "background_jobs", columns: new[] { "tenant_id", "job_type", "status", "created_at" }); migrationBuilder.CreateIndex( name: "ix_background_jobs_tenant_id_output_asset_id", table: "background_jobs", columns: new[] { "tenant_id", "output_asset_id" }); migrationBuilder.CreateIndex( name: "ix_background_jobs_tenant_id_status_run_after_created_at", table: "background_jobs", columns: new[] { "tenant_id", "status", "run_after", "created_at" }); migrationBuilder.CreateIndex( name: "ix_badges_tenant_id_category_is_active_sort_order", table: "badges", 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_adjustment_voucher_events_actor_user_id", table: "commerce_adjustment_voucher_events", column: "actor_user_id"); migrationBuilder.CreateIndex( name: "ix_commerce_adjustment_voucher_events_tenant_id_voucher_id_cre~", table: "commerce_adjustment_voucher_events", columns: new[] { "tenant_id", "voucher_id", "created_at" }); migrationBuilder.CreateIndex( name: "ix_commerce_adjustment_vouchers_created_by", table: "commerce_adjustment_vouchers", column: "created_by"); migrationBuilder.CreateIndex( name: "ix_commerce_adjustment_vouchers_reviewed_by", table: "commerce_adjustment_vouchers", column: "reviewed_by"); migrationBuilder.CreateIndex( name: "ix_commerce_adjustment_vouchers_tenant_id_batch_id", table: "commerce_adjustment_vouchers", columns: new[] { "tenant_id", "batch_id" }); migrationBuilder.CreateIndex( name: "ix_commerce_adjustment_vouchers_tenant_id_issue_id_created_at", table: "commerce_adjustment_vouchers", columns: new[] { "tenant_id", "issue_id", "created_at" }); migrationBuilder.CreateIndex( name: "ix_commerce_adjustment_vouchers_tenant_id_item_id", table: "commerce_adjustment_vouchers", columns: new[] { "tenant_id", "item_id" }); migrationBuilder.CreateIndex( name: "ix_commerce_adjustment_vouchers_tenant_id_order_id", table: "commerce_adjustment_vouchers", columns: new[] { "tenant_id", "order_id" }); migrationBuilder.CreateIndex( name: "ix_commerce_adjustment_vouchers_tenant_id_payment_id", table: "commerce_adjustment_vouchers", columns: new[] { "tenant_id", "payment_id" }); migrationBuilder.CreateIndex( name: "ix_commerce_adjustment_vouchers_tenant_id_refund_request_id", table: "commerce_adjustment_vouchers", columns: new[] { "tenant_id", "refund_request_id" }); migrationBuilder.CreateIndex( name: "ix_commerce_adjustment_vouchers_tenant_id_status_created_at", table: "commerce_adjustment_vouchers", columns: new[] { "tenant_id", "status", "created_at" }); migrationBuilder.CreateIndex( name: "ix_commerce_adjustment_vouchers_tenant_id_voucher_no", table: "commerce_adjustment_vouchers", columns: new[] { "tenant_id", "voucher_no" }, 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_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_batch_id_row_no", table: "commerce_reconciliation_items", columns: new[] { "tenant_id", "batch_id", "row_no" }, unique: true); 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_export_events_exported_by", table: "commission_settlement_export_events", column: "exported_by"); migrationBuilder.CreateIndex( name: "ix_commission_settlement_export_events_tenant_id_settlement_id~", table: "commission_settlement_export_events", columns: new[] { "tenant_id", "settlement_id", "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_settlement_proofs_reviewed_by", table: "commission_settlement_proofs", column: "reviewed_by"); migrationBuilder.CreateIndex( name: "ix_commission_settlement_proofs_submitted_by", table: "commission_settlement_proofs", column: "submitted_by"); migrationBuilder.CreateIndex( name: "ix_commission_settlement_proofs_tenant_id_asset_id", table: "commission_settlement_proofs", columns: new[] { "tenant_id", "asset_id" }); migrationBuilder.CreateIndex( name: "ix_commission_settlement_proofs_tenant_id_settlement_id_status~", table: "commission_settlement_proofs", columns: new[] { "tenant_id", "settlement_id", "status", "created_at" }); 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_tenant_id_job_id_row_no", table: "content_import_items", columns: new[] { "tenant_id", "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_question_owner_tenant_id_question_id", table: "favorite_questions", columns: new[] { "question_owner_tenant_id", "question_id" }); migrationBuilder.CreateIndex( name: "ix_favorite_questions_tenant_id_question_reference_id", table: "favorite_questions", columns: new[] { "tenant_id", "question_reference_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_inbox_state_delivered", table: "inbox_state", column: "delivered"); 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_outbox_message_enqueue_time", table: "outbox_message", column: "enqueue_time"); migrationBuilder.CreateIndex( name: "ix_outbox_message_expiration_time", table: "outbox_message", column: "expiration_time"); migrationBuilder.CreateIndex( name: "ix_outbox_message_inbox_message_id_inbox_consumer_id_sequence_~", table: "outbox_message", columns: new[] { "inbox_message_id", "inbox_consumer_id", "sequence_number" }, unique: true); migrationBuilder.CreateIndex( name: "ix_outbox_message_outbox_id_sequence_number", table: "outbox_message", columns: new[] { "outbox_id", "sequence_number" }, unique: true); migrationBuilder.CreateIndex( name: "ix_outbox_state_created", table: "outbox_state", column: "created"); migrationBuilder.CreateIndex( name: "ix_payment_events_tenant_id_payment_id", table: "payment_events", columns: new[] { "tenant_id", "payment_id" }); migrationBuilder.CreateIndex( name: "ix_payment_events_tenant_id_provider_event_id", table: "payment_events", columns: new[] { "tenant_id", "provider", "event_id" }, unique: true); 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_payments_tenant_id_provider_provider_trade_no", table: "payments", columns: new[] { "tenant_id", "provider", "provider_trade_no" }, unique: true, filter: "provider_trade_no is not null"); 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_permission_modules_area_sort_order", table: "permission_modules", columns: new[] { "area", "sort_order" }); migrationBuilder.CreateIndex( name: "ix_permission_modules_code", table: "permission_modules", column: "code", unique: true); migrationBuilder.CreateIndex( name: "ix_permission_modules_required_feature_code", table: "permission_modules", column: "required_feature_code"); 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_backend_role_menus_menu_code", table: "platform_backend_role_menus", column: "menu_code"); migrationBuilder.CreateIndex( name: "ix_platform_backend_role_menus_role_id_menu_code", table: "platform_backend_role_menus", columns: new[] { "role_id", "menu_code" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_backend_role_permissions_permission_code", table: "platform_backend_role_permissions", column: "permission_code"); migrationBuilder.CreateIndex( name: "ix_platform_backend_role_permissions_role_id_permission_code", table: "platform_backend_role_permissions", columns: new[] { "role_id", "permission_code" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_backend_roles_code", table: "platform_backend_roles", column: "code", unique: true); migrationBuilder.CreateIndex( name: "ix_platform_backend_roles_status_code", table: "platform_backend_roles", columns: new[] { "status", "code" }); migrationBuilder.CreateIndex( name: "ix_platform_backend_user_roles_role_id", table: "platform_backend_user_roles", column: "role_id"); migrationBuilder.CreateIndex( name: "ix_platform_backend_user_roles_user_id_role_id", table: "platform_backend_user_roles", columns: new[] { "user_id", "role_id" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_dunning_notification_channels_channel_code", table: "platform_billing_dunning_notification_channels", column: "channel_code", unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_dunning_notification_channels_enabled_min_~", table: "platform_billing_dunning_notification_channels", columns: new[] { "enabled", "min_reminder_level", "channel_code" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_dunning_notification_events_channel_id", table: "platform_billing_dunning_notification_events", column: "channel_id"); migrationBuilder.CreateIndex( name: "ix_platform_billing_dunning_notification_events_invoice_id_sta~", table: "platform_billing_dunning_notification_events", columns: new[] { "invoice_id", "status", "created_at" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_dunning_notification_events_reminder_id_st~", table: "platform_billing_dunning_notification_events", columns: new[] { "reminder_id", "status", "created_at" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_dunning_notification_events_status_next_at~", table: "platform_billing_dunning_notification_events", columns: new[] { "status", "next_attempt_at", "scheduled_at", "created_at" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_dunning_notification_events_tenant_id_chan~", table: "platform_billing_dunning_notification_events", columns: new[] { "tenant_id", "channel_id", "reminder_id" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_dunning_notification_events_tenant_id_invo~", table: "platform_billing_dunning_notification_events", columns: new[] { "tenant_id", "invoice_id" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_dunning_notification_events_tenant_id_remi~", table: "platform_billing_dunning_notification_events", columns: new[] { "tenant_id", "reminder_id" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_dunning_notification_events_tenant_id_stat~", table: "platform_billing_dunning_notification_events", columns: new[] { "tenant_id", "status", "created_at" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_invoice_reminders_created_by", table: "platform_billing_invoice_reminders", column: "created_by"); migrationBuilder.CreateIndex( name: "ix_platform_billing_invoice_reminders_invoice_id_reminder_date", table: "platform_billing_invoice_reminders", columns: new[] { "invoice_id", "reminder_date" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_invoice_reminders_tenant_id_invoice_id_rem~", table: "platform_billing_invoice_reminders", columns: new[] { "tenant_id", "invoice_id", "reminder_type", "channel", "reminder_date" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_invoice_reminders_tenant_id_status_reminde~", table: "platform_billing_invoice_reminders", columns: new[] { "tenant_id", "status", "reminder_date" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_invoices_tenant_id_invoice_no", table: "platform_billing_invoices", columns: new[] { "tenant_id", "invoice_no" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_invoices_tenant_id_order_id", table: "platform_billing_invoices", columns: new[] { "tenant_id", "order_id" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_invoices_tenant_id_status_due_date", table: "platform_billing_invoices", columns: new[] { "tenant_id", "status", "due_date" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_order_items_offering_version_id", table: "platform_billing_order_items", column: "offering_version_id"); migrationBuilder.CreateIndex( name: "ix_platform_billing_order_items_tenant_id_order_id_offering_ve~", table: "platform_billing_order_items", columns: new[] { "tenant_id", "order_id", "offering_version_id" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_orders_tenant_id_idempotency_key", table: "platform_billing_orders", columns: new[] { "tenant_id", "idempotency_key" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_orders_tenant_id_order_no", table: "platform_billing_orders", columns: new[] { "tenant_id", "order_no" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_orders_tenant_id_quote_id", table: "platform_billing_orders", columns: new[] { "tenant_id", "quote_id" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_orders_tenant_id_status_created_at", table: "platform_billing_orders", columns: new[] { "tenant_id", "status", "created_at" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_payment_events_tenant_id_payment_id_create~", table: "platform_billing_payment_events", columns: new[] { "tenant_id", "payment_id", "created_at" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_payment_events_tenant_id_provider_provider~", table: "platform_billing_payment_events", columns: new[] { "tenant_id", "provider", "provider_event_id" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_payments_tenant_id_idempotency_key", table: "platform_billing_payments", columns: new[] { "tenant_id", "idempotency_key" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_payments_tenant_id_order_id_status", table: "platform_billing_payments", columns: new[] { "tenant_id", "order_id", "status" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_payments_tenant_id_payment_no", table: "platform_billing_payments", columns: new[] { "tenant_id", "payment_no" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_quote_items_offering_version_id", table: "platform_billing_quote_items", column: "offering_version_id"); migrationBuilder.CreateIndex( name: "ix_platform_billing_quote_items_tenant_id_quote_id_offering_ve~", table: "platform_billing_quote_items", columns: new[] { "tenant_id", "quote_id", "offering_version_id" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_quotes_tenant_id_idempotency_key", table: "platform_billing_quotes", columns: new[] { "tenant_id", "idempotency_key" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_quotes_tenant_id_quote_no", table: "platform_billing_quotes", columns: new[] { "tenant_id", "quote_no" }, unique: true); migrationBuilder.CreateIndex( name: "ix_platform_billing_quotes_tenant_id_status_expires_at", table: "platform_billing_quotes", columns: new[] { "tenant_id", "status", "expires_at" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_refunds_tenant_id_order_id_status", table: "platform_billing_refunds", columns: new[] { "tenant_id", "order_id", "status" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_refunds_tenant_id_payment_id", table: "platform_billing_refunds", columns: new[] { "tenant_id", "payment_id" }); migrationBuilder.CreateIndex( name: "ix_platform_billing_refunds_tenant_id_refund_no", table: "platform_billing_refunds", columns: new[] { "tenant_id", "refund_no" }, unique: true); migrationBuilder.CreateIndex( name: "ix_point_activity_claims_tenant_id_task_id", table: "point_activity_claims", columns: new[] { "tenant_id", "task_id" }); migrationBuilder.CreateIndex( name: "ix_point_activity_claims_tenant_id_user_id_created_at", table: "point_activity_claims", columns: new[] { "tenant_id", "user_id", "created_at" }); migrationBuilder.CreateIndex( name: "ix_point_activity_claims_tenant_id_user_id_task_id_source_type~", table: "point_activity_claims", columns: new[] { "tenant_id", "user_id", "task_id", "source_type", "source_id" }, unique: true, filter: "source_type is not null and source_id is not null"); migrationBuilder.CreateIndex( name: "ix_point_activity_claims_user_id", table: "point_activity_claims", column: "user_id"); migrationBuilder.CreateIndex( name: "ix_point_activity_tasks_tenant_id_status_sort_order", table: "point_activity_tasks", columns: new[] { "tenant_id", "status", "sort_order" }); migrationBuilder.CreateIndex( name: "ix_point_activity_tasks_tenant_id_task_key", table: "point_activity_tasks", columns: new[] { "tenant_id", "task_key" }, unique: true); migrationBuilder.CreateIndex( name: "ix_point_exchange_items_tenant_id_item_key", table: "point_exchange_items", columns: new[] { "tenant_id", "item_key" }, unique: true); migrationBuilder.CreateIndex( name: "ix_point_exchange_items_tenant_id_region_id_status_sort_order", table: "point_exchange_items", columns: new[] { "tenant_id", "region_id", "status", "sort_order" }); migrationBuilder.CreateIndex( name: "ix_point_exchange_orders_tenant_id_item_id", table: "point_exchange_orders", columns: new[] { "tenant_id", "item_id" }); migrationBuilder.CreateIndex( name: "ix_point_exchange_orders_tenant_id_order_no", table: "point_exchange_orders", columns: new[] { "tenant_id", "order_no" }, unique: true); migrationBuilder.CreateIndex( name: "ix_point_exchange_orders_tenant_id_user_id_created_at", table: "point_exchange_orders", columns: new[] { "tenant_id", "user_id", "created_at" }); migrationBuilder.CreateIndex( name: "ix_point_exchange_orders_user_id", table: "point_exchange_orders", column: "user_id"); 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_questions_question_owner_tenant_id_questio~", table: "practice_session_questions", columns: new[] { "question_owner_tenant_id", "question_id", "question_version_id" }); migrationBuilder.CreateIndex( name: "ix_practice_session_questions_tenant_id_practice_session_id_po~", table: "practice_session_questions", columns: new[] { "tenant_id", "practice_session_id", "position" }, unique: true); migrationBuilder.CreateIndex( name: "ix_practice_session_questions_tenant_id_question_owner_tenant_~", table: "practice_session_questions", columns: new[] { "tenant_id", "question_owner_tenant_id", "question_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_is_active_sort_order", table: "products", columns: new[] { "tenant_id", "region_id", "type", "is_active", "sort_order" }); 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_question_owner_tenant_id_question~", table: "question_collection_items", columns: new[] { "question_owner_tenant_id", "question_id" }); migrationBuilder.CreateIndex( name: "ix_question_collection_items_tenant_id_collection_id_question_~", table: "question_collection_items", columns: new[] { "tenant_id", "collection_id", "question_reference_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_reference_id", table: "question_collection_items", columns: new[] { "tenant_id", "question_reference_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_taxonomy_assignments_taxonomy_owner_tenant_id_taxo~", table: "question_taxonomy_assignments", columns: new[] { "taxonomy_owner_tenant_id", "taxonomy_node_id" }); migrationBuilder.CreateIndex( name: "ix_question_taxonomy_assignments_tenant_id_question_id_taxonom~", table: "question_taxonomy_assignments", columns: new[] { "tenant_id", "question_id", "taxonomy_owner_tenant_id", "taxonomy_node_id" }, unique: true); 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_tenant_id_question_id_version_no", table: "question_versions", columns: new[] { "tenant_id", "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_saas_feature_limit_definitions_feature_code_kind", table: "saas_feature_limit_definitions", columns: new[] { "feature_code", "kind" }); migrationBuilder.CreateIndex( name: "ix_saas_feature_limit_definitions_metric_code", table: "saas_feature_limit_definitions", column: "metric_code", unique: true); migrationBuilder.CreateIndex( name: "ix_saas_features_code", table: "saas_features", column: "code", unique: true); migrationBuilder.CreateIndex( name: "ix_saas_features_status_category_sort_order", table: "saas_features", columns: new[] { "status", "category", "sort_order" }); migrationBuilder.CreateIndex( name: "ix_saas_offering_version_features_feature_code", table: "saas_offering_version_features", column: "feature_code"); migrationBuilder.CreateIndex( name: "ix_saas_offering_version_features_offering_version_id_feature_~", table: "saas_offering_version_features", columns: new[] { "offering_version_id", "feature_code" }, unique: true); migrationBuilder.CreateIndex( name: "ix_saas_offering_version_limits_metric_code", table: "saas_offering_version_limits", column: "metric_code"); migrationBuilder.CreateIndex( name: "ix_saas_offering_version_limits_offering_version_id_metric_code", table: "saas_offering_version_limits", columns: new[] { "offering_version_id", "metric_code" }, unique: true); migrationBuilder.CreateIndex( name: "ix_saas_offering_versions_offering_id_status_effective_at", table: "saas_offering_versions", columns: new[] { "offering_id", "status", "effective_at" }); migrationBuilder.CreateIndex( name: "ix_saas_offering_versions_offering_id_version", table: "saas_offering_versions", columns: new[] { "offering_id", "version" }, unique: true); migrationBuilder.CreateIndex( name: "ix_saas_offerings_code", table: "saas_offerings", column: "code", unique: true); migrationBuilder.CreateIndex( name: "ix_saas_offerings_type_status_sort_order", table: "saas_offerings", columns: new[] { "type", "status", "sort_order" }); 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_scoreline_fields_tenant_id_legacy_id", table: "scoreline_fields", columns: new[] { "tenant_id", "legacy_id" }, unique: true); migrationBuilder.CreateIndex( name: "ix_scoreline_fields_tenant_id_region_id_field_key", table: "scoreline_fields", columns: new[] { "tenant_id", "region_id", "field_key" }, unique: true); migrationBuilder.CreateIndex( name: "ix_scoreline_fields_tenant_id_region_id_is_filter_sort_order", table: "scoreline_fields", columns: new[] { "tenant_id", "region_id", "is_filter", "sort_order" }); migrationBuilder.CreateIndex( name: "ix_scoreline_records_tenant_id_legacy_id", table: "scoreline_records", columns: new[] { "tenant_id", "legacy_id" }, unique: true); migrationBuilder.CreateIndex( name: "ix_scoreline_records_tenant_id_major_id", table: "scoreline_records", columns: new[] { "tenant_id", "major_id" }); migrationBuilder.CreateIndex( name: "ix_scoreline_records_tenant_id_region_id_school_id_major_id_ye~", table: "scoreline_records", columns: new[] { "tenant_id", "region_id", "school_id", "major_id", "year" }); migrationBuilder.CreateIndex( name: "ix_scoreline_records_tenant_id_school_id", table: "scoreline_records", columns: new[] { "tenant_id", "school_id" }); migrationBuilder.CreateIndex( name: "ix_scoreline_records_tenant_id_year", table: "scoreline_records", columns: new[] { "tenant_id", "year" }); 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_taxonomy_nodes_parent_owner_tenant_id_parent_id", table: "taxonomy_nodes", columns: new[] { "parent_owner_tenant_id", "parent_id" }); migrationBuilder.CreateIndex( name: "ix_taxonomy_nodes_tenant_id_code", table: "taxonomy_nodes", columns: new[] { "tenant_id", "code" }, unique: true); migrationBuilder.CreateIndex( name: "ix_tenant_backend_role_menus_menu_code", table: "tenant_backend_role_menus", column: "menu_code"); migrationBuilder.CreateIndex( name: "ix_tenant_backend_role_menus_tenant_id_role_id_menu_code", table: "tenant_backend_role_menus", columns: new[] { "tenant_id", "role_id", "menu_code" }, unique: true); migrationBuilder.CreateIndex( name: "ix_tenant_backend_role_permissions_permission_code", table: "tenant_backend_role_permissions", column: "permission_code"); migrationBuilder.CreateIndex( name: "ix_tenant_backend_role_permissions_tenant_id_role_id_permissio~", table: "tenant_backend_role_permissions", columns: new[] { "tenant_id", "role_id", "permission_code" }, unique: true); migrationBuilder.CreateIndex( name: "ix_tenant_backend_roles_tenant_id_code", table: "tenant_backend_roles", columns: new[] { "tenant_id", "code" }, unique: true); migrationBuilder.CreateIndex( name: "ix_tenant_backend_roles_tenant_id_status_code", table: "tenant_backend_roles", columns: new[] { "tenant_id", "status", "code" }); migrationBuilder.CreateIndex( name: "ix_tenant_backend_user_roles_tenant_id_role_id", table: "tenant_backend_user_roles", columns: new[] { "tenant_id", "role_id" }); migrationBuilder.CreateIndex( name: "ix_tenant_backend_user_roles_tenant_id_user_id_role_id", table: "tenant_backend_user_roles", columns: new[] { "tenant_id", "user_id", "role_id" }, unique: true); migrationBuilder.CreateIndex( name: "ix_tenant_backend_user_roles_user_id", table: "tenant_backend_user_roles", column: "user_id"); migrationBuilder.CreateIndex( name: "ix_tenant_class_members_tenant_id_class_id_status_member_type", table: "tenant_class_members", 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_external_providers_tenant_id_capability_provider", table: "tenant_external_providers", columns: new[] { "tenant_id", "capability", "provider" }, unique: true); migrationBuilder.CreateIndex( name: "ix_tenant_external_providers_tenant_id_capability_status_prior~", table: "tenant_external_providers", columns: new[] { "tenant_id", "capability", "status", "priority" }); migrationBuilder.CreateIndex( name: "ix_tenant_feature_overrides_feature_code", table: "tenant_feature_overrides", column: "feature_code"); migrationBuilder.CreateIndex( name: "ix_tenant_feature_overrides_tenant_id_feature_code", table: "tenant_feature_overrides", columns: new[] { "tenant_id", "feature_code" }, unique: true); migrationBuilder.CreateIndex( name: "ix_tenant_feature_usage_metric_code", table: "tenant_feature_usage", column: "metric_code"); migrationBuilder.CreateIndex( name: "ix_tenant_feature_usage_tenant_id_metric_code_period_start_per~", table: "tenant_feature_usage", columns: new[] { "tenant_id", "metric_code", "period_start", "period_end" }, unique: true); migrationBuilder.CreateIndex( name: "ix_tenant_frontend_configs_tenant_id", table: "tenant_frontend_configs", column: "tenant_id", unique: true); 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_question_bank_preferences_created_by", table: "tenant_question_bank_preferences", column: "created_by"); migrationBuilder.CreateIndex( name: "ix_tenant_question_bank_preferences_question_bank_owner_tenant~", table: "tenant_question_bank_preferences", columns: new[] { "question_bank_owner_tenant_id", "question_bank_id" }); migrationBuilder.CreateIndex( name: "ix_tenant_question_bank_preferences_tenant_id_question_bank_ow~", table: "tenant_question_bank_preferences", columns: new[] { "tenant_id", "question_bank_owner_tenant_id", "question_bank_id" }, unique: true); migrationBuilder.CreateIndex( name: "ix_tenant_question_bank_preferences_updated_by", table: "tenant_question_bank_preferences", column: "updated_by"); migrationBuilder.CreateIndex( name: "ix_tenant_question_references_created_by", table: "tenant_question_references", column: "created_by"); migrationBuilder.CreateIndex( name: "ix_tenant_question_references_question_owner_tenant_id_questio~", table: "tenant_question_references", columns: new[] { "question_owner_tenant_id", "question_id" }); migrationBuilder.CreateIndex( name: "ix_tenant_saas_subscription_items_offering_version_id", table: "tenant_saas_subscription_items", column: "offering_version_id"); migrationBuilder.CreateIndex( name: "ix_tenant_saas_subscription_items_tenant_id_source_order_item_~", table: "tenant_saas_subscription_items", columns: new[] { "tenant_id", "source_order_item_id" }); migrationBuilder.CreateIndex( name: "ix_tenant_saas_subscription_items_tenant_id_subscription_id_of~", table: "tenant_saas_subscription_items", columns: new[] { "tenant_id", "subscription_id", "offering_version_id", "status" }); migrationBuilder.CreateIndex( name: "ux_tenant_saas_subscription_items_current_base", table: "tenant_saas_subscription_items", columns: new[] { "tenant_id", "subscription_id", "item_type" }, unique: true, filter: "item_type = 'base_plan' and status = 'active'"); migrationBuilder.CreateIndex( name: "ux_tenant_saas_subscription_items_scheduled_base", table: "tenant_saas_subscription_items", columns: new[] { "tenant_id", "subscription_id", "status" }, unique: true, filter: "item_type = 'base_plan' and status = 'scheduled'"); migrationBuilder.CreateIndex( name: "ix_tenant_saas_subscriptions_base_offering_version_id", table: "tenant_saas_subscriptions", column: "base_offering_version_id"); migrationBuilder.CreateIndex( name: "ix_tenant_saas_subscriptions_scheduled_base_offering_version_id", table: "tenant_saas_subscriptions", column: "scheduled_base_offering_version_id"); migrationBuilder.CreateIndex( name: "ix_tenant_saas_subscriptions_tenant_id", table: "tenant_saas_subscriptions", column: "tenant_id", unique: true, filter: "status in ('trial', 'active', 'past_due', 'suspended')"); migrationBuilder.CreateIndex( name: "ix_tenant_saas_subscriptions_tenant_id_status_current_period_e~", table: "tenant_saas_subscriptions", columns: new[] { "tenant_id", "status", "current_period_end" }); migrationBuilder.CreateIndex( name: "ix_tenant_secrets_tenant_id_purpose_provider_secret_key", table: "tenant_secrets", columns: new[] { "tenant_id", "purpose", "provider", "secret_key" }, unique: true); migrationBuilder.CreateIndex( name: "ix_tenant_secrets_tenant_id_purpose_provider_status", table: "tenant_secrets", columns: new[] { "tenant_id", "purpose", "provider", "status" }); migrationBuilder.CreateIndex( name: "ix_tenant_secrets_tenant_id_secret_ref", table: "tenant_secrets", columns: new[] { "tenant_id", "secret_ref" }, unique: true); 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_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_tenants_legacy_id", table: "tenants", column: "legacy_id", unique: true); migrationBuilder.CreateIndex( name: "ix_tenants_mode", table: "tenants", column: "mode", unique: true, filter: "mode = 'platform_owned'"); 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_claims_user_id", table: "user_claims", 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_logins_user_id", table: "user_logins", 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: "email_index", table: "users", column: "normalized_email"); 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: "user_name_index", table: "users", column: "normalized_user_name", 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_video_playback_progress_tenant_id_question_id", table: "video_playback_progress", columns: new[] { "tenant_id", "question_id" }); migrationBuilder.CreateIndex( name: "ix_video_playback_progress_tenant_id_user_id_last_played_at", table: "video_playback_progress", columns: new[] { "tenant_id", "user_id", "last_played_at" }); migrationBuilder.CreateIndex( name: "ix_video_playback_progress_tenant_id_user_id_video_id", table: "video_playback_progress", columns: new[] { "tenant_id", "user_id", "video_id" }, unique: true, filter: "question_id is null"); migrationBuilder.CreateIndex( name: "ix_video_playback_progress_tenant_id_user_id_video_id_question~", table: "video_playback_progress", columns: new[] { "tenant_id", "user_id", "video_id", "question_id" }, unique: true, filter: "question_id is not null"); migrationBuilder.CreateIndex( name: "ix_video_playback_progress_tenant_id_video_id", table: "video_playback_progress", columns: new[] { "tenant_id", "video_id" }); migrationBuilder.CreateIndex( name: "ix_video_playback_progress_user_id", table: "video_playback_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" }); migrationBuilder.CreateIndex( name: "ix_wrong_questions_question_owner_tenant_id_question_id", table: "wrong_questions", columns: new[] { "question_owner_tenant_id", "question_id" }); migrationBuilder.CreateIndex( name: "ix_wrong_questions_tenant_id_question_reference_id", table: "wrong_questions", columns: new[] { "tenant_id", "question_reference_id" }); migrationBuilder.CreateIndex( name: "ix_wrong_questions_user_id", table: "wrong_questions", column: "user_id"); migrationBuilder.AddForeignKey( name: "fk_answer_records_practice_session_questions_tenant_id_practic~", table: "answer_records", columns: new[] { "tenant_id", "practice_session_id", "session_question_id" }, principalTable: "practice_session_questions", principalColumns: new[] { "tenant_id", "practice_session_id", "id" }, onDelete: ReferentialAction.Restrict); migrationBuilder.AddForeignKey( name: "fk_favorite_questions_questions_question_owner_tenant_id_quest~", table: "favorite_questions", columns: new[] { "question_owner_tenant_id", "question_id" }, principalTable: "questions", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); migrationBuilder.AddForeignKey( name: "fk_favorite_questions_tenant_question_references_tenant_id_que~", table: "favorite_questions", columns: new[] { "tenant_id", "question_reference_id" }, principalTable: "tenant_question_references", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); migrationBuilder.AddForeignKey( name: "fk_practice_session_questions_question_versions_question_owner~", table: "practice_session_questions", columns: new[] { "question_owner_tenant_id", "question_id", "question_version_id" }, principalTable: "question_versions", principalColumns: new[] { "tenant_id", "question_id", "id" }, onDelete: ReferentialAction.Restrict); migrationBuilder.AddForeignKey( name: "fk_practice_session_questions_tenant_question_references_tenan~", table: "practice_session_questions", columns: new[] { "tenant_id", "question_owner_tenant_id", "question_id" }, principalTable: "tenant_question_references", principalColumns: new[] { "tenant_id", "question_owner_tenant_id", "question_id" }, onDelete: ReferentialAction.Restrict); migrationBuilder.AddForeignKey( name: "fk_question_collection_items_questions_question_owner_tenant_i~", table: "question_collection_items", columns: new[] { "question_owner_tenant_id", "question_id" }, principalTable: "questions", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Restrict); migrationBuilder.AddForeignKey( name: "fk_question_collection_items_tenant_question_references_tenant~", table: "question_collection_items", columns: new[] { "tenant_id", "question_reference_id" }, principalTable: "tenant_question_references", principalColumns: new[] { "tenant_id", "id" }, onDelete: ReferentialAction.Cascade); migrationBuilder.AddForeignKey( name: "fk_question_taxonomy_assignments_questions_tenant_id_question_~", table: "question_taxonomy_assignments", 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); migrationBuilder.EnsureTenantIsolationGuards(); migrationBuilder.EnsureSaasCatalogGuards(); } /// protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropSaasCatalogGuards(); migrationBuilder.DropTenantIsolationGuards(); 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_categories_module_nodes_tenant_id_node_id", table: "categories"); migrationBuilder.DropForeignKey( name: "fk_questions_module_nodes_tenant_id_node_id", table: "questions"); migrationBuilder.DropForeignKey( name: "fk_subjects_module_nodes_tenant_id_node_id", table: "subjects"); migrationBuilder.DropForeignKey( name: "fk_categories_subjects_tenant_id_subject_id", table: "categories"); migrationBuilder.DropForeignKey( name: "fk_question_collections_subjects_tenant_id_subject_id", table: "question_collections"); migrationBuilder.DropForeignKey( name: "fk_questions_subjects_tenant_id_subject_id", table: "questions"); migrationBuilder.DropForeignKey( name: "fk_question_collections_categories_tenant_id_category_id", table: "question_collections"); migrationBuilder.DropForeignKey( name: "fk_questions_categories_tenant_id_category_id", table: "questions"); migrationBuilder.DropForeignKey( name: "fk_question_collections_content_nodes_tenant_id_node_id", table: "question_collections"); migrationBuilder.DropForeignKey( name: "fk_questions_content_nodes_tenant_id_content_node_id", table: "questions"); migrationBuilder.DropForeignKey( name: "fk_question_collections_question_banks_tenant_id_question_bank~", table: "question_collections"); migrationBuilder.DropForeignKey( name: "fk_questions_question_banks_tenant_id_question_bank_id", table: "questions"); migrationBuilder.DropForeignKey( name: "fk_question_collections_content_entries_tenant_id_entry_id", table: "question_collections"); migrationBuilder.DropForeignKey( name: "fk_questions_content_entries_tenant_id_entry_id", table: "questions"); migrationBuilder.DropForeignKey( name: "fk_question_versions_questions_tenant_id_question_id", table: "question_versions"); 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_challenges"); migrationBuilder.DropTable( name: "auth_login_events"); migrationBuilder.DropTable( name: "auth_sessions"); migrationBuilder.DropTable( name: "background_jobs"); migrationBuilder.DropTable( name: "banners"); migrationBuilder.DropTable( name: "commerce_adjustment_voucher_events"); migrationBuilder.DropTable( name: "commerce_reconciliation_issue_events"); migrationBuilder.DropTable( name: "commerce_refund_events"); migrationBuilder.DropTable( name: "commission_settlement_export_events"); migrationBuilder.DropTable( name: "commission_settlement_items"); migrationBuilder.DropTable( name: "commission_settlement_proofs"); 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: "data_protection_keys"); 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: "outbox_message"); 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_backend_role_menus"); migrationBuilder.DropTable( name: "platform_backend_role_permissions"); migrationBuilder.DropTable( name: "platform_backend_user_roles"); migrationBuilder.DropTable( name: "platform_billing_dunning_notification_events"); migrationBuilder.DropTable( name: "platform_billing_payment_events"); migrationBuilder.DropTable( name: "platform_billing_quote_items"); migrationBuilder.DropTable( name: "platform_billing_refunds"); migrationBuilder.DropTable( name: "point_activity_claims"); migrationBuilder.DropTable( name: "point_exchange_orders"); 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_taxonomy_assignments"); 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: "saas_offering_version_features"); migrationBuilder.DropTable( name: "saas_offering_version_limits"); migrationBuilder.DropTable( name: "scoreline_fields"); migrationBuilder.DropTable( name: "scoreline_records"); 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_policies"); migrationBuilder.DropTable( name: "tenant_backend_role_menus"); migrationBuilder.DropTable( name: "tenant_backend_role_permissions"); migrationBuilder.DropTable( name: "tenant_backend_user_roles"); migrationBuilder.DropTable( name: "tenant_billing_profiles"); 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_external_providers"); migrationBuilder.DropTable( name: "tenant_feature_overrides"); migrationBuilder.DropTable( name: "tenant_feature_usage"); migrationBuilder.DropTable( name: "tenant_frontend_configs"); migrationBuilder.DropTable( name: "tenant_memberships"); migrationBuilder.DropTable( name: "tenant_question_bank_preferences"); migrationBuilder.DropTable( name: "tenant_saas_subscription_items"); migrationBuilder.DropTable( name: "tenant_secrets"); migrationBuilder.DropTable( name: "tenant_settings"); migrationBuilder.DropTable( name: "tenant_student_followups"); migrationBuilder.DropTable( name: "tenant_student_notes"); migrationBuilder.DropTable( name: "tenant_theme_configs"); migrationBuilder.DropTable( name: "user_badges"); migrationBuilder.DropTable( name: "user_claims"); migrationBuilder.DropTable( name: "user_identities"); migrationBuilder.DropTable( name: "user_logins"); migrationBuilder.DropTable( name: "user_notifications"); migrationBuilder.DropTable( name: "user_score_events"); migrationBuilder.DropTable( name: "user_tokens"); migrationBuilder.DropTable( name: "user_word_favorites"); migrationBuilder.DropTable( name: "user_word_progress"); migrationBuilder.DropTable( name: "video_playback_progress"); migrationBuilder.DropTable( name: "wrong_questions"); migrationBuilder.DropTable( name: "code_batches"); migrationBuilder.DropTable( name: "coupon_redemptions"); migrationBuilder.DropTable( name: "practice_session_questions"); migrationBuilder.DropTable( name: "commerce_adjustment_vouchers"); migrationBuilder.DropTable( name: "commission_settlements"); migrationBuilder.DropTable( name: "content_assets"); migrationBuilder.DropTable( name: "content_import_items"); migrationBuilder.DropTable( name: "handbook_chapters"); migrationBuilder.DropTable( name: "inbox_state"); migrationBuilder.DropTable( name: "outbox_state"); migrationBuilder.DropTable( name: "pb_import_runs"); migrationBuilder.DropTable( name: "audit_logs"); migrationBuilder.DropTable( name: "platform_audit_alert_rules"); migrationBuilder.DropTable( name: "platform_backend_roles"); migrationBuilder.DropTable( name: "platform_billing_dunning_notification_channels"); migrationBuilder.DropTable( name: "platform_billing_invoice_reminders"); migrationBuilder.DropTable( name: "platform_billing_payments"); migrationBuilder.DropTable( name: "point_activity_tasks"); migrationBuilder.DropTable( name: "point_exchange_items"); migrationBuilder.DropTable( name: "practice_session_reports"); migrationBuilder.DropTable( name: "taxonomy_nodes"); migrationBuilder.DropTable( name: "reports"); migrationBuilder.DropTable( name: "backend_menus"); migrationBuilder.DropTable( name: "tenant_backend_roles"); migrationBuilder.DropTable( name: "saas_feature_limit_definitions"); migrationBuilder.DropTable( name: "platform_billing_order_items"); migrationBuilder.DropTable( name: "tenant_saas_subscriptions"); migrationBuilder.DropTable( name: "tenant_classes"); migrationBuilder.DropTable( name: "tenant_theme_templates"); migrationBuilder.DropTable( name: "badges"); migrationBuilder.DropTable( name: "vocabulary_words"); migrationBuilder.DropTable( name: "video_explanations"); migrationBuilder.DropTable( name: "coupons"); migrationBuilder.DropTable( name: "tenant_question_references"); migrationBuilder.DropTable( name: "commerce_reconciliation_issues"); migrationBuilder.DropTable( name: "content_import_jobs"); migrationBuilder.DropTable( name: "handbook_subjects"); migrationBuilder.DropTable( name: "platform_billing_invoices"); migrationBuilder.DropTable( name: "practice_sessions"); migrationBuilder.DropTable( name: "backend_permissions"); migrationBuilder.DropTable( name: "saas_offering_versions"); migrationBuilder.DropTable( name: "vocabulary_units"); migrationBuilder.DropTable( name: "commerce_reconciliation_items"); migrationBuilder.DropTable( name: "platform_billing_orders"); migrationBuilder.DropTable( name: "practice_blueprints"); migrationBuilder.DropTable( name: "permission_modules"); migrationBuilder.DropTable( name: "saas_offerings"); migrationBuilder.DropTable( name: "commerce_reconciliation_batches"); migrationBuilder.DropTable( name: "commerce_refund_requests"); migrationBuilder.DropTable( name: "platform_billing_quotes"); migrationBuilder.DropTable( name: "saas_features"); 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: "module_nodes"); migrationBuilder.DropTable( name: "subjects"); migrationBuilder.DropTable( name: "majors"); migrationBuilder.DropTable( name: "schools"); migrationBuilder.DropTable( name: "region_modules"); migrationBuilder.DropTable( name: "categories"); migrationBuilder.DropTable( name: "content_nodes"); migrationBuilder.DropTable( name: "question_banks"); migrationBuilder.DropTable( name: "content_entries"); migrationBuilder.DropTable( name: "questions"); migrationBuilder.DropTable( name: "question_collections"); migrationBuilder.DropTable( name: "question_versions"); migrationBuilder.DropTable( name: "referral_tracks"); migrationBuilder.DropTable( name: "referral_leads"); } } }