From b8dbc208f8f7b6949071be21c117a6a50477bee8 Mon Sep 17 00:00:00 2001 From: sei-tspencer Date: Tue, 19 Mar 2024 13:30:23 -0400 Subject: [PATCH 1/2] msel copy bug fix --- Blueprint.Api.Data/Models/CiteAction.cs | 4 + Blueprint.Api.Data/Models/CiteRole.cs | 4 + Blueprint.Api.Data/Models/Team.cs | 7 + ...319164829_more-cascade-deletes.Designer.cs | 1751 +++++++++++++++++ .../20240319164829_more-cascade-deletes.cs | 84 + .../BlueprintContextModelSnapshot.cs | 22 +- Blueprint.Api/Blueprint.Api.csproj | 2 +- Blueprint.Api/Services/MselService.cs | 116 +- 8 files changed, 1949 insertions(+), 41 deletions(-) create mode 100644 Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.Designer.cs create mode 100644 Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.cs diff --git a/Blueprint.Api.Data/Models/CiteAction.cs b/Blueprint.Api.Data/Models/CiteAction.cs index 3f2fe86..ead7035 100644 --- a/Blueprint.Api.Data/Models/CiteAction.cs +++ b/Blueprint.Api.Data/Models/CiteAction.cs @@ -33,6 +33,10 @@ public void Configure(EntityTypeBuilder builder) .HasOne(d => d.Msel) .WithMany(d => d.CiteActions) .OnDelete(DeleteBehavior.Cascade); + builder + .HasOne(d => d.Team) + .WithMany(d => d.CiteActions) + .OnDelete(DeleteBehavior.Cascade); } } diff --git a/Blueprint.Api.Data/Models/CiteRole.cs b/Blueprint.Api.Data/Models/CiteRole.cs index 336a7d3..e34dc72 100644 --- a/Blueprint.Api.Data/Models/CiteRole.cs +++ b/Blueprint.Api.Data/Models/CiteRole.cs @@ -30,6 +30,10 @@ public void Configure(EntityTypeBuilder builder) .HasOne(d => d.Msel) .WithMany(d => d.CiteRoles) .OnDelete(DeleteBehavior.Cascade); + builder + .HasOne(d => d.Team) + .WithMany(d => d.CiteRoles) + .OnDelete(DeleteBehavior.Cascade); } } diff --git a/Blueprint.Api.Data/Models/Team.cs b/Blueprint.Api.Data/Models/Team.cs index 6ad0d5e..01a9cc4 100755 --- a/Blueprint.Api.Data/Models/Team.cs +++ b/Blueprint.Api.Data/Models/Team.cs @@ -30,6 +30,8 @@ public class TeamEntity : BaseEntity public virtual ICollection Invitations { get; set; } = new HashSet(); public Guid? OldTeamId { get; set; } public virtual ICollection UserTeamRoles { get; set; } = new HashSet(); + public virtual ICollection CiteActions { get; set; } = new HashSet(); + public virtual ICollection CiteRoles { get; set; } = new HashSet(); } public class TeamConfiguration : IEntityTypeConfiguration @@ -37,6 +39,11 @@ public class TeamConfiguration : IEntityTypeConfiguration public void Configure(EntityTypeBuilder builder) { builder.HasIndex(e => e.Id).IsUnique(); + + builder + .HasOne(d => d.Msel) + .WithMany(d => d.Teams) + .OnDelete(DeleteBehavior.Cascade); } } } diff --git a/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.Designer.cs b/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.Designer.cs new file mode 100644 index 0000000..e15b099 --- /dev/null +++ b/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.Designer.cs @@ -0,0 +1,1751 @@ +// +using System; +using Blueprint.Api.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Blueprint.Api.Migrations.PostgreSQL.Migrations +{ + [DbContext(typeof(BlueprintContext))] + [Migration("20240319164829_more-cascade-deletes")] + partial class morecascadedeletes + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "uuid-ossp"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Blueprint.Api.Data.Models.CardEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("GalleryId") + .HasColumnType("uuid") + .HasColumnName("gallery_id"); + + b.Property("Inject") + .HasColumnType("integer") + .HasColumnName("inject"); + + b.Property("IsTemplate") + .HasColumnType("boolean") + .HasColumnName("is_template"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("Move") + .HasColumnType("integer") + .HasColumnName("move"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.HasIndex("MselId"); + + b.ToTable("cards"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.CardTeamEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CanPostArticles") + .HasColumnType("boolean") + .HasColumnName("can_post_articles"); + + b.Property("CardId") + .HasColumnType("uuid") + .HasColumnName("card_id"); + + b.Property("IsShownOnWall") + .HasColumnType("boolean") + .HasColumnName("is_shown_on_wall"); + + b.Property("TeamId") + .HasColumnType("uuid") + .HasColumnName("team_id"); + + b.HasKey("Id"); + + b.HasIndex("CardId"); + + b.HasIndex("TeamId", "CardId") + .IsUnique(); + + b.ToTable("card_teams"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.CiteActionEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("ActionNumber") + .HasColumnType("integer") + .HasColumnName("action_number"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("InjectNumber") + .HasColumnType("integer") + .HasColumnName("inject_number"); + + b.Property("IsTemplate") + .HasColumnType("boolean") + .HasColumnName("is_template"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("MoveNumber") + .HasColumnType("integer") + .HasColumnName("move_number"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("TeamId") + .HasColumnType("uuid") + .HasColumnName("team_id"); + + b.HasKey("Id"); + + b.HasIndex("MselId"); + + b.HasIndex("TeamId"); + + b.ToTable("cite_actions"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.CiteRoleEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("IsTemplate") + .HasColumnType("boolean") + .HasColumnName("is_template"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("TeamId") + .HasColumnType("uuid") + .HasColumnName("team_id"); + + b.HasKey("Id"); + + b.HasIndex("MselId"); + + b.HasIndex("TeamId"); + + b.ToTable("cite_roles"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.DataFieldEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CellMetadata") + .HasColumnType("text") + .HasColumnName("cell_metadata"); + + b.Property("ColumnMetadata") + .HasColumnType("text") + .HasColumnName("column_metadata"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DataType") + .HasColumnType("integer") + .HasColumnName("data_type"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("DisplayOrder") + .HasColumnType("integer") + .HasColumnName("display_order"); + + b.Property("GalleryArticleParameter") + .HasColumnType("text") + .HasColumnName("gallery_article_parameter"); + + b.Property("IsChosenFromList") + .HasColumnType("boolean") + .HasColumnName("is_chosen_from_list"); + + b.Property("IsInitiallyHidden") + .HasColumnType("boolean") + .HasColumnName("is_initially_hidden"); + + b.Property("IsOnlyShownToOwners") + .HasColumnType("boolean") + .HasColumnName("is_only_shown_to_owners"); + + b.Property("IsTemplate") + .HasColumnType("boolean") + .HasColumnName("is_template"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("OnExerciseView") + .HasColumnType("boolean") + .HasColumnName("on_exercise_view"); + + b.Property("OnScenarioEventList") + .HasColumnType("boolean") + .HasColumnName("on_scenario_event_list"); + + b.HasKey("Id"); + + b.HasIndex("MselId"); + + b.ToTable("data_fields"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.DataOptionEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DataFieldId") + .HasColumnType("uuid") + .HasColumnName("data_field_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("DisplayOrder") + .HasColumnType("integer") + .HasColumnName("display_order"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("OptionName") + .HasColumnType("text") + .HasColumnName("option_name"); + + b.Property("OptionValue") + .HasColumnType("text") + .HasColumnName("option_value"); + + b.HasKey("Id"); + + b.HasIndex("DataFieldId"); + + b.ToTable("data_options"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.DataValueEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CellMetadata") + .HasColumnType("text") + .HasColumnName("cell_metadata"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DataFieldId") + .HasColumnType("uuid") + .HasColumnName("data_field_id"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("ScenarioEventId") + .HasColumnType("uuid") + .HasColumnName("scenario_event_id"); + + b.Property("Value") + .HasColumnType("text") + .HasColumnName("value"); + + b.HasKey("Id"); + + b.HasIndex("DataFieldId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("ScenarioEventId", "DataFieldId") + .IsUnique(); + + b.ToTable("data_values"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.InvitationEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("EmailDomain") + .HasColumnType("text") + .HasColumnName("email_domain"); + + b.Property("ExpirationDateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_date_time"); + + b.Property("IsTeamLeader") + .HasColumnType("boolean") + .HasColumnName("is_team_leader"); + + b.Property("MaxUsersAllowed") + .HasColumnType("integer") + .HasColumnName("max_users_allowed"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("TeamId") + .HasColumnType("uuid") + .HasColumnName("team_id"); + + b.Property("UserCount") + .HasColumnType("integer") + .HasColumnName("user_count"); + + b.Property("WasDeactivated") + .HasColumnType("boolean") + .HasColumnName("was_deactivated"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MselId"); + + b.HasIndex("TeamId"); + + b.ToTable("invitations"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.MoveEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("DeltaSeconds") + .HasColumnType("integer") + .HasColumnName("delta_seconds"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("MoveNumber") + .HasColumnType("integer") + .HasColumnName("move_number"); + + b.Property("MoveStartTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("move_start_time"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("SituationDescription") + .HasColumnType("text") + .HasColumnName("situation_description"); + + b.Property("SituationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("situation_time"); + + b.HasKey("Id"); + + b.HasIndex("MselId", "MoveNumber") + .IsUnique(); + + b.ToTable("moves"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.MselEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CiteEvaluationId") + .HasColumnType("uuid") + .HasColumnName("cite_evaluation_id"); + + b.Property("CiteIntegrationType") + .HasColumnType("integer") + .HasColumnName("cite_integration_type"); + + b.Property("CiteScoringModelId") + .HasColumnType("uuid") + .HasColumnName("cite_scoring_model_id"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("DurationSeconds") + .HasColumnType("integer") + .HasColumnName("duration_seconds"); + + b.Property("GalleryCollectionId") + .HasColumnType("uuid") + .HasColumnName("gallery_collection_id"); + + b.Property("GalleryExhibitId") + .HasColumnType("uuid") + .HasColumnName("gallery_exhibit_id"); + + b.Property("GalleryIntegrationType") + .HasColumnType("integer") + .HasColumnName("gallery_integration_type"); + + b.Property("HeaderRowMetadata") + .HasColumnType("text") + .HasColumnName("header_row_metadata"); + + b.Property("IsTemplate") + .HasColumnType("boolean") + .HasColumnName("is_template"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("PlayerIntegrationType") + .HasColumnType("integer") + .HasColumnName("player_integration_type"); + + b.Property("PlayerViewId") + .HasColumnType("uuid") + .HasColumnName("player_view_id"); + + b.Property("ShowGroupOnExerciseView") + .HasColumnType("boolean") + .HasColumnName("show_group_on_exercise_view"); + + b.Property("ShowGroupOnScenarioEventList") + .HasColumnType("boolean") + .HasColumnName("show_group_on_scenario_event_list"); + + b.Property("ShowMoveOnExerciseView") + .HasColumnType("boolean") + .HasColumnName("show_move_on_exercise_view"); + + b.Property("ShowMoveOnScenarioEventList") + .HasColumnType("boolean") + .HasColumnName("show_move_on_scenario_event_list"); + + b.Property("ShowTimeOnExerciseView") + .HasColumnType("boolean") + .HasColumnName("show_time_on_exercise_view"); + + b.Property("ShowTimeOnScenarioEventList") + .HasColumnType("boolean") + .HasColumnName("show_time_on_scenario_event_list"); + + b.Property("StartTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("start_time"); + + b.Property("Status") + .HasColumnType("integer") + .HasColumnName("status"); + + b.Property("SteamfitterIntegrationType") + .HasColumnType("integer") + .HasColumnName("steamfitter_integration_type"); + + b.Property("SteamfitterScenarioId") + .HasColumnType("uuid") + .HasColumnName("steamfitter_scenario_id"); + + b.Property("UseCite") + .HasColumnType("boolean") + .HasColumnName("use_cite"); + + b.Property("UseGallery") + .HasColumnType("boolean") + .HasColumnName("use_gallery"); + + b.Property("UsePlayer") + .HasColumnType("boolean") + .HasColumnName("use_player"); + + b.Property("UseSteamfitter") + .HasColumnType("boolean") + .HasColumnName("use_steamfitter"); + + b.HasKey("Id"); + + b.ToTable("msels"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.MselPageEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("AllCanView") + .HasColumnType("boolean") + .HasColumnName("all_can_view"); + + b.Property("Content") + .HasColumnType("text") + .HasColumnName("content"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MselId"); + + b.ToTable("msel_pages"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.MselTeamEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CiteTeamTypeId") + .HasColumnType("uuid") + .HasColumnName("cite_team_type_id"); + + b.Property("Email") + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("TeamId") + .HasColumnType("uuid") + .HasColumnName("team_id"); + + b.HasKey("Id"); + + b.HasIndex("MselId"); + + b.HasIndex("TeamId", "MselId") + .IsUnique(); + + b.ToTable("msel_teams"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.MselUnitEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("UnitId") + .HasColumnType("uuid") + .HasColumnName("unit_id"); + + b.HasKey("Id"); + + b.HasIndex("MselId"); + + b.HasIndex("UnitId", "MselId") + .IsUnique(); + + b.ToTable("msel_units"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.OrganizationEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Email") + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("IsTemplate") + .HasColumnType("boolean") + .HasColumnName("is_template"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("ShortName") + .HasColumnType("text") + .HasColumnName("short_name"); + + b.Property("Summary") + .HasColumnType("text") + .HasColumnName("summary"); + + b.HasKey("Id"); + + b.HasIndex("MselId"); + + b.ToTable("organizations"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.PermissionEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Description") + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Key") + .HasColumnType("text") + .HasColumnName("key"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("ReadOnly") + .HasColumnType("boolean") + .HasColumnName("read_only"); + + b.Property("Value") + .HasColumnType("text") + .HasColumnName("value"); + + b.HasKey("Id"); + + b.HasIndex("Key", "Value") + .IsUnique(); + + b.ToTable("permissions"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.PlayerApplicationEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Embeddable") + .HasColumnType("boolean") + .HasColumnName("embeddable"); + + b.Property("Icon") + .HasColumnType("text") + .HasColumnName("icon"); + + b.Property("LoadInBackground") + .HasColumnType("boolean") + .HasColumnName("load_in_background"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Url") + .HasColumnType("text") + .HasColumnName("url"); + + b.HasKey("Id"); + + b.HasIndex("MselId"); + + b.ToTable("player_applications"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.PlayerApplicationTeamEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("PlayerApplicationId") + .HasColumnType("uuid") + .HasColumnName("player_application_id"); + + b.Property("TeamId") + .HasColumnType("uuid") + .HasColumnName("team_id"); + + b.HasKey("Id"); + + b.HasIndex("PlayerApplicationId"); + + b.HasIndex("TeamId", "PlayerApplicationId") + .IsUnique(); + + b.ToTable("player_application_teams"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.ScenarioEventEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("DeltaSeconds") + .HasColumnType("integer") + .HasColumnName("delta_seconds"); + + b.Property("IsHidden") + .HasColumnType("boolean") + .HasColumnName("is_hidden"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("RowIndex") + .HasColumnType("integer") + .HasColumnName("row_index"); + + b.Property("RowMetadata") + .HasColumnType("text") + .HasColumnName("row_metadata"); + + b.HasKey("Id"); + + b.HasIndex("MselId"); + + b.ToTable("scenario_events"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.TeamEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CiteTeamId") + .HasColumnType("uuid") + .HasColumnName("cite_team_id"); + + b.Property("CiteTeamTypeId") + .HasColumnType("uuid") + .HasColumnName("cite_team_type_id"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("Email") + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("GalleryTeamId") + .HasColumnType("uuid") + .HasColumnName("gallery_team_id"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("OldTeamId") + .HasColumnType("uuid") + .HasColumnName("old_team_id"); + + b.Property("PlayerTeamId") + .HasColumnType("uuid") + .HasColumnName("player_team_id"); + + b.Property("ShortName") + .HasColumnType("text") + .HasColumnName("short_name"); + + b.Property("canTeamLeaderInvite") + .HasColumnType("boolean") + .HasColumnName("can_team_leader_invite"); + + b.Property("canTeamMemberInvite") + .HasColumnType("boolean") + .HasColumnName("can_team_member_invite"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MselId"); + + b.ToTable("teams"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.TeamUserEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("TeamId") + .HasColumnType("uuid") + .HasColumnName("team_id"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("TeamId"); + + b.HasIndex("UserId", "TeamId") + .IsUnique(); + + b.ToTable("team_users"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.UnitEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("OldTeamId") + .HasColumnType("uuid") + .HasColumnName("old_team_id"); + + b.Property("ShortName") + .HasColumnType("text") + .HasColumnName("short_name"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("units"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.UnitUserEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("UnitId") + .HasColumnType("uuid") + .HasColumnName("unit_id"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("UnitId"); + + b.HasIndex("UserId", "UnitId") + .IsUnique(); + + b.ToTable("unit_users"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.UserEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("users"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.UserMselRoleEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("MselId") + .HasColumnType("uuid") + .HasColumnName("msel_id"); + + b.Property("Role") + .HasColumnType("integer") + .HasColumnName("role"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("MselId", "UserId", "Role") + .IsUnique(); + + b.ToTable("user_msel_roles"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.UserPermissionEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("PermissionId") + .HasColumnType("uuid") + .HasColumnName("permission_id"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("PermissionId"); + + b.HasIndex("UserId", "PermissionId") + .IsUnique(); + + b.ToTable("user_permissions"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.UserTeamRoleEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id") + .HasDefaultValueSql("uuid_generate_v4()"); + + b.Property("CreatedBy") + .HasColumnType("uuid") + .HasColumnName("created_by"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_modified"); + + b.Property("ModifiedBy") + .HasColumnType("uuid") + .HasColumnName("modified_by"); + + b.Property("Role") + .HasColumnType("integer") + .HasColumnName("role"); + + b.Property("TeamId") + .HasColumnType("uuid") + .HasColumnName("team_id"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("TeamId", "UserId", "Role") + .IsUnique(); + + b.ToTable("user_team_roles"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.CardEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany("Cards") + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Msel"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.CardTeamEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.CardEntity", "Card") + .WithMany("CardTeams") + .HasForeignKey("CardId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blueprint.Api.Data.Models.TeamEntity", "Team") + .WithMany("CardTeams") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Card"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.CiteActionEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany("CiteActions") + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Blueprint.Api.Data.Models.TeamEntity", "Team") + .WithMany("CiteActions") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Msel"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.CiteRoleEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany("CiteRoles") + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Blueprint.Api.Data.Models.TeamEntity", "Team") + .WithMany("CiteRoles") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Msel"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.DataFieldEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany("DataFields") + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Msel"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.DataOptionEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.DataFieldEntity", "DataField") + .WithMany("DataOptions") + .HasForeignKey("DataFieldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DataField"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.DataValueEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.DataFieldEntity", "DataField") + .WithMany() + .HasForeignKey("DataFieldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blueprint.Api.Data.Models.ScenarioEventEntity", "ScenarioEvent") + .WithMany("DataValues") + .HasForeignKey("ScenarioEventId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DataField"); + + b.Navigation("ScenarioEvent"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.InvitationEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany("Invitations") + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blueprint.Api.Data.Models.TeamEntity", "Team") + .WithMany("Invitations") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Msel"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.MoveEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany("Moves") + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Msel"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.MselPageEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany("Pages") + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Msel"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.MselTeamEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany() + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blueprint.Api.Data.Models.TeamEntity", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Msel"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.MselUnitEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany("MselUnits") + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blueprint.Api.Data.Models.UnitEntity", "Unit") + .WithMany("MselUnits") + .HasForeignKey("UnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Msel"); + + b.Navigation("Unit"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.OrganizationEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany("Organizations") + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Msel"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.PlayerApplicationEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany("PlayerApplications") + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Msel"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.PlayerApplicationTeamEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.PlayerApplicationEntity", "PlayerApplication") + .WithMany("PlayerApplicationTeams") + .HasForeignKey("PlayerApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blueprint.Api.Data.Models.TeamEntity", "Team") + .WithMany("PlayerApplicationTeams") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlayerApplication"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.ScenarioEventEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany("ScenarioEvents") + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Msel"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.TeamEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany("Teams") + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Msel"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.TeamUserEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.TeamEntity", "Team") + .WithMany("TeamUsers") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blueprint.Api.Data.Models.UserEntity", "User") + .WithMany("TeamUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Team"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.UnitUserEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.UnitEntity", "Unit") + .WithMany("UnitUsers") + .HasForeignKey("UnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blueprint.Api.Data.Models.UserEntity", "User") + .WithMany("UnitUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Unit"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.UserMselRoleEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") + .WithMany("UserMselRoles") + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blueprint.Api.Data.Models.UserEntity", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Msel"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.UserPermissionEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.PermissionEntity", "Permission") + .WithMany("UserPermissions") + .HasForeignKey("PermissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blueprint.Api.Data.Models.UserEntity", "User") + .WithMany("UserPermissions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Permission"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.UserTeamRoleEntity", b => + { + b.HasOne("Blueprint.Api.Data.Models.TeamEntity", "Team") + .WithMany("UserTeamRoles") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Blueprint.Api.Data.Models.UserEntity", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Team"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.CardEntity", b => + { + b.Navigation("CardTeams"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.DataFieldEntity", b => + { + b.Navigation("DataOptions"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.MselEntity", b => + { + b.Navigation("Cards"); + + b.Navigation("CiteActions"); + + b.Navigation("CiteRoles"); + + b.Navigation("DataFields"); + + b.Navigation("Invitations"); + + b.Navigation("Moves"); + + b.Navigation("MselUnits"); + + b.Navigation("Organizations"); + + b.Navigation("Pages"); + + b.Navigation("PlayerApplications"); + + b.Navigation("ScenarioEvents"); + + b.Navigation("Teams"); + + b.Navigation("UserMselRoles"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.PermissionEntity", b => + { + b.Navigation("UserPermissions"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.PlayerApplicationEntity", b => + { + b.Navigation("PlayerApplicationTeams"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.ScenarioEventEntity", b => + { + b.Navigation("DataValues"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.TeamEntity", b => + { + b.Navigation("CardTeams"); + + b.Navigation("CiteActions"); + + b.Navigation("CiteRoles"); + + b.Navigation("Invitations"); + + b.Navigation("PlayerApplicationTeams"); + + b.Navigation("TeamUsers"); + + b.Navigation("UserTeamRoles"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.UnitEntity", b => + { + b.Navigation("MselUnits"); + + b.Navigation("UnitUsers"); + }); + + modelBuilder.Entity("Blueprint.Api.Data.Models.UserEntity", b => + { + b.Navigation("TeamUsers"); + + b.Navigation("UnitUsers"); + + b.Navigation("UserPermissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.cs b/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.cs new file mode 100644 index 0000000..714dc0c --- /dev/null +++ b/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.cs @@ -0,0 +1,84 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Blueprint.Api.Migrations.PostgreSQL.Migrations +{ + public partial class morecascadedeletes : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_cite_actions_teams_team_id", + table: "cite_actions"); + + migrationBuilder.DropForeignKey( + name: "FK_cite_roles_teams_team_id", + table: "cite_roles"); + + migrationBuilder.DropForeignKey( + name: "FK_teams_msels_msel_id", + table: "teams"); + + migrationBuilder.AddForeignKey( + name: "FK_cite_actions_teams_team_id", + table: "cite_actions", + column: "team_id", + principalTable: "teams", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_cite_roles_teams_team_id", + table: "cite_roles", + column: "team_id", + principalTable: "teams", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_teams_msels_msel_id", + table: "teams", + column: "msel_id", + principalTable: "msels", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_cite_actions_teams_team_id", + table: "cite_actions"); + + migrationBuilder.DropForeignKey( + name: "FK_cite_roles_teams_team_id", + table: "cite_roles"); + + migrationBuilder.DropForeignKey( + name: "FK_teams_msels_msel_id", + table: "teams"); + + migrationBuilder.AddForeignKey( + name: "FK_cite_actions_teams_team_id", + table: "cite_actions", + column: "team_id", + principalTable: "teams", + principalColumn: "id"); + + migrationBuilder.AddForeignKey( + name: "FK_cite_roles_teams_team_id", + table: "cite_roles", + column: "team_id", + principalTable: "teams", + principalColumn: "id"); + + migrationBuilder.AddForeignKey( + name: "FK_teams_msels_msel_id", + table: "teams", + column: "msel_id", + principalTable: "msels", + principalColumn: "id"); + } + } +} diff --git a/Blueprint.Api.Migrations.PostgreSQL/Migrations/BlueprintContextModelSnapshot.cs b/Blueprint.Api.Migrations.PostgreSQL/Migrations/BlueprintContextModelSnapshot.cs index 4813f31..1889df4 100644 --- a/Blueprint.Api.Migrations.PostgreSQL/Migrations/BlueprintContextModelSnapshot.cs +++ b/Blueprint.Api.Migrations.PostgreSQL/Migrations/BlueprintContextModelSnapshot.cs @@ -1,8 +1,3 @@ -/* - Copyright 2024 Carnegie Mellon University. All Rights Reserved. - Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information. -*/ - // using System; using Blueprint.Api.Data; @@ -1361,8 +1356,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .OnDelete(DeleteBehavior.Cascade); b.HasOne("Blueprint.Api.Data.Models.TeamEntity", "Team") - .WithMany() - .HasForeignKey("TeamId"); + .WithMany("CiteActions") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade); b.Navigation("Msel"); @@ -1377,8 +1373,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .OnDelete(DeleteBehavior.Cascade); b.HasOne("Blueprint.Api.Data.Models.TeamEntity", "Team") - .WithMany() - .HasForeignKey("TeamId"); + .WithMany("CiteRoles") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade); b.Navigation("Msel"); @@ -1559,7 +1556,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.HasOne("Blueprint.Api.Data.Models.MselEntity", "Msel") .WithMany("Teams") - .HasForeignKey("MselId"); + .HasForeignKey("MselId") + .OnDelete(DeleteBehavior.Cascade); b.Navigation("Msel"); }); @@ -1717,6 +1715,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Navigation("CardTeams"); + b.Navigation("CiteActions"); + + b.Navigation("CiteRoles"); + b.Navigation("Invitations"); b.Navigation("PlayerApplicationTeams"); diff --git a/Blueprint.Api/Blueprint.Api.csproj b/Blueprint.Api/Blueprint.Api.csproj index 169aa8a..68623f9 100755 --- a/Blueprint.Api/Blueprint.Api.csproj +++ b/Blueprint.Api/Blueprint.Api.csproj @@ -1,7 +1,7 @@  - 1.0.0-rc1 + 1.0.0-rc2 net6.0 bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml CS1591 diff --git a/Blueprint.Api/Services/MselService.cs b/Blueprint.Api/Services/MselService.cs index 060796b..45e1e8e 100755 --- a/Blueprint.Api/Services/MselService.cs +++ b/Blueprint.Api/Services/MselService.cs @@ -257,6 +257,7 @@ public MselService( private async Task privateMselCopyAsync(Guid mselId, Guid? currentUserTeamId, CancellationToken ct) { + var currentUserId = _user.GetId(); var username = (await _context.Users.SingleOrDefaultAsync(u => u.Id == _user.GetId())).Name; var mselEntity = await _context.Msels .AsNoTracking() @@ -264,9 +265,11 @@ private async Task privateMselCopyAsync(Guid mselId, Guid? currentUs .ThenInclude(df => df.DataOptions) .Include(m => m.ScenarioEvents) .ThenInclude(se => se.DataValues) + .Include(m => m.MselUnits) .Include(m => m.Teams) .ThenInclude(t => t.TeamUsers) - .ThenInclude(tu => tu.User) + .Include(m => m.Teams) + .ThenInclude(t => t.UserTeamRoles) .Include(m => m.UserMselRoles) .Include(m => m.Moves) .Include(m => m.Organizations) @@ -280,7 +283,7 @@ private async Task privateMselCopyAsync(Guid mselId, Guid? currentUs mselEntity.Id = Guid.NewGuid(); mselEntity.DateCreated = DateTime.UtcNow; - mselEntity.CreatedBy = _user.GetId(); + mselEntity.CreatedBy = currentUserId; mselEntity.DateModified = mselEntity.DateCreated; mselEntity.ModifiedBy = mselEntity.CreatedBy; mselEntity.Name = mselEntity.Name + " - " + username; @@ -318,14 +321,45 @@ private async Task privateMselCopyAsync(Guid mselId, Guid? currentUs move.DateCreated = mselEntity.DateCreated; move.CreatedBy = mselEntity.CreatedBy; } + // copy MselUnits + foreach (var mselUnit in mselEntity.MselUnits) + { + mselUnit.Id = Guid.NewGuid(); + mselUnit.MselId = mselEntity.Id; + mselUnit.Msel = null; + } // copy Teams foreach (var team in mselEntity.Teams) { + team.Id = Guid.NewGuid(); + team.MselId = mselEntity.Id; + team.Msel = null; + team.DateCreated = mselEntity.DateCreated; + team.CreatedBy = mselEntity.CreatedBy; + team.DateModified = mselEntity.DateModified; + team.ModifiedBy = mselEntity.ModifiedBy; var addUser = team.Id == currentUserTeamId; + // copy TeamUsers + foreach(var teamUser in team.TeamUsers) + { + addUser = addUser && teamUser.UserId != currentUserId; + teamUser.Id = Guid.NewGuid(); + teamUser.TeamId = team.Id; + teamUser.Team = null; + teamUser.User = null; + } // add current user to the indicated team if (addUser) { - team.TeamUsers.Add(new TeamUserEntity{TeamId = team.Id, UserId = _user.GetId()}); + team.TeamUsers.Add(new TeamUserEntity{TeamId = team.Id, UserId = currentUserId}); + } + // copy TeamUserRoles + foreach(var userTeamRole in team.UserTeamRoles) + { + userTeamRole.Id = Guid.NewGuid(); + userTeamRole.TeamId = team.Id; + userTeamRole.Team = null; + userTeamRole.User = null; } } // copy Organizations @@ -1669,42 +1703,64 @@ private async Task FindDuplicateMselUsersAsync(Guid mselId, Cancellation public async Task> GetMyJoinInvitationMselsAsync(CancellationToken ct) { - var myMsels = (IQueryable)_context.Msels; - var myDeployedMselIds = await GetMyDeployedMselIdsAsync(ct); - // get the IDs for MSELs where user has an invitation - var currentDateTime = DateTime.UtcNow; - var userEmail = _user.Claims.SingleOrDefault(c => c.Type == "Email").Value; - var inviteMselIds = await _context.Invitations + var userId = _user.GetId(); + if (!(await _authorizationService.AuthorizeAsync(_user, null, new BaseUserRequirement())).Succeeded) + throw new ForbiddenException(); + + // get the user's teams + var teamIdList = await _context.TeamUsers + .Where(tu => tu.UserId == userId) + .Select(tu => tu.TeamId) + .ToListAsync(ct); + // get the teams' deployed msels + var teamMselList = await _context.MselTeams + .Where(mt => + mt.Msel.PlayerViewId != null && + mt.Msel.Status == ItemStatus.Deployed && + teamIdList.Contains(mt.TeamId) + ) + .Select(mt => mt.Msel) + .ToListAsync(ct); + // get deployed msels with an invitation + var email = _user.Claims.First(c => c.Type == "Email")?.Value; + var now = DateTime.Now; + var inviteMselList = await _context.Invitations .Where(i => !i.WasDeactivated && - i.ExpirationDateTime < currentDateTime && - userEmail.EndsWith(i.EmailDomain) - ) - .Select(i => i.MselId) + i.ExpirationDateTime > now && + i.UserCount < i.MaxUsersAllowed && + i.EmailDomain.Contains('@') && + email.EndsWith(i.EmailDomain) && + i.Msel.Status == ItemStatus.Deployed) + .Select(i => i.Msel) .ToListAsync(ct); - // get the actual MSELs - myMsels = myMsels - .Where(m => - (m.Status == ItemStatus.Deployed && inviteMselIds.Contains(m.Id)) || - myDeployedMselIds.Contains(m.Id) - ); - return _mapper.Map>(await myMsels.ToListAsync(ct));; + // combine lists + var mselList = teamMselList.Union(inviteMselList).OrderByDescending(m => m.DateCreated); + + return _mapper.Map>(mselList); } public async Task> GetMyLaunchInvitationMselsAsync(CancellationToken ct) { - // get the launchable MSELs where user has an invitation - var currentDateTime = DateTime.UtcNow; - var userEmail = _user.Claims.SingleOrDefault(c => c.Type == "Email").Value; - var myMsels = _context.Invitations + var userId = _user.GetId(); + if (!(await _authorizationService.AuthorizeAsync(_user, null, new BaseUserRequirement())).Succeeded) + throw new ForbiddenException(); + + // get template msels with an invitation + var email = _user.Claims.First(c => c.Type == "Email")?.Value; + var now = DateTime.UtcNow; + var mselList = await _context.Invitations .Where(i => !i.WasDeactivated && - i.ExpirationDateTime < currentDateTime && - userEmail.EndsWith(i.EmailDomain) && - i.Msel.IsTemplate - ) - .Select(i => i.Msel); - return _mapper.Map>(await myMsels.ToListAsync(ct));; + i.ExpirationDateTime > now && + i.UserCount < i.MaxUsersAllowed && + i.EmailDomain.Contains('@') && + email.EndsWith(i.EmailDomain) && + i.Msel.IsTemplate) + .Select(i => i.Msel) + .ToListAsync(ct); + + return _mapper.Map>(mselList); } /// From 2f77a1955117360c482a94f27f3befbc24f58981 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 17:31:35 +0000 Subject: [PATCH 2/2] Add missing document markings --- .../20240319164829_more-cascade-deletes.Designer.cs | 5 +++++ .../Migrations/20240319164829_more-cascade-deletes.cs | 5 +++++ .../Migrations/BlueprintContextModelSnapshot.cs | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.Designer.cs b/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.Designer.cs index e15b099..7b23b90 100644 --- a/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.Designer.cs +++ b/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.Designer.cs @@ -1,3 +1,8 @@ +/* + Copyright 2024 Carnegie Mellon University. All Rights Reserved. + Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information. +*/ + // using System; using Blueprint.Api.Data; diff --git a/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.cs b/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.cs index 714dc0c..7e0561a 100644 --- a/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.cs +++ b/Blueprint.Api.Migrations.PostgreSQL/Migrations/20240319164829_more-cascade-deletes.cs @@ -1,3 +1,8 @@ +/* + Copyright 2024 Carnegie Mellon University. All Rights Reserved. + Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information. +*/ + using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/Blueprint.Api.Migrations.PostgreSQL/Migrations/BlueprintContextModelSnapshot.cs b/Blueprint.Api.Migrations.PostgreSQL/Migrations/BlueprintContextModelSnapshot.cs index 1889df4..4186cf3 100644 --- a/Blueprint.Api.Migrations.PostgreSQL/Migrations/BlueprintContextModelSnapshot.cs +++ b/Blueprint.Api.Migrations.PostgreSQL/Migrations/BlueprintContextModelSnapshot.cs @@ -1,3 +1,8 @@ +/* + Copyright 2024 Carnegie Mellon University. All Rights Reserved. + Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information. +*/ + // using System; using Blueprint.Api.Data;