forked from xiongyuxing/tiku-backend.net
9778 lines
578 KiB
C#
9778 lines
578 KiB
C#
using System;
|
|
using System.Text.Json;
|
|
using Microsoft.EntityFrameworkCore.Migrations;
|
|
using Tiku.Infrastructure.Persistence;
|
|
|
|
#nullable disable
|
|
|
|
namespace Tiku.Infrastructure.Persistence.Migrations
|
|
{
|
|
/// <inheritdoc />
|
|
public partial class InitialSchema : Migration
|
|
{
|
|
/// <inheritdoc />
|
|
protected override void Up(MigrationBuilder migrationBuilder)
|
|
{
|
|
migrationBuilder.AlterDatabase()
|
|
.Annotation("Npgsql:PostgresExtension:citext", ",,")
|
|
.Annotation("Npgsql:PostgresExtension:ltree", ",,");
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "backend_permissions",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: false),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
area = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
module = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
description = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
is_system = table.Column<bool>(type: "boolean", nullable: false),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_backend_permissions", x => x.id);
|
|
table.UniqueConstraint("ak_backend_permissions_code", x => x.code);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "platform_backend_roles",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
is_system = table.Column<bool>(type: "boolean", nullable: false),
|
|
description = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_platform_backend_roles", x => x.id);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "platform_dunning_notification_channels",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
channel_code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
enabled = table.Column<bool>(type: "boolean", nullable: false),
|
|
provider = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
webhook_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: false),
|
|
secret_ref = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
reminder_types = table.Column<string[]>(type: "text[]", nullable: false, defaultValueSql: "array['overdue', 'final_notice']::text[]"),
|
|
reminder_channels = table.Column<string[]>(type: "text[]", nullable: false, defaultValueSql: "array['internal']::text[]"),
|
|
min_reminder_level = table.Column<int>(type: "integer", nullable: false),
|
|
tenant_ids = table.Column<Guid[]>(type: "uuid[]", nullable: false, defaultValueSql: "'{}'::uuid[]"),
|
|
timeout_seconds = table.Column<int>(type: "integer", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_platform_dunning_notification_channels", x => x.id);
|
|
table.CheckConstraint("ck_platform_dunning_channels_level", "min_reminder_level between 1 and 20");
|
|
table.CheckConstraint("ck_platform_dunning_channels_timeout", "timeout_seconds between 1 and 60");
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "platform_saas_plans",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
billing_cycle = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
base_amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
currency = table.Column<string>(type: "character varying(10)", maxLength: 10, nullable: false),
|
|
included_quotas = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
overage_prices = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
feature_flags = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_platform_saas_plans", x => x.id);
|
|
table.CheckConstraint("ck_platform_saas_plans_amount", "base_amount_cents >= 0");
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenant_theme_templates",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
preview_image_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
theme = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
public_assets = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
username = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
email = table.Column<string>(type: "citext", maxLength: 320, nullable: true),
|
|
phone = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
avatar_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
primary_role = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
score = table.Column<int>(type: "integer", nullable: false),
|
|
last_seen_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
legacy_password_hash = table.Column<string>(type: "character varying(512)", maxLength: 512, nullable: true),
|
|
password_migration_required = table.Column<bool>(type: "boolean", nullable: false),
|
|
raw_profile = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_users", x => x.id);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "backend_menus",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: false),
|
|
parent_code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: true),
|
|
title = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
area = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
path = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
|
icon = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
permission_code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_backend_menus", x => x.id);
|
|
table.UniqueConstraint("ak_backend_menus_code", x => x.code);
|
|
table.ForeignKey(
|
|
name: "fk_backend_menus_backend_permissions_permission_code",
|
|
column: x => x.permission_code,
|
|
principalTable: "backend_permissions",
|
|
principalColumn: "code",
|
|
onDelete: ReferentialAction.SetNull);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "platform_backend_role_permissions",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
role_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
permission_code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_platform_backend_role_permissions", x => x.id);
|
|
table.ForeignKey(
|
|
name: "fk_platform_backend_role_permissions_backend_permissions_permi~",
|
|
column: x => x.permission_code,
|
|
principalTable: "backend_permissions",
|
|
principalColumn: "code",
|
|
onDelete: ReferentialAction.Restrict);
|
|
table.ForeignKey(
|
|
name: "fk_platform_backend_role_permissions_platform_backend_roles_ro~",
|
|
column: x => x.role_id,
|
|
principalTable: "platform_backend_roles",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "platform_backend_user_roles",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
role_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_platform_backend_user_roles", x => x.id);
|
|
table.ForeignKey(
|
|
name: "fk_platform_backend_user_roles_platform_backend_roles_role_id",
|
|
column: x => x.role_id,
|
|
principalTable: "platform_backend_roles",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_platform_backend_user_roles_users_user_id",
|
|
column: x => x.user_id,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenants",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
slug = table.Column<string>(type: "citext", maxLength: 100, nullable: false),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
legal_name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
mode = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
billing_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
owner_user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenants", x => x.id);
|
|
table.ForeignKey(
|
|
name: "fk_tenants_users_owner_user_id",
|
|
column: x => x.owner_user_id,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "user_identities",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
provider_subject = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false),
|
|
union_id = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true),
|
|
open_id = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true),
|
|
phone = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
email = table.Column<string>(type: "citext", maxLength: 320, nullable: true),
|
|
secret_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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: "platform_backend_role_menus",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
role_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
menu_code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_platform_backend_role_menus", x => x.id);
|
|
table.ForeignKey(
|
|
name: "fk_platform_backend_role_menus_backend_menus_menu_code",
|
|
column: x => x.menu_code,
|
|
principalTable: "backend_menus",
|
|
principalColumn: "code",
|
|
onDelete: ReferentialAction.Restrict);
|
|
table.ForeignKey(
|
|
name: "fk_platform_backend_role_menus_platform_backend_roles_role_id",
|
|
column: x => x.role_id,
|
|
principalTable: "platform_backend_roles",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "announcements",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
content = table.Column<string>(type: "text", nullable: true),
|
|
link = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
background_color = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
asset_key = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
file_name = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
|
|
description = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
actor_user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
action = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
target_type = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
target_id = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
details = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
ip_address = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
user_agent = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_audit_logs", x => x.id);
|
|
table.ForeignKey(
|
|
name: "fk_audit_logs_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_audit_logs_users_actor_user_id",
|
|
column: x => x.actor_user_id,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "auth_login_events",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
identifier = table.Column<string>(type: "character varying(320)", maxLength: 320, nullable: true),
|
|
result = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
failure_code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
ip_address = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
user_agent = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_auth_login_events", x => x.id);
|
|
table.UniqueConstraint("ak_auth_login_events_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_auth_login_events_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_auth_login_events_users_user_id",
|
|
column: x => x.user_id,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "auth_sessions",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
token_hash = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
|
provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
expires_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
|
|
revoked_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
ip_address = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
user_agent = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_auth_sessions", x => x.id);
|
|
table.UniqueConstraint("ak_auth_sessions_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_auth_sessions_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_auth_sessions_users_user_id",
|
|
column: x => x.user_id,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "badges",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
category = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
icon_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
level = table.Column<int>(type: "integer", nullable: true),
|
|
unlock_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
condition_field = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
condition_operator = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
condition_value = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: true),
|
|
condition_extra = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
sale_type = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
channel = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
campaign_name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
default_unit_price_cents = table.Column<int>(type: "integer", nullable: false),
|
|
cost_price_cents = table.Column<int>(type: "integer", nullable: false),
|
|
total_count = table.Column<int>(type: "integer", nullable: false),
|
|
days = table.Column<int>(type: "integer", nullable: true),
|
|
legacy_region_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
issued_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
remark = table.Column<string>(type: "text", nullable: true),
|
|
commission_rate = table.Column<decimal>(type: "numeric(6,4)", precision: 6, scale: 4, nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
bill_date = table.Column<DateOnly>(type: "date", nullable: false),
|
|
bill_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
source = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
source_name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
source_hash = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
total_count = table.Column<int>(type: "integer", nullable: false),
|
|
matched_count = table.Column<int>(type: "integer", nullable: false),
|
|
mismatch_count = table.Column<int>(type: "integer", nullable: false),
|
|
missing_local_count = table.Column<int>(type: "integer", nullable: false),
|
|
missing_provider_count = table.Column<int>(type: "integer", nullable: false),
|
|
duplicate_count = table.Column<int>(type: "integer", nullable: false),
|
|
ignored_count = table.Column<int>(type: "integer", nullable: false),
|
|
amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
refund_amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
fee_cents = table.Column<int>(type: "integer", nullable: false),
|
|
completed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
error = table.Column<string>(type: "text", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
referrer_user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
generated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
reviewed_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
paid_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
settlement_no = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
period_start = table.Column<DateOnly>(type: "date", nullable: false),
|
|
period_end = table.Column<DateOnly>(type: "date", nullable: false),
|
|
source_count = table.Column<int>(type: "integer", nullable: false),
|
|
paid_user_count = table.Column<int>(type: "integer", nullable: false),
|
|
gross_amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
commission_amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
default_rate = table.Column<decimal>(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false),
|
|
effective_rate = table.Column<decimal>(type: "numeric(6,4)", precision: 6, scale: 4, nullable: true),
|
|
reviewed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
paid_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
payment_method = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
payment_account = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
remark = table.Column<string>(type: "text", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
enabled = table.Column<bool>(type: "boolean", nullable: false),
|
|
url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
secret_ref = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
form_name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
exam_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
timeout_seconds = table.Column<int>(type: "integer", nullable: true),
|
|
delay_seconds = table.Column<int>(type: "integer", nullable: true),
|
|
assignment_mode = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
assignment_pool = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
assignment_cursor = table.Column<int>(type: "integer", nullable: false),
|
|
assignment_config = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
record_id = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
lead_id = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
http_code = table.Column<int>(type: "integer", nullable: true),
|
|
outcome = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
error_message = table.Column<string>(type: "text", nullable: true),
|
|
request_body = table.Column<string>(type: "text", nullable: true),
|
|
request_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
response_summary = table.Column<string>(type: "character varying(2000)", maxLength: 2000, nullable: true),
|
|
signed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
attempt = table.Column<int>(type: "integer", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
record_id = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
lead_id = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
source = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
provider = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
scheduled_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
attempts = table.Column<int>(type: "integer", nullable: false),
|
|
next_attempt_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
last_attempt_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
last_error = table.Column<string>(type: "text", nullable: true),
|
|
last_http_code = table.Column<int>(type: "integer", nullable: true),
|
|
last_response_summary = table.Column<string>(type: "text", nullable: true),
|
|
sent_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
idempotency_key = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
target_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
entitlement_type = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
scope_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
scope_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
source_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
source_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_source_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
starts_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
expires_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
revoked_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
revoked_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
revoked_reason = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
title = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
category = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
file_name = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
|
|
is_public = table.Column<bool>(type: "boolean", nullable: false),
|
|
cdn_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
source_name = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: false),
|
|
source_kind = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
stats = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
started_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
finished_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
enabled = table.Column<bool>(type: "boolean", nullable: false),
|
|
severity = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
action_patterns = table.Column<string[]>(type: "text[]", nullable: false, defaultValueSql: "'{}'::text[]"),
|
|
target_types = table.Column<string[]>(type: "text[]", nullable: false, defaultValueSql: "'{}'::text[]"),
|
|
conditions = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_platform_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: "point_activity_tasks",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
task_key = table.Column<string>(type: "citext", maxLength: 100, nullable: false),
|
|
title = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
description = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
task_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
points = table.Column<int>(type: "integer", nullable: false),
|
|
max_claims_per_user = table.Column<int>(type: "integer", nullable: false),
|
|
starts_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
ends_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
rules = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
usage_date = table.Column<DateOnly>(type: "date", nullable: false, defaultValueSql: "current_date"),
|
|
scope_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
scope_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
free_limit = table.Column<int>(type: "integer", nullable: false),
|
|
used_count = table.Column<int>(type: "integer", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
practice_type = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
target_legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
target_name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
progress = table.Column<int>(type: "integer", nullable: false),
|
|
color = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
last_access_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
last_practice_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
code = table.Column<string>(type: "citext", maxLength: 100, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
channel = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
landing_path = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
ref_code = table.Column<string>(type: "citext", maxLength: 100, nullable: false),
|
|
scene = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
page = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
provider = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
qrcode_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
error_message = table.Column<string>(type: "text", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
member_user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
leader_user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
relation_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
code = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
short_name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
full_name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
icon = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
pinyin = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_hot = table.Column<bool>(type: "boolean", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
config = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false),
|
|
dimension = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
scope_hash = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: false),
|
|
bucket_start = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
|
|
request_count = table.Column<int>(type: "integer", nullable: false, defaultValue: 0),
|
|
updated_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
phone = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
purpose = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
code_hash = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
|
|
provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
attempts = table.Column<int>(type: "integer", nullable: false),
|
|
expires_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
|
|
consumed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
ip_address = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
user_agent = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_sms_verification_codes", x => x.id);
|
|
table.UniqueConstraint("ak_sms_verification_codes_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.CheckConstraint("ck_sms_verification_codes_attempts", "attempts >= 0");
|
|
table.ForeignKey(
|
|
name: "fk_sms_verification_codes_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "taxonomy_nodes",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
parent_owner_tenant_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
parent_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
node_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
path = table.Column<string>(type: "ltree", nullable: true),
|
|
depth = table.Column<int>(type: "integer", nullable: false),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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_backend_roles",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
is_system = table.Column<bool>(type: "boolean", nullable: false),
|
|
description = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
data_scope = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_backend_roles", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_backend_roles_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_tenant_backend_roles_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenant_billing_profiles",
|
|
columns: table => new
|
|
{
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
billing_name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
tax_id = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
contact_name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
contact_phone = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
contact_email = table.Column<string>(type: "citext", maxLength: 300, nullable: true),
|
|
billing_address = table.Column<string>(type: "text", nullable: true),
|
|
invoice_title = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
invoice_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
bank_name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
bank_account_masked = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_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<Guid>(type: "uuid", nullable: false),
|
|
brand_name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
short_name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
slogan = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
organization_name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
logo_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
favicon_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
service_wechat = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
service_account_name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
theme = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
public_assets = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
default_rate = table.Column<decimal>(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false),
|
|
min_settlement_cents = table.Column<int>(type: "integer", nullable: false),
|
|
settlement_cycle = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
config = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
updated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
host = table.Column<string>(type: "citext", maxLength: 253, nullable: false),
|
|
domain_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
is_primary = table.Column<bool>(type: "boolean", nullable: false),
|
|
verification_token = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
|
verified_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
last_checked_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
dns_verified_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
tls_ready_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
last_failure_reason = table.Column<string>(type: "character varying(2000)", maxLength: 2000, nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
capability = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
display_name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
secret_ref = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
priority = table.Column<int>(type: "integer", nullable: false),
|
|
config_public = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_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_frontend_configs",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
schema_version = table.Column<int>(type: "integer", nullable: false),
|
|
config_version = table.Column<int>(type: "integer", nullable: false),
|
|
published_branding = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
published_theme = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
published_features = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
published_navigation = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
published_home_modules = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
draft_branding = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
draft_theme = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
draft_features = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
draft_navigation = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
draft_home_modules = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
published_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_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_invoices",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
invoice_no = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
invoice_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
currency = table.Column<string>(type: "character varying(10)", maxLength: 10, nullable: false),
|
|
subtotal_cents = table.Column<int>(type: "integer", nullable: false),
|
|
discount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
tax_cents = table.Column<int>(type: "integer", nullable: false),
|
|
total_cents = table.Column<int>(type: "integer", nullable: false),
|
|
paid_cents = table.Column<int>(type: "integer", nullable: false),
|
|
balance_cents = table.Column<int>(type: "integer", nullable: false),
|
|
billing_period_start = table.Column<DateOnly>(type: "date", nullable: true),
|
|
billing_period_end = table.Column<DateOnly>(type: "date", nullable: true),
|
|
due_date = table.Column<DateOnly>(type: "date", nullable: true),
|
|
issued_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
paid_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
note = table.Column<string>(type: "text", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_invoices", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_invoices_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.CheckConstraint("ck_tenant_invoices_amounts", "subtotal_cents >= 0 and discount_cents >= 0 and tax_cents >= 0 and total_cents >= 0 and paid_cents >= 0 and balance_cents >= 0");
|
|
table.CheckConstraint("ck_tenant_invoices_period", "billing_period_end is null or billing_period_start is null or billing_period_end >= billing_period_start");
|
|
table.ForeignKey(
|
|
name: "fk_tenant_invoices_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_invoices_users_created_by",
|
|
column: x => x.created_by,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenant_role_templates",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
base_role = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
permissions = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
menu_permissions = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
module_permissions = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
field_permissions = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
data_scope = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
is_system = table.Column<bool>(type: "boolean", nullable: false),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
updated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_role_templates", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_role_templates_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_tenant_role_templates_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_role_templates_users_created_by",
|
|
column: x => x.created_by,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_role_templates_users_updated_by",
|
|
column: x => x.updated_by,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenant_secrets",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
purpose = table.Column<string>(type: "character varying(80)", maxLength: 80, nullable: false),
|
|
provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
secret_key = table.Column<string>(type: "character varying(120)", maxLength: 120, nullable: false),
|
|
secret_ref = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
encryption_key_id = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
encrypted_payload = table.Column<byte[]>(type: "bytea", nullable: false),
|
|
encryption_nonce = table.Column<byte[]>(type: "bytea", nullable: false),
|
|
encryption_tag = table.Column<byte[]>(type: "bytea", nullable: false),
|
|
rotated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
expires_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_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<Guid>(type: "uuid", nullable: false),
|
|
feature_flags = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
admin_feature_flags = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
public_config = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
student_user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
note_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
content = table.Column<string>(type: "text", nullable: false),
|
|
visibility = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
is_pinned = table.Column<bool>(type: "boolean", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
updated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_student_notes", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_student_notes_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_tenant_student_notes_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_student_notes_users_created_by",
|
|
column: x => x.created_by,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_student_notes_users_student_user_id",
|
|
column: x => x.student_user_id,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_student_notes_users_updated_by",
|
|
column: x => x.updated_by,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenant_subscriptions",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
plan_code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
starts_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
expires_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
billing_cycle = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_subscriptions", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_subscriptions_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_tenant_subscriptions_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenant_theme_configs",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
active_template_code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
active_theme = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
active_public_assets = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
draft_template_code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
draft_theme = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
draft_public_assets = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
published_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
published_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
draft_updated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_theme_configs", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_theme_configs_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_tenant_theme_configs_tenant_theme_templates_active_template~",
|
|
column: x => x.active_template_code,
|
|
principalTable: "tenant_theme_templates",
|
|
principalColumn: "code",
|
|
onDelete: ReferentialAction.SetNull);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_theme_configs_tenant_theme_templates_draft_template_~",
|
|
column: x => x.draft_template_code,
|
|
principalTable: "tenant_theme_templates",
|
|
principalColumn: "code",
|
|
onDelete: ReferentialAction.SetNull);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_theme_configs_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_theme_configs_users_draft_updated_by",
|
|
column: x => x.draft_updated_by,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_theme_configs_users_published_by",
|
|
column: x => x.published_by,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenant_usage_records",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
metric_key = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
metric_value = table.Column<decimal>(type: "numeric(18,4)", precision: 18, scale: 4, nullable: false),
|
|
period_start = table.Column<DateOnly>(type: "date", nullable: false),
|
|
period_end = table.Column<DateOnly>(type: "date", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_usage_records", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_usage_records_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_tenant_usage_records_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "user_notifications",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
source_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
notification_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
severity = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
title = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
message = table.Column<string>(type: "text", nullable: false),
|
|
action_label = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
action_path = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
source_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
dedupe_key = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
read_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
event_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
points = table.Column<int>(type: "integer", nullable: false),
|
|
balance_after = table.Column<int>(type: "integer", nullable: false),
|
|
source_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
source_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
idempotency_key = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_user_score_events", x => x.id);
|
|
table.UniqueConstraint("ak_user_score_events_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_user_score_events_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_user_score_events_users_user_id",
|
|
column: x => x.user_id,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "user_badges",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
badge_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
granted_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
note = table.Column<string>(type: "text", nullable: true),
|
|
granted_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
settlement_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
exported_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
export_format = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
|
|
filename = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: false),
|
|
row_count = table.Column<int>(type: "integer", nullable: false),
|
|
content_sha256 = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
settlement_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
referrer_user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
student_user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
source_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
source_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
source_no = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
source_paid_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
gross_amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
commission_rate = table.Column<decimal>(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false),
|
|
commission_amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
rate_source = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
attribution_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
run_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
collection_name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
legacy_id = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
severity = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
issue_code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
message = table.Column<string>(type: "text", nullable: false),
|
|
field_path = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
|
|
raw_value_sample = table.Column<string>(type: "character varying(2000)", maxLength: 2000, nullable: true),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false),
|
|
collection_name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
legacy_id = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
record = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
normalized = table.Column<bool>(type: "boolean", nullable: false),
|
|
errors = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
imported_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
rule_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
audit_log_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
acknowledged_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
resolved_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
severity = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
action = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
target_type = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
target_id = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
title = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
summary = table.Column<string>(type: "text", nullable: true),
|
|
details = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
first_seen_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
last_seen_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
acknowledged_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
resolved_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
resolution_note = table.Column<string>(type: "text", nullable: true),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_platform_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: "point_activity_claims",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
task_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
task_key = table.Column<string>(type: "citext", maxLength: 100, nullable: false),
|
|
points = table.Column<int>(type: "integer", nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
source_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
source_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
claimed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
provider = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
model = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
prompt_version = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
input_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
context_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
result_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
error_message = table.Column<string>(type: "text", nullable: true),
|
|
generated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
title = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
subtitle = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
|
|
content = table.Column<string>(type: "text", nullable: true),
|
|
button_text = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
button_link = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
background_color = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
border_color = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
entry_key = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
entry_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
icon = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
route = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
|
|
description = table.Column<string>(type: "character varying(2000)", maxLength: 2000, nullable: true),
|
|
visibility = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
access_rules = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
layout_config = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
updated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_region_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
stat_date = table.Column<DateOnly>(type: "date", nullable: false),
|
|
new_users = table.Column<int>(type: "integer", nullable: false),
|
|
new_questions = table.Column<int>(type: "integer", nullable: false),
|
|
new_orders = table.Column<int>(type: "integer", nullable: false),
|
|
new_revenue_cents = table.Column<int>(type: "integer", nullable: false),
|
|
active_users = table.Column<int>(type: "integer", nullable: false),
|
|
rebuilt_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
question = table.Column<string>(type: "text", nullable: true),
|
|
answer = table.Column<string>(type: "text", nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
item_key = table.Column<string>(type: "citext", maxLength: 100, nullable: false),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
description = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
item_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
points_cost = table.Column<int>(type: "integer", nullable: false),
|
|
stock = table.Column<int>(type: "integer", nullable: true),
|
|
days = table.Column<int>(type: "integer", nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
starts_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
ends_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
fulfillment_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
title = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
legacy_price_text = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
link = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
tags = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
cover = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
preview_iframe = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
detail_images = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false, defaultValue: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
type = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
icon = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
color = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
text_color = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
route = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_primary_school_module = table.Column<bool>(type: "boolean", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_region_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
stat_date = table.Column<DateOnly>(type: "date", nullable: false),
|
|
sale_type = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
real_revenue_cents = table.Column<int>(type: "integer", nullable: false),
|
|
order_count = table.Column<int>(type: "integer", nullable: false),
|
|
code_count = table.Column<int>(type: "integer", nullable: false),
|
|
code_used = table.Column<int>(type: "integer", nullable: false),
|
|
code_estimated = table.Column<int>(type: "integer", nullable: false),
|
|
estimated_revenue_cents = table.Column<int>(type: "integer", nullable: false),
|
|
rebuilt_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
field_key = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
|
|
field_name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
field_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
unit = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
is_filter = table.Column<bool>(type: "boolean", nullable: false),
|
|
is_required = table.Column<bool>(type: "boolean", nullable: false),
|
|
is_visible = table.Column<bool>(type: "boolean", nullable: false),
|
|
is_trend = table.Column<bool>(type: "boolean", nullable: false),
|
|
options = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
placeholder = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
description = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
price_cents = table.Column<int>(type: "integer", nullable: false),
|
|
original_price_cents = table.Column<int>(type: "integer", nullable: true),
|
|
days = table.Column<int>(type: "integer", nullable: false),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
per_day_label = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
badge = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
recommended = table.Column<bool>(type: "boolean", nullable: false),
|
|
coupon_only = table.Column<bool>(type: "boolean", nullable: false),
|
|
vp_product_id = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
vp_enabled = table.Column<bool>(type: "boolean", nullable: false),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
updated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_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_menus",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
role_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
menu_code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_backend_role_menus", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_backend_role_menus_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_tenant_backend_role_menus_backend_menus_menu_code",
|
|
column: x => x.menu_code,
|
|
principalTable: "backend_menus",
|
|
principalColumn: "code",
|
|
onDelete: ReferentialAction.Restrict);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_backend_role_menus_tenant_backend_roles_tenant_id_ro~",
|
|
columns: x => new { x.tenant_id, x.role_id },
|
|
principalTable: "tenant_backend_roles",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenant_backend_role_permissions",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
role_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
permission_code = table.Column<string>(type: "character varying(160)", maxLength: 160, nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_backend_role_permissions", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_backend_role_permissions_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_tenant_backend_role_permissions_backend_permissions_permiss~",
|
|
column: x => x.permission_code,
|
|
principalTable: "backend_permissions",
|
|
principalColumn: "code",
|
|
onDelete: ReferentialAction.Restrict);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_backend_role_permissions_tenant_backend_roles_tenant~",
|
|
columns: x => new { x.tenant_id, x.role_id },
|
|
principalTable: "tenant_backend_roles",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenant_backend_user_roles",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
role_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_backend_user_roles", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_backend_user_roles_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_tenant_backend_user_roles_tenant_backend_roles_tenant_id_ro~",
|
|
columns: x => new { x.tenant_id, x.role_id },
|
|
principalTable: "tenant_backend_roles",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_backend_user_roles_users_user_id",
|
|
column: x => x.user_id,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenant_invoice_items",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
invoice_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
item_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
item_ref_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
description = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: false),
|
|
quantity = table.Column<decimal>(type: "numeric(12,2)", precision: 12, scale: 2, nullable: false),
|
|
unit_amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_invoice_items", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_invoice_items_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.CheckConstraint("ck_tenant_invoice_items_amounts", "unit_amount_cents >= 0 and amount_cents >= 0");
|
|
table.CheckConstraint("ck_tenant_invoice_items_quantity", "quantity > 0");
|
|
table.ForeignKey(
|
|
name: "fk_tenant_invoice_items_tenant_invoices_tenant_id_invoice_id",
|
|
columns: x => new { x.tenant_id, x.invoice_id },
|
|
principalTable: "tenant_invoices",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_invoice_items_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenant_invoice_payments",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
invoice_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
received_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
payment_no = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
method = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
paid_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
provider_trade_no = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
raw_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_invoice_payments", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_invoice_payments_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.CheckConstraint("ck_tenant_invoice_payments_amount", "amount_cents >= 0");
|
|
table.ForeignKey(
|
|
name: "fk_tenant_invoice_payments_tenant_invoices_tenant_id_invoice_id",
|
|
columns: x => new { x.tenant_id, x.invoice_id },
|
|
principalTable: "tenant_invoices",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_invoice_payments_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_invoice_payments_users_received_by",
|
|
column: x => x.received_by,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenant_invoice_reminders",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
invoice_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
reminder_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
channel = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
reminder_date = table.Column<DateOnly>(type: "date", nullable: false),
|
|
reminder_level = table.Column<int>(type: "integer", nullable: false),
|
|
due_date = table.Column<DateOnly>(type: "date", nullable: true),
|
|
balance_cents_snapshot = table.Column<int>(type: "integer", nullable: false),
|
|
message = table.Column<string>(type: "text", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
sent_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
acknowledged_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_invoice_reminders", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_invoice_reminders_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.CheckConstraint("ck_tenant_invoice_reminders_balance", "balance_cents_snapshot >= 0");
|
|
table.CheckConstraint("ck_tenant_invoice_reminders_level", "reminder_level between 1 and 20");
|
|
table.ForeignKey(
|
|
name: "fk_tenant_invoice_reminders_tenant_invoices_tenant_id_invoice_~",
|
|
columns: x => new { x.tenant_id, x.invoice_id },
|
|
principalTable: "tenant_invoices",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_invoice_reminders_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_invoice_reminders_users_created_by",
|
|
column: x => x.created_by,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "tenant_memberships",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
role_template_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
role = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
permissions = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
legacy_role = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_memberships", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_memberships_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_tenant_memberships_tenant_role_templates_tenant_id_role_tem~",
|
|
columns: x => new { x.tenant_id, x.role_template_id },
|
|
principalTable: "tenant_role_templates",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Restrict);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_memberships_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_memberships_users_user_id",
|
|
column: x => x.user_id,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "content_nodes",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
entry_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
parent_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
node_key = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
node_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
marker_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
marker_config = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
path = table.Column<string>(type: "ltree", nullable: true),
|
|
depth = table.Column<int>(type: "integer", nullable: false),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
is_selectable = table.Column<bool>(type: "boolean", nullable: false),
|
|
is_leaf = table.Column<bool>(type: "boolean", nullable: false),
|
|
access_rules = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
updated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
item_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
order_no = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
item_name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
item_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
points_cost = table.Column<int>(type: "integer", nullable: false),
|
|
ordered_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
completed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
cancelled_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
fulfillment_snapshot = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
adoption_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
source_question_bank_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
read_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
notification_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
severity = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
title = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
message = table.Column<string>(type: "text", nullable: false),
|
|
action_label = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
action_path = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
dedupe_key = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
read_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
resolved_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
question_bank_owner_tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_bank_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
is_visible = table.Column<bool>(type: "boolean", nullable: false),
|
|
alias = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
navigation_location = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
updated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
module_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
parent_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_parent_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_module_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
path = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
module_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
professional_exam_date = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
plan_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
code = table.Column<string>(type: "citext", maxLength: 100, nullable: false),
|
|
discount_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
discount_value = table.Column<decimal>(type: "numeric(10,2)", precision: 10, scale: 2, nullable: true),
|
|
valid_from = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
valid_to = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
max_uses = table.Column<int>(type: "integer", nullable: true),
|
|
used_count = table.Column<int>(type: "integer", nullable: false),
|
|
source = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
remark = table.Column<string>(type: "text", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
plan_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_user_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_plan_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_region_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
order_no = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
product_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
product_name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
pay_method = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
pay_provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
trade_no = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
days = table.Column<int>(type: "integer", nullable: true),
|
|
refunded_amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
paid_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
raw_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
class_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
member_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
joined_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
left_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
updated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
student_user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
assigned_to_user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
class_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
title = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
followup_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
priority = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
due_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
completed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
completed_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
updated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_student_followups", x => x.id);
|
|
table.UniqueConstraint("ak_tenant_student_followups_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_tenant_student_followups_tenant_classes_tenant_id_class_id",
|
|
columns: x => new { x.tenant_id, x.class_id },
|
|
principalTable: "tenant_classes",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.SetNull);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_student_followups_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_student_followups_users_assigned_to_user_id",
|
|
column: x => x.assigned_to_user_id,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_student_followups_users_completed_by",
|
|
column: x => x.completed_by,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.SetNull);
|
|
table.ForeignKey(
|
|
name: "fk_tenant_student_followups_users_student_user_id",
|
|
column: x => x.student_user_id,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "platform_dunning_notification_events",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
channel_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
reminder_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
invoice_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
provider = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
attempts = table.Column<int>(type: "integer", nullable: false),
|
|
scheduled_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
next_attempt_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
last_attempt_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
sent_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
last_error = table.Column<string>(type: "text", nullable: true),
|
|
last_http_code = table.Column<int>(type: "integer", nullable: true),
|
|
last_response_summary = table.Column<string>(type: "text", nullable: true),
|
|
request_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_platform_dunning_notification_events", x => x.id);
|
|
table.UniqueConstraint("ak_platform_dunning_notification_events_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.CheckConstraint("ck_platform_dunning_events_attempts", "attempts >= 0");
|
|
table.ForeignKey(
|
|
name: "fk_platform_dunning_notification_events_platform_dunning_notif~",
|
|
column: x => x.channel_id,
|
|
principalTable: "platform_dunning_notification_channels",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_platform_dunning_notification_events_tenant_invoice_reminde~",
|
|
columns: x => new { x.tenant_id, x.reminder_id },
|
|
principalTable: "tenant_invoice_reminders",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_platform_dunning_notification_events_tenant_invoices_tenant~",
|
|
columns: x => new { x.tenant_id, x.invoice_id },
|
|
principalTable: "tenant_invoices",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_platform_dunning_notification_events_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "vocabulary_units",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
entry_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
content_node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
word_count = table.Column<int>(type: "integer", nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
source_hash = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
school_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
exam_name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
exam_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
exam_type = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
school_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
study_tips = table.Column<string>(type: "text", nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
coupon_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
plan_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
order_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
coupon_code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
discount_applied_cents = table.Column<int>(type: "integer", nullable: true),
|
|
source = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
remark = table.Column<string>(type: "text", nullable: true),
|
|
claimed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
used_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
order_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
item_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
item_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
quantity = table.Column<int>(type: "integer", nullable: false),
|
|
unit_amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
total_amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
order_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_order_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
method = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
refunded_amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
provider_trade_no = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
paid_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
raw_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_payments", x => x.id);
|
|
table.UniqueConstraint("ak_payments_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.CheckConstraint("ck_payments_amount", "amount_cents >= 0");
|
|
table.CheckConstraint("ck_payments_refunded_amount", "refunded_amount_cents >= 0");
|
|
table.ForeignKey(
|
|
name: "fk_payments_orders_tenant_id_order_id",
|
|
columns: x => new { x.tenant_id, x.order_id },
|
|
principalTable: "orders",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_payments_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "vocabulary_words",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
unit_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
entry_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
content_node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
word = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
phonetic = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
meaning = table.Column<string>(type: "text", nullable: true),
|
|
example = table.Column<string>(type: "text", nullable: true),
|
|
example_translation = table.Column<string>(type: "text", nullable: true),
|
|
difficulty = table.Column<int>(type: "integer", nullable: true),
|
|
tags = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
source_hash = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
school_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
major_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
entry_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
content_node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
icon = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
color = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
major_legacy_ids = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
source_hash = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
school_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
major_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
year = table.Column<int>(type: "integer", nullable: false),
|
|
school_name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
major_name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
field_values = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
legacy_user_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
avatar_preset = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false, defaultValue: "male"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
selected_school_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
selected_major_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
questions_answered_today = table.Column<int>(type: "integer", nullable: false),
|
|
mastered_words_count = table.Column<int>(type: "integer", nullable: false),
|
|
last_check_in_date = table.Column<DateOnly>(type: "date", nullable: true),
|
|
stats = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
progress = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
module_selections = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
recent_activities = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
module_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
school_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
major_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
major_legacy_ids = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
icon = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
stats = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
used_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
agent_user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
batch_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
used_region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
coupon_redemption_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
code = table.Column<string>(type: "citext", maxLength: 100, nullable: false),
|
|
days = table.Column<int>(type: "integer", nullable: false),
|
|
is_used = table.Column<bool>(type: "boolean", nullable: false),
|
|
used_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
sale_type = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
unit_price_cents = table.Column<int>(type: "integer", nullable: true),
|
|
sold_to = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
coupon_code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
remark = table.Column<string>(type: "text", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
order_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
payment_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
requested_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
reviewed_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
processed_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
refund_no = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
provider_refund_no = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
reason = table.Column<string>(type: "text", nullable: true),
|
|
entitlement_action = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
requested_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
reviewed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
processed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
succeeded_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
failed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
cancelled_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
failure_reason = table.Column<string>(type: "text", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
payment_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
event_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
event_id = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
signature_valid = table.Column<bool>(type: "boolean", nullable: true),
|
|
payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
processed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
error = table.Column<string>(type: "text", nullable: true),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
word_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
legacy_id = table.Column<string>(type: "text", nullable: true),
|
|
legacy_user_id = table.Column<string>(type: "text", nullable: true),
|
|
legacy_word_id = table.Column<string>(type: "text", nullable: true),
|
|
note = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
favorited_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
word_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
legacy_id = table.Column<string>(type: "text", nullable: true),
|
|
legacy_user_id = table.Column<string>(type: "text", nullable: true),
|
|
legacy_word_id = table.Column<string>(type: "text", nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
correct_count = table.Column<int>(type: "integer", nullable: false),
|
|
wrong_count = table.Column<int>(type: "integer", nullable: false),
|
|
last_review_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
next_review_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
review_count = table.Column<int>(type: "integer", nullable: false),
|
|
correct_streak = table.Column<int>(type: "integer", nullable: false),
|
|
ease_factor = table.Column<decimal>(type: "numeric(4,2)", precision: 4, scale: 2, nullable: false, defaultValue: 2.50m),
|
|
last_result = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
due_level = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
subject_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
entry_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
content_node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
source_hash = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
subject_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
category_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
svip_question_limit = table.Column<int>(type: "integer", nullable: true),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
subject_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
display_name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
|
types = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false),
|
|
source_subject_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
target_subject_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
legacy_id = table.Column<string>(type: "text", nullable: true),
|
|
legacy_source_subject_id = table.Column<string>(type: "text", nullable: true),
|
|
legacy_target_subject_id = table.Column<string>(type: "text", nullable: true),
|
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false)
|
|
},
|
|
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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
subject_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_subject_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
title = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
video_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
thumbnail_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
duration_seconds = table.Column<int>(type: "integer", nullable: true),
|
|
knowledge_tags = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
is_general = table.Column<bool>(type: "boolean", nullable: false),
|
|
difficulty = table.Column<int>(type: "integer", nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
source_hash = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
batch_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
order_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
payment_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
refund_request_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
row_no = table.Column<int>(type: "integer", nullable: false),
|
|
provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
transaction_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
provider_trade_no = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
provider_refund_no = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
order_no = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
refund_no = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
refund_amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
fee_cents = table.Column<int>(type: "integer", nullable: false),
|
|
paid_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
refunded_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
provider_status = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
local_status = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
match_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
severity = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
issue_code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
details = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
refund_request_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
from_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
to_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
event_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
actor_user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
details = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
chapter_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
entry_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
content_node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
title = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: false),
|
|
summary = table.Column<string>(type: "text", nullable: true),
|
|
content = table.Column<string>(type: "text", nullable: true),
|
|
tags = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
is_active = table.Column<bool>(type: "boolean", nullable: false),
|
|
source_hash = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
subject_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
category_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
content_node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
updated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
verified_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
asset_key = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
title = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
category = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
file_name = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
|
|
cdn_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
is_public = table.Column<bool>(type: "boolean", nullable: false),
|
|
asset_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
storage_provider = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
bucket = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
object_key = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
mime_type = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
file_size_bytes = table.Column<long>(type: "bigint", nullable: true),
|
|
checksum_sha256 = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
visibility = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
preview_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
access_rules = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
source = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
download_count = table.Column<int>(type: "integer", nullable: false),
|
|
upload_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
verified_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
verified_size_bytes = table.Column<long>(type: "bigint", nullable: true),
|
|
verified_checksum_sha256 = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
verification_details = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
preview_object_key = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
preview_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
security_scan_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false, defaultValue: "not_required"),
|
|
security_scanned_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
security_scan_provider = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
security_scan_summary = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
security_flags = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
target_region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
target_subject_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
target_category_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
target_content_node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
target_question_bank_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
import_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
source_format = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
source_name = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
|
|
source_hash = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
|
dry_run = table.Column<bool>(type: "boolean", nullable: false),
|
|
total_count = table.Column<int>(type: "integer", nullable: false),
|
|
valid_count = table.Column<int>(type: "integer", nullable: false),
|
|
error_count = table.Column<int>(type: "integer", nullable: false),
|
|
warning_count = table.Column<int>(type: "integer", nullable: false),
|
|
inserted_count = table.Column<int>(type: "integer", nullable: false),
|
|
updated_count = table.Column<int>(type: "integer", nullable: false),
|
|
skipped_count = table.Column<int>(type: "integer", nullable: false),
|
|
summary = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
raw_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
normalized_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
error_message = table.Column<string>(type: "text", nullable: true),
|
|
started_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
finished_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
entry_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
subject_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
category_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
question_bank_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
collection_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
source_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
filters = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
access_rules = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
question_count = table.Column<int>(type: "integer", nullable: false),
|
|
total_score = table.Column<decimal>(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true),
|
|
duration_minutes = table.Column<int>(type: "integer", nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
updated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
batch_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
item_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
order_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
payment_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
refund_request_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
assigned_to = table.Column<Guid>(type: "uuid", nullable: true),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
resolved_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
issue_no = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
transaction_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
issue_code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
match_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
severity = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
resolution_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
order_no = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
refund_no = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
provider_trade_no = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
provider_refund_no = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
refund_amount_cents = table.Column<int>(type: "integer", nullable: false),
|
|
resolved_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
due_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
summary = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
resolution_note = table.Column<string>(type: "text", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
job_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
retry_count = table.Column<int>(type: "integer", nullable: false),
|
|
max_retries = table.Column<int>(type: "integer", nullable: false),
|
|
locked_by = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
lock_expires_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
run_after = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
started_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
completed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
last_error = table.Column<string>(type: "character varying(4000)", maxLength: 4000, nullable: true),
|
|
output_asset_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
result = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_background_jobs", x => x.id);
|
|
table.UniqueConstraint("ak_background_jobs_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.ForeignKey(
|
|
name: "fk_background_jobs_content_assets_tenant_id_output_asset_id",
|
|
columns: x => new { x.tenant_id, x.output_asset_id },
|
|
principalTable: "content_assets",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.SetNull);
|
|
table.ForeignKey(
|
|
name: "fk_background_jobs_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "commission_settlement_proofs",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
settlement_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
asset_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
submitted_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
reviewed_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
proof_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
title = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
external_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
amount_cents = table.Column<int>(type: "integer", nullable: true),
|
|
payment_method = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
payment_account = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
paid_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
reviewed_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
review_note = table.Column<string>(type: "text", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
asset_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
actor_role = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
access_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
visibility = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
asset_type = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
storage_provider = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
disposition = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
expires_in_seconds = table.Column<int>(type: "integer", nullable: true),
|
|
signature_mode = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
result = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
deny_code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
ip_address = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
user_agent = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
asset_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
provider = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
scan_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
risk_level = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
issue_codes = table.Column<string[]>(type: "text[]", nullable: false, defaultValueSql: "'{}'::text[]"),
|
|
details = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
job_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
row_no = table.Column<int>(type: "integer", nullable: false),
|
|
external_id = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
target_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
target_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
source_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
normalized_payload = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
content_hash = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
|
issues_count = table.Column<int>(type: "integer", nullable: false),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
region_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
entry_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
collection_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
|
mode = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
assembly_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
question_limit = table.Column<int>(type: "integer", nullable: true),
|
|
duration_minutes = table.Column<int>(type: "integer", nullable: true),
|
|
total_score = table.Column<decimal>(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true),
|
|
pass_score = table.Column<decimal>(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true),
|
|
sections = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
rules = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
access_rules = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
updated_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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_reconciliation_issue_events",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
issue_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
from_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
to_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
event_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
actor_user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
note = table.Column<string>(type: "text", nullable: true),
|
|
details = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
job_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
item_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
row_no = table.Column<int>(type: "integer", nullable: true),
|
|
severity = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
code = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
field_path = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
|
|
message = table.Column<string>(type: "character varying(2000)", maxLength: 2000, nullable: false),
|
|
details = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
blueprint_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
collection_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
entry_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
content_node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
mode = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
target_type = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
target_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
started_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
finished_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
question_count = table.Column<int>(type: "integer", nullable: false),
|
|
duration_minutes = table.Column<int>(type: "integer", nullable: true),
|
|
total_score = table.Column<decimal>(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true),
|
|
expires_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
access_mode = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false, defaultValue: "free"),
|
|
access_entitlement_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
consumed_free_quota = table.Column<int>(type: "integer", nullable: false),
|
|
access_snapshot = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false)
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_practice_sessions", x => x.id);
|
|
table.UniqueConstraint("ak_practice_sessions_tenant_id_id", x => new { x.tenant_id, x.id });
|
|
table.UniqueConstraint("ak_practice_sessions_tenant_id_user_id_id", x => new { x.tenant_id, x.user_id, x.id });
|
|
table.CheckConstraint("ck_practice_sessions_consumed_free_quota", "consumed_free_quota >= 0");
|
|
table.ForeignKey(
|
|
name: "fk_practice_sessions_content_entries_tenant_id_entry_id",
|
|
columns: x => new { x.tenant_id, x.entry_id },
|
|
principalTable: "content_entries",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Restrict);
|
|
table.ForeignKey(
|
|
name: "fk_practice_sessions_content_nodes_tenant_id_content_node_id",
|
|
columns: x => new { x.tenant_id, x.content_node_id },
|
|
principalTable: "content_nodes",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Restrict);
|
|
table.ForeignKey(
|
|
name: "fk_practice_sessions_practice_blueprints_tenant_id_blueprint_id",
|
|
columns: x => new { x.tenant_id, x.blueprint_id },
|
|
principalTable: "practice_blueprints",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Restrict);
|
|
table.ForeignKey(
|
|
name: "fk_practice_sessions_question_collections_tenant_id_collection~",
|
|
columns: x => new { x.tenant_id, x.collection_id },
|
|
principalTable: "question_collections",
|
|
principalColumns: new[] { "tenant_id", "id" },
|
|
onDelete: ReferentialAction.Restrict);
|
|
table.ForeignKey(
|
|
name: "fk_practice_sessions_tenants_tenant_id",
|
|
column: x => x.tenant_id,
|
|
principalTable: "tenants",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
table.ForeignKey(
|
|
name: "fk_practice_sessions_users_user_id",
|
|
column: x => x.user_id,
|
|
principalTable: "users",
|
|
principalColumn: "id",
|
|
onDelete: ReferentialAction.Cascade);
|
|
});
|
|
|
|
migrationBuilder.CreateTable(
|
|
name: "practice_access_events",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
practice_session_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
event_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
access_mode = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
requested_count = table.Column<int>(type: "integer", nullable: false),
|
|
granted_count = table.Column<int>(type: "integer", nullable: false),
|
|
consumed_free_quota = table.Column<int>(type: "integer", nullable: false),
|
|
reason = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
|
scope_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
scope_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
entitlement_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
practice_session_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
blueprint_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
collection_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
mode = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
total_questions = table.Column<int>(type: "integer", nullable: false),
|
|
answered_count = table.Column<int>(type: "integer", nullable: false),
|
|
correct_count = table.Column<int>(type: "integer", nullable: false),
|
|
wrong_count = table.Column<int>(type: "integer", nullable: false),
|
|
unanswered_count = table.Column<int>(type: "integer", nullable: false),
|
|
score = table.Column<decimal>(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false),
|
|
total_score = table.Column<decimal>(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false),
|
|
accuracy = table.Column<decimal>(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false),
|
|
duration_seconds = table.Column<int>(type: "integer", nullable: false),
|
|
started_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
submitted_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
section_stats = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
question_results = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
wrong_question_ids = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
report_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
practice_session_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
section_key = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
section_name = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
question_type = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
question_count = table.Column<int>(type: "integer", nullable: false),
|
|
answered_count = table.Column<int>(type: "integer", nullable: false),
|
|
correct_count = table.Column<int>(type: "integer", nullable: false),
|
|
wrong_count = table.Column<int>(type: "integer", nullable: false),
|
|
unanswered_count = table.Column<int>(type: "integer", nullable: false),
|
|
score = table.Column<decimal>(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false),
|
|
total_score = table.Column<decimal>(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false),
|
|
accuracy = table.Column<decimal>(type: "numeric(6,4)", precision: 6, scale: 4, nullable: false),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
practice_session_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
session_question_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_question_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_category_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
selected_options = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
answer_text = table.Column<string>(type: "text", nullable: true),
|
|
is_correct = table.Column<bool>(type: "boolean", nullable: true),
|
|
answered_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
tenant_id = table.Column<Guid>(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<Guid>(type: "uuid", nullable: false),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_reference_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_owner_tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
source = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
practice_session_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_reference_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_owner_tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_version_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
position = table.Column<int>(type: "integer", nullable: false),
|
|
score = table.Column<decimal>(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true),
|
|
tenant_id = table.Column<Guid>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
collection_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_reference_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_owner_tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
section_key = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
score = table.Column<decimal>(type: "numeric(8,2)", precision: 8, scale: 2, nullable: true),
|
|
required = table.Column<bool>(type: "boolean", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
taxonomy_owner_tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
taxonomy_node_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
is_primary = table.Column<bool>(type: "boolean", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
version_no = table.Column<int>(type: "integer", nullable: false),
|
|
content = table.Column<string>(type: "text", nullable: true),
|
|
options = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
correct_option_index = table.Column<int>(type: "integer", nullable: true),
|
|
correct_option_indices = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
answer_text = table.Column<string>(type: "text", nullable: true),
|
|
explanation = table.Column<string>(type: "text", nullable: true),
|
|
sub_questions = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
code_lang = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
|
code_template = table.Column<string>(type: "text", nullable: true),
|
|
source_hash = table.Column<string>(type: "character varying(128)", maxLength: 128, nullable: true),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
question_bank_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
subject_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
category_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
entry_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
content_node_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
primary_collection_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_subject_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_category_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_node_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
type = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
|
type_label = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
difficulty = table.Column<int>(type: "integer", nullable: true),
|
|
tags = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
exam_markers = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
media_url = table.Column<string>(type: "character varying(2048)", maxLength: 2048, nullable: true),
|
|
has_video_explanation = table.Column<bool>(type: "boolean", nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
current_version_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
question_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
video_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_question_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
legacy_video_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
video_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
sort_order = table.Column<int>(type: "integer", nullable: false),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
question_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
handled_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
title = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
category = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
description = table.Column<string>(type: "text", nullable: true),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
priority = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
handled_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
resolution = table.Column<string>(type: "text", nullable: true),
|
|
contact = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
|
attachments = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'[]'::jsonb"),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
question_owner_tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
source = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
created_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_tenant_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: "report_status_events",
|
|
columns: table => new
|
|
{
|
|
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
report_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
from_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
to_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
note = table.Column<string>(type: "text", nullable: true),
|
|
actor_user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
created_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false),
|
|
user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_reference_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_owner_tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
question_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
wrong_count = table.Column<int>(type: "integer", nullable: false, defaultValue: 1),
|
|
last_wrong_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
resolved_at = table.Column<DateTimeOffset>(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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
student_user_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
referrer_user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
first_track_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
assigned_to_user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
assigned_by = table.Column<Guid>(type: "uuid", nullable: true),
|
|
ref_code = table.Column<string>(type: "citext", maxLength: 100, nullable: true),
|
|
source = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
bind_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
|
protected_until = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
assignment_mode = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: true),
|
|
assigned_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
bound_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
|
|
lead_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
referrer_user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
target_user_id = table.Column<Guid>(type: "uuid", nullable: true),
|
|
legacy_id = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true),
|
|
event_type = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
|
ref_code = table.Column<string>(type: "citext", maxLength: 100, nullable: true),
|
|
source = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
ip_address = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true),
|
|
user_agent = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
|
|
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
|
|
tenant_id = table.Column<Guid>(type: "uuid", nullable: false),
|
|
created_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()"),
|
|
updated_at = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now()")
|
|
},
|
|
constraints: table =>
|
|
{
|
|
table.PrimaryKey("pk_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_login_events_tenant_id_user_id_created_at",
|
|
table: "auth_login_events",
|
|
columns: new[] { "tenant_id", "user_id", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_auth_login_events_user_id",
|
|
table: "auth_login_events",
|
|
column: "user_id");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_auth_sessions_tenant_id_user_id_expires_at",
|
|
table: "auth_sessions",
|
|
columns: new[] { "tenant_id", "user_id", "expires_at" },
|
|
filter: "revoked_at is null");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_auth_sessions_token_hash",
|
|
table: "auth_sessions",
|
|
column: "token_hash",
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_auth_sessions_user_id",
|
|
table: "auth_sessions",
|
|
column: "user_id");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_backend_menus_area_parent_code_sort_order",
|
|
table: "backend_menus",
|
|
columns: new[] { "area", "parent_code", "sort_order" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_backend_menus_code",
|
|
table: "backend_menus",
|
|
column: "code",
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_backend_menus_permission_code",
|
|
table: "backend_menus",
|
|
column: "permission_code");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_backend_permissions_area_module_sort_order",
|
|
table: "backend_permissions",
|
|
columns: new[] { "area", "module", "sort_order" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_backend_permissions_code",
|
|
table: "backend_permissions",
|
|
column: "code",
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_background_jobs_tenant_id_job_type_status_created_at",
|
|
table: "background_jobs",
|
|
columns: new[] { "tenant_id", "job_type", "status", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_background_jobs_tenant_id_output_asset_id",
|
|
table: "background_jobs",
|
|
columns: new[] { "tenant_id", "output_asset_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_background_jobs_tenant_id_status_run_after_created_at",
|
|
table: "background_jobs",
|
|
columns: new[] { "tenant_id", "status", "run_after", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_badges_tenant_id_category_is_active_sort_order",
|
|
table: "badges",
|
|
columns: new[] { "tenant_id", "category", "is_active", "sort_order" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_badges_tenant_id_legacy_id",
|
|
table: "badges",
|
|
columns: new[] { "tenant_id", "legacy_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_banners_tenant_id_legacy_id",
|
|
table: "banners",
|
|
columns: new[] { "tenant_id", "legacy_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_banners_tenant_id_region_id_is_active_sort_order",
|
|
table: "banners",
|
|
columns: new[] { "tenant_id", "region_id", "is_active", "sort_order" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_categories_tenant_id_legacy_id",
|
|
table: "categories",
|
|
columns: new[] { "tenant_id", "legacy_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_categories_tenant_id_node_id",
|
|
table: "categories",
|
|
columns: new[] { "tenant_id", "node_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_categories_tenant_id_subject_id",
|
|
table: "categories",
|
|
columns: new[] { "tenant_id", "subject_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_code_batches_tenant_id_legacy_id",
|
|
table: "code_batches",
|
|
columns: new[] { "tenant_id", "legacy_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_batches_created_by",
|
|
table: "commerce_reconciliation_batches",
|
|
column: "created_by");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_batches_tenant_id_provider_bill_dat~",
|
|
table: "commerce_reconciliation_batches",
|
|
columns: new[] { "tenant_id", "provider", "bill_date", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_batches_tenant_id_status_created_at",
|
|
table: "commerce_reconciliation_batches",
|
|
columns: new[] { "tenant_id", "status", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issue_events_actor_user_id",
|
|
table: "commerce_reconciliation_issue_events",
|
|
column: "actor_user_id");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issue_events_tenant_id_issue_id_cre~",
|
|
table: "commerce_reconciliation_issue_events",
|
|
columns: new[] { "tenant_id", "issue_id", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issues_assigned_to",
|
|
table: "commerce_reconciliation_issues",
|
|
column: "assigned_to");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issues_created_by",
|
|
table: "commerce_reconciliation_issues",
|
|
column: "created_by");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issues_resolved_by",
|
|
table: "commerce_reconciliation_issues",
|
|
column: "resolved_by");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issues_tenant_id_assigned_to_status~",
|
|
table: "commerce_reconciliation_issues",
|
|
columns: new[] { "tenant_id", "assigned_to", "status", "due_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issues_tenant_id_batch_id_status_cr~",
|
|
table: "commerce_reconciliation_issues",
|
|
columns: new[] { "tenant_id", "batch_id", "status", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issues_tenant_id_issue_no",
|
|
table: "commerce_reconciliation_issues",
|
|
columns: new[] { "tenant_id", "issue_no" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issues_tenant_id_item_id",
|
|
table: "commerce_reconciliation_issues",
|
|
columns: new[] { "tenant_id", "item_id" },
|
|
unique: true,
|
|
filter: "item_id is not null and status in ('open', 'investigating', 'escalated')");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issues_tenant_id_order_id",
|
|
table: "commerce_reconciliation_issues",
|
|
columns: new[] { "tenant_id", "order_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issues_tenant_id_order_no_created_at",
|
|
table: "commerce_reconciliation_issues",
|
|
columns: new[] { "tenant_id", "order_no", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issues_tenant_id_payment_id_created~",
|
|
table: "commerce_reconciliation_issues",
|
|
columns: new[] { "tenant_id", "payment_id", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issues_tenant_id_refund_request_id",
|
|
table: "commerce_reconciliation_issues",
|
|
columns: new[] { "tenant_id", "refund_request_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_issues_tenant_id_status_severity_cr~",
|
|
table: "commerce_reconciliation_issues",
|
|
columns: new[] { "tenant_id", "status", "severity", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_commerce_reconciliation_items_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_majors_tenant_id_legacy_id",
|
|
table: "majors",
|
|
columns: new[] { "tenant_id", "legacy_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_majors_tenant_id_region_id",
|
|
table: "majors",
|
|
columns: new[] { "tenant_id", "region_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_majors_tenant_id_school_id",
|
|
table: "majors",
|
|
columns: new[] { "tenant_id", "school_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_module_nodes_tenant_id_legacy_id",
|
|
table: "module_nodes",
|
|
columns: new[] { "tenant_id", "legacy_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_module_nodes_tenant_id_module_id",
|
|
table: "module_nodes",
|
|
columns: new[] { "tenant_id", "module_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_module_nodes_tenant_id_parent_id",
|
|
table: "module_nodes",
|
|
columns: new[] { "tenant_id", "parent_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_module_nodes_tenant_id_region_id",
|
|
table: "module_nodes",
|
|
columns: new[] { "tenant_id", "region_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_order_items_tenant_id_legacy_id",
|
|
table: "order_items",
|
|
columns: new[] { "tenant_id", "legacy_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_order_items_tenant_id_order_id",
|
|
table: "order_items",
|
|
columns: new[] { "tenant_id", "order_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_orders_tenant_id_legacy_id",
|
|
table: "orders",
|
|
columns: new[] { "tenant_id", "legacy_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_orders_tenant_id_order_no",
|
|
table: "orders",
|
|
columns: new[] { "tenant_id", "order_no" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_orders_tenant_id_plan_id",
|
|
table: "orders",
|
|
columns: new[] { "tenant_id", "plan_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_orders_tenant_id_region_id",
|
|
table: "orders",
|
|
columns: new[] { "tenant_id", "region_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_orders_tenant_id_user_id_created_at",
|
|
table: "orders",
|
|
columns: new[] { "tenant_id", "user_id", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_orders_user_id",
|
|
table: "orders",
|
|
column: "user_id");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_payment_events_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_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_dunning_notification_channels_channel_code",
|
|
table: "platform_dunning_notification_channels",
|
|
column: "channel_code",
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_platform_dunning_notification_channels_enabled_min_reminder~",
|
|
table: "platform_dunning_notification_channels",
|
|
columns: new[] { "enabled", "min_reminder_level", "channel_code" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_platform_dunning_notification_events_channel_id",
|
|
table: "platform_dunning_notification_events",
|
|
column: "channel_id");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_platform_dunning_notification_events_invoice_id_status_crea~",
|
|
table: "platform_dunning_notification_events",
|
|
columns: new[] { "invoice_id", "status", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_platform_dunning_notification_events_reminder_id_status_cre~",
|
|
table: "platform_dunning_notification_events",
|
|
columns: new[] { "reminder_id", "status", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_platform_dunning_notification_events_status_next_attempt_at~",
|
|
table: "platform_dunning_notification_events",
|
|
columns: new[] { "status", "next_attempt_at", "scheduled_at", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_platform_dunning_notification_events_tenant_id_channel_id_r~",
|
|
table: "platform_dunning_notification_events",
|
|
columns: new[] { "tenant_id", "channel_id", "reminder_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_platform_dunning_notification_events_tenant_id_invoice_id",
|
|
table: "platform_dunning_notification_events",
|
|
columns: new[] { "tenant_id", "invoice_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_platform_dunning_notification_events_tenant_id_reminder_id",
|
|
table: "platform_dunning_notification_events",
|
|
columns: new[] { "tenant_id", "reminder_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_platform_dunning_notification_events_tenant_id_status_creat~",
|
|
table: "platform_dunning_notification_events",
|
|
columns: new[] { "tenant_id", "status", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_platform_saas_plans_code",
|
|
table: "platform_saas_plans",
|
|
column: "code",
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_platform_saas_plans_status_sort_order",
|
|
table: "platform_saas_plans",
|
|
columns: new[] { "status", "sort_order" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_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_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_frontend_configs_tenant_id",
|
|
table: "tenant_frontend_configs",
|
|
column: "tenant_id",
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoice_items_invoice_id",
|
|
table: "tenant_invoice_items",
|
|
column: "invoice_id");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoice_items_tenant_id_invoice_id",
|
|
table: "tenant_invoice_items",
|
|
columns: new[] { "tenant_id", "invoice_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoice_payments_invoice_id_status",
|
|
table: "tenant_invoice_payments",
|
|
columns: new[] { "invoice_id", "status" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoice_payments_received_by",
|
|
table: "tenant_invoice_payments",
|
|
column: "received_by");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoice_payments_tenant_id_invoice_id",
|
|
table: "tenant_invoice_payments",
|
|
columns: new[] { "tenant_id", "invoice_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoice_payments_tenant_id_payment_no",
|
|
table: "tenant_invoice_payments",
|
|
columns: new[] { "tenant_id", "payment_no" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoice_reminders_created_by",
|
|
table: "tenant_invoice_reminders",
|
|
column: "created_by");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoice_reminders_invoice_id_reminder_date",
|
|
table: "tenant_invoice_reminders",
|
|
columns: new[] { "invoice_id", "reminder_date" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoice_reminders_tenant_id_invoice_id_reminder_type~",
|
|
table: "tenant_invoice_reminders",
|
|
columns: new[] { "tenant_id", "invoice_id", "reminder_type", "channel", "reminder_date" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoice_reminders_tenant_id_status_reminder_date",
|
|
table: "tenant_invoice_reminders",
|
|
columns: new[] { "tenant_id", "status", "reminder_date" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoices_created_by",
|
|
table: "tenant_invoices",
|
|
column: "created_by");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoices_tenant_id_billing_period_start_billing_peri~",
|
|
table: "tenant_invoices",
|
|
columns: new[] { "tenant_id", "billing_period_start", "billing_period_end" },
|
|
unique: true,
|
|
filter: "invoice_type = 'usage_overage' and status <> 'void' and metadata->>'source' = 'usage_overage_auto'");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoices_tenant_id_invoice_no",
|
|
table: "tenant_invoices",
|
|
columns: new[] { "tenant_id", "invoice_no" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_invoices_tenant_id_status_due_date",
|
|
table: "tenant_invoices",
|
|
columns: new[] { "tenant_id", "status", "due_date" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_memberships_tenant_id_role_template_id",
|
|
table: "tenant_memberships",
|
|
columns: new[] { "tenant_id", "role_template_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_memberships_tenant_id_user_id_role",
|
|
table: "tenant_memberships",
|
|
columns: new[] { "tenant_id", "user_id", "role" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_memberships_user_id",
|
|
table: "tenant_memberships",
|
|
column: "user_id");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_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_role_templates_created_by",
|
|
table: "tenant_role_templates",
|
|
column: "created_by");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_role_templates_tenant_id_code",
|
|
table: "tenant_role_templates",
|
|
columns: new[] { "tenant_id", "code" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_role_templates_tenant_id_status_sort_order",
|
|
table: "tenant_role_templates",
|
|
columns: new[] { "tenant_id", "status", "sort_order" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_role_templates_updated_by",
|
|
table: "tenant_role_templates",
|
|
column: "updated_by");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_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_subscriptions_tenant_id_status_expires_at",
|
|
table: "tenant_subscriptions",
|
|
columns: new[] { "tenant_id", "status", "expires_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_theme_configs_active_template_code",
|
|
table: "tenant_theme_configs",
|
|
column: "active_template_code");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_theme_configs_draft_template_code",
|
|
table: "tenant_theme_configs",
|
|
column: "draft_template_code");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_theme_configs_draft_updated_by",
|
|
table: "tenant_theme_configs",
|
|
column: "draft_updated_by");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_theme_configs_published_by",
|
|
table: "tenant_theme_configs",
|
|
column: "published_by");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_theme_configs_tenant_id",
|
|
table: "tenant_theme_configs",
|
|
column: "tenant_id",
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_theme_templates_code",
|
|
table: "tenant_theme_templates",
|
|
column: "code",
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_theme_templates_status_sort_order_code",
|
|
table: "tenant_theme_templates",
|
|
columns: new[] { "status", "sort_order", "code" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenant_usage_records_tenant_id_metric_key_period_start_peri~",
|
|
table: "tenant_usage_records",
|
|
columns: new[] { "tenant_id", "metric_key", "period_start", "period_end" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenants_legacy_id",
|
|
table: "tenants",
|
|
column: "legacy_id",
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_tenants_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_identities_provider_provider_subject",
|
|
table: "user_identities",
|
|
columns: new[] { "provider", "provider_subject" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_identities_user_id",
|
|
table: "user_identities",
|
|
column: "user_id");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_notifications_created_by",
|
|
table: "user_notifications",
|
|
column: "created_by");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_notifications_tenant_id_source_type_source_id",
|
|
table: "user_notifications",
|
|
columns: new[] { "tenant_id", "source_type", "source_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_notifications_tenant_id_user_id_notification_type_dedu~",
|
|
table: "user_notifications",
|
|
columns: new[] { "tenant_id", "user_id", "notification_type", "dedupe_key" },
|
|
unique: true,
|
|
filter: "dedupe_key is not null");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_notifications_tenant_id_user_id_status_created_at",
|
|
table: "user_notifications",
|
|
columns: new[] { "tenant_id", "user_id", "status", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_notifications_user_id",
|
|
table: "user_notifications",
|
|
column: "user_id");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_score_events_tenant_id_idempotency_key",
|
|
table: "user_score_events",
|
|
columns: new[] { "tenant_id", "idempotency_key" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_score_events_tenant_id_user_id_created_at",
|
|
table: "user_score_events",
|
|
columns: new[] { "tenant_id", "user_id", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_score_events_user_id",
|
|
table: "user_score_events",
|
|
column: "user_id");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_word_favorites_tenant_id_user_id_word_id",
|
|
table: "user_word_favorites",
|
|
columns: new[] { "tenant_id", "user_id", "word_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_word_favorites_tenant_id_word_id",
|
|
table: "user_word_favorites",
|
|
columns: new[] { "tenant_id", "word_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_word_favorites_user_id",
|
|
table: "user_word_favorites",
|
|
column: "user_id");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_word_progress_tenant_id_user_id_next_review_at_status_~",
|
|
table: "user_word_progress",
|
|
columns: new[] { "tenant_id", "user_id", "next_review_at", "status", "due_level" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_word_progress_tenant_id_user_id_word_id",
|
|
table: "user_word_progress",
|
|
columns: new[] { "tenant_id", "user_id", "word_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_word_progress_tenant_id_word_id",
|
|
table: "user_word_progress",
|
|
columns: new[] { "tenant_id", "word_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_user_word_progress_user_id",
|
|
table: "user_word_progress",
|
|
column: "user_id");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_users_email",
|
|
table: "users",
|
|
column: "email",
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_users_legacy_id",
|
|
table: "users",
|
|
column: "legacy_id",
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_users_phone",
|
|
table: "users",
|
|
column: "phone",
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_users_username",
|
|
table: "users",
|
|
column: "username",
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_video_explanations_tenant_id_legacy_id",
|
|
table: "video_explanations",
|
|
columns: new[] { "tenant_id", "legacy_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_video_explanations_tenant_id_source_hash",
|
|
table: "video_explanations",
|
|
columns: new[] { "tenant_id", "source_hash" },
|
|
filter: "source_hash is not null");
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_video_explanations_tenant_id_subject_id_is_active_sort_order",
|
|
table: "video_explanations",
|
|
columns: new[] { "tenant_id", "subject_id", "is_active", "sort_order" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_vocabulary_units_tenant_id_content_node_id",
|
|
table: "vocabulary_units",
|
|
columns: new[] { "tenant_id", "content_node_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_vocabulary_units_tenant_id_entry_id_content_node_id_region_~",
|
|
table: "vocabulary_units",
|
|
columns: new[] { "tenant_id", "entry_id", "content_node_id", "region_id", "is_active", "sort_order" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_vocabulary_units_tenant_id_legacy_id",
|
|
table: "vocabulary_units",
|
|
columns: new[] { "tenant_id", "legacy_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_vocabulary_units_tenant_id_region_id",
|
|
table: "vocabulary_units",
|
|
columns: new[] { "tenant_id", "region_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_vocabulary_words_tenant_id_content_node_id",
|
|
table: "vocabulary_words",
|
|
columns: new[] { "tenant_id", "content_node_id" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_vocabulary_words_tenant_id_entry_id_content_node_id_unit_id~",
|
|
table: "vocabulary_words",
|
|
columns: new[] { "tenant_id", "entry_id", "content_node_id", "unit_id", "is_active", "sort_order" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_vocabulary_words_tenant_id_legacy_id",
|
|
table: "vocabulary_words",
|
|
columns: new[] { "tenant_id", "legacy_id" },
|
|
unique: true);
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_vocabulary_words_tenant_id_unit_id_is_active_sort_order_cre~",
|
|
table: "vocabulary_words",
|
|
columns: new[] { "tenant_id", "unit_id", "is_active", "sort_order", "created_at" });
|
|
|
|
migrationBuilder.CreateIndex(
|
|
name: "ix_wrong_questions_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.Sql(PostgreSqlTenantConstraintSql.CreateTenantQuestionReferenceGuard);
|
|
migrationBuilder.Sql(PostgreSqlTenantConstraintSql.CreateTaxonomyParentGuard);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
protected override void Down(MigrationBuilder migrationBuilder)
|
|
{
|
|
migrationBuilder.Sql(PostgreSqlTenantConstraintSql.DropTenantGuards);
|
|
|
|
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_login_events");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "auth_sessions");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "background_jobs");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "banners");
|
|
|
|
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: "entitlements");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "exam_dates");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "faqs");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "favorite_questions");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "handbook_entries");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "images");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "order_items");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "payment_events");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "pb_import_issues");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "pb_raw_records");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "platform_audit_alerts");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "platform_backend_role_menus");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "platform_backend_role_permissions");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "platform_backend_user_roles");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "platform_dunning_notification_events");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "platform_saas_plans");
|
|
|
|
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: "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_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_frontend_configs");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenant_invoice_items");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenant_invoice_payments");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenant_memberships");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenant_question_bank_preferences");
|
|
|
|
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_subscriptions");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenant_theme_configs");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenant_usage_records");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "user_badges");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "user_identities");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "user_notifications");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "user_score_events");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "user_word_favorites");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "user_word_progress");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "wrong_questions");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "code_batches");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "coupon_redemptions");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "practice_session_questions");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "commerce_reconciliation_issues");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "commission_settlements");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "content_assets");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "content_import_items");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "handbook_chapters");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "pb_import_runs");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "audit_logs");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "platform_audit_alert_rules");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "platform_backend_roles");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "platform_dunning_notification_channels");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenant_invoice_reminders");
|
|
|
|
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: "video_explanations");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "reports");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "backend_menus");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenant_backend_roles");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenant_role_templates");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenant_classes");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenant_theme_templates");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "badges");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "vocabulary_words");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "coupons");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenant_question_references");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "commerce_reconciliation_items");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "content_import_jobs");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "handbook_subjects");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenant_invoices");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "practice_sessions");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "backend_permissions");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "vocabulary_units");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "commerce_reconciliation_batches");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "commerce_refund_requests");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "practice_blueprints");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "payments");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "orders");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "svip_plans");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "regions");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "tenants");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "users");
|
|
|
|
migrationBuilder.DropTable(
|
|
name: "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");
|
|
}
|
|
}
|
|
}
|