Files
tiku-backend.net/Tiku.Infrastructure/Persistence/Migrations/20260725215750_AddContentPlatformOperationsPersistence.cs

453 lines
26 KiB
C#

using System;
using System.Text.Json;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Tiku.Infrastructure.Persistence.Migrations
{
/// <inheritdoc />
public partial class AddContentPlatformOperationsPersistence : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "security_scan_provider",
table: "content_assets",
type: "character varying(100)",
maxLength: 100,
nullable: true);
migrationBuilder.AddColumn<string>(
name: "security_scan_status",
table: "content_assets",
type: "character varying(32)",
maxLength: 32,
nullable: false,
defaultValue: "not_required");
migrationBuilder.AddColumn<JsonElement>(
name: "security_scan_summary",
table: "content_assets",
type: "jsonb",
nullable: false,
defaultValueSql: "'{}'::jsonb");
migrationBuilder.AddColumn<DateTimeOffset>(
name: "security_scanned_at",
table: "content_assets",
type: "timestamp with time zone",
nullable: true);
migrationBuilder.CreateTable(
name: "ai_recommendation_reports",
columns: table => new
{
id = table.Column<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: "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: "question_bank_grants",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
source_question_bank_id = table.Column<Guid>(type: "uuid", nullable: false),
created_by = table.Column<Guid>(type: "uuid", nullable: true),
updated_by = table.Column<Guid>(type: "uuid", nullable: true),
grant_scope = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
allowed_plan_codes = table.Column<string[]>(type: "text[]", nullable: false, defaultValueSql: "'{}'::text[]"),
allowed_tenant_ids = table.Column<Guid[]>(type: "uuid[]", nullable: false, defaultValueSql: "'{}'::uuid[]"),
allowed_region_ids = table.Column<Guid[]>(type: "uuid[]", nullable: false, defaultValueSql: "'{}'::uuid[]"),
allowed_subject_ids = table.Column<Guid[]>(type: "uuid[]", nullable: false, defaultValueSql: "'{}'::uuid[]"),
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),
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_question_bank_grants", x => x.id);
table.ForeignKey(
name: "fk_question_bank_grants_question_banks_source_question_bank_id",
column: x => x.source_question_bank_id,
principalTable: "question_banks",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_question_bank_grants_users_created_by",
column: x => x.created_by,
principalTable: "users",
principalColumn: "id",
onDelete: ReferentialAction.SetNull);
table.ForeignKey(
name: "fk_question_bank_grants_users_updated_by",
column: x => x.updated_by,
principalTable: "users",
principalColumn: "id",
onDelete: ReferentialAction.SetNull);
});
migrationBuilder.CreateTable(
name: "tenant_question_bank_adoptions",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", nullable: false, defaultValueSql: "gen_random_uuid()"),
source_question_bank_id = table.Column<Guid>(type: "uuid", nullable: false),
grant_id = table.Column<Guid>(type: "uuid", nullable: true),
target_question_bank_id = table.Column<Guid>(type: "uuid", nullable: true),
target_entry_id = table.Column<Guid>(type: "uuid", nullable: true),
target_collection_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),
adoption_mode = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
sync_status = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
source_snapshot = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
copied_question_count = table.Column<int>(type: "integer", nullable: false),
metadata = table.Column<JsonElement>(type: "jsonb", nullable: false, defaultValueSql: "'{}'::jsonb"),
last_synced_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_question_bank_adoptions", x => x.id);
table.UniqueConstraint("ak_tenant_question_bank_adoptions_tenant_id_id", x => new { x.tenant_id, x.id });
table.CheckConstraint("ck_tenant_question_bank_adoptions_copied_count", "copied_question_count >= 0");
table.ForeignKey(
name: "fk_tenant_question_bank_adoptions_content_entries_tenant_id_ta~",
columns: x => new { x.tenant_id, x.target_entry_id },
principalTable: "content_entries",
principalColumns: new[] { "tenant_id", "id" },
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "fk_tenant_question_bank_adoptions_question_bank_grants_grant_id",
column: x => x.grant_id,
principalTable: "question_bank_grants",
principalColumn: "id",
onDelete: ReferentialAction.SetNull);
table.ForeignKey(
name: "fk_tenant_question_bank_adoptions_question_banks_source_questi~",
column: x => x.source_question_bank_id,
principalTable: "question_banks",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_tenant_question_bank_adoptions_question_banks_tenant_id_tar~",
columns: x => new { x.tenant_id, x.target_question_bank_id },
principalTable: "question_banks",
principalColumns: new[] { "tenant_id", "id" },
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "fk_tenant_question_bank_adoptions_question_collections_tenant_~",
columns: x => new { x.tenant_id, x.target_collection_id },
principalTable: "question_collections",
principalColumns: new[] { "tenant_id", "id" },
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "fk_tenant_question_bank_adoptions_tenants_tenant_id",
column: x => x.tenant_id,
principalTable: "tenants",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_tenant_question_bank_adoptions_users_created_by",
column: x => x.created_by,
principalTable: "users",
principalColumn: "id",
onDelete: ReferentialAction.SetNull);
table.ForeignKey(
name: "fk_tenant_question_bank_adoptions_users_updated_by",
column: x => x.updated_by,
principalTable: "users",
principalColumn: "id",
onDelete: ReferentialAction.SetNull);
});
migrationBuilder.CreateIndex(
name: "ix_content_assets_tenant_id_security_scan_status_upload_status~",
table: "content_assets",
columns: new[] { "tenant_id", "security_scan_status", "upload_status", "status", "updated_at" });
migrationBuilder.CreateIndex(
name: "ix_ai_recommendation_reports_tenant_id_region_id_created_at",
table: "ai_recommendation_reports",
columns: new[] { "tenant_id", "region_id", "created_at" });
migrationBuilder.CreateIndex(
name: "ix_ai_recommendation_reports_tenant_id_user_id_created_at",
table: "ai_recommendation_reports",
columns: new[] { "tenant_id", "user_id", "created_at" });
migrationBuilder.CreateIndex(
name: "ix_ai_recommendation_reports_user_id",
table: "ai_recommendation_reports",
column: "user_id");
migrationBuilder.CreateIndex(
name: "ix_content_asset_access_events_tenant_id_access_type_result_cr~",
table: "content_asset_access_events",
columns: new[] { "tenant_id", "access_type", "result", "created_at" });
migrationBuilder.CreateIndex(
name: "ix_content_asset_access_events_tenant_id_asset_id_created_at",
table: "content_asset_access_events",
columns: new[] { "tenant_id", "asset_id", "created_at" });
migrationBuilder.CreateIndex(
name: "ix_content_asset_access_events_tenant_id_user_id_created_at",
table: "content_asset_access_events",
columns: new[] { "tenant_id", "user_id", "created_at" },
filter: "user_id is not null");
migrationBuilder.CreateIndex(
name: "ix_content_asset_access_events_user_id",
table: "content_asset_access_events",
column: "user_id");
migrationBuilder.CreateIndex(
name: "ix_content_asset_security_scan_events_tenant_id_asset_id_creat~",
table: "content_asset_security_scan_events",
columns: new[] { "tenant_id", "asset_id", "created_at" });
migrationBuilder.CreateIndex(
name: "ix_content_asset_security_scan_events_tenant_id_scan_status_ri~",
table: "content_asset_security_scan_events",
columns: new[] { "tenant_id", "scan_status", "risk_level", "created_at" });
migrationBuilder.CreateIndex(
name: "ix_question_bank_grants_allowed_plan_codes",
table: "question_bank_grants",
column: "allowed_plan_codes")
.Annotation("Npgsql:IndexMethod", "gin");
migrationBuilder.CreateIndex(
name: "ix_question_bank_grants_allowed_tenant_ids",
table: "question_bank_grants",
column: "allowed_tenant_ids")
.Annotation("Npgsql:IndexMethod", "gin");
migrationBuilder.CreateIndex(
name: "ix_question_bank_grants_created_by",
table: "question_bank_grants",
column: "created_by");
migrationBuilder.CreateIndex(
name: "ix_question_bank_grants_source_question_bank_id_status_starts_~",
table: "question_bank_grants",
columns: new[] { "source_question_bank_id", "status", "starts_at", "expires_at" });
migrationBuilder.CreateIndex(
name: "ix_question_bank_grants_updated_by",
table: "question_bank_grants",
column: "updated_by");
migrationBuilder.CreateIndex(
name: "ix_tenant_question_bank_adoptions_created_by",
table: "tenant_question_bank_adoptions",
column: "created_by");
migrationBuilder.CreateIndex(
name: "ix_tenant_question_bank_adoptions_grant_id",
table: "tenant_question_bank_adoptions",
column: "grant_id");
migrationBuilder.CreateIndex(
name: "ix_tenant_question_bank_adoptions_source_question_bank_id",
table: "tenant_question_bank_adoptions",
column: "source_question_bank_id");
migrationBuilder.CreateIndex(
name: "ix_tenant_question_bank_adoptions_tenant_id_source_question_ba~",
table: "tenant_question_bank_adoptions",
columns: new[] { "tenant_id", "source_question_bank_id" },
unique: true);
migrationBuilder.CreateIndex(
name: "ix_tenant_question_bank_adoptions_tenant_id_status_updated_at",
table: "tenant_question_bank_adoptions",
columns: new[] { "tenant_id", "status", "updated_at" });
migrationBuilder.CreateIndex(
name: "ix_tenant_question_bank_adoptions_tenant_id_target_collection_~",
table: "tenant_question_bank_adoptions",
columns: new[] { "tenant_id", "target_collection_id" });
migrationBuilder.CreateIndex(
name: "ix_tenant_question_bank_adoptions_tenant_id_target_entry_id",
table: "tenant_question_bank_adoptions",
columns: new[] { "tenant_id", "target_entry_id" });
migrationBuilder.CreateIndex(
name: "ix_tenant_question_bank_adoptions_tenant_id_target_question_ba~",
table: "tenant_question_bank_adoptions",
columns: new[] { "tenant_id", "target_question_bank_id" });
migrationBuilder.CreateIndex(
name: "ix_tenant_question_bank_adoptions_updated_by",
table: "tenant_question_bank_adoptions",
column: "updated_by");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ai_recommendation_reports");
migrationBuilder.DropTable(
name: "content_asset_access_events");
migrationBuilder.DropTable(
name: "content_asset_security_scan_events");
migrationBuilder.DropTable(
name: "tenant_question_bank_adoptions");
migrationBuilder.DropTable(
name: "question_bank_grants");
migrationBuilder.DropIndex(
name: "ix_content_assets_tenant_id_security_scan_status_upload_status~",
table: "content_assets");
migrationBuilder.DropColumn(
name: "security_scan_provider",
table: "content_assets");
migrationBuilder.DropColumn(
name: "security_scan_status",
table: "content_assets");
migrationBuilder.DropColumn(
name: "security_scan_summary",
table: "content_assets");
migrationBuilder.DropColumn(
name: "security_scanned_at",
table: "content_assets");
}
}
}