From b2a86227c2fd2f494ed5f70c91f9f54ac7ab7724 Mon Sep 17 00:00:00 2001 From: "SHAKIR, Muhammad" Date: Mon, 16 Sep 2024 12:19:29 +0100 Subject: [PATCH] Assign user with role capabilities --- .../AcademisationContext.cs | 18 +- ...0913151403_Remove-UserRole-Tbl.Designer.cs | 2304 +++++++++++++++++ .../20240913151403_Remove-UserRole-Tbl.cs | 42 + .../AcademisationContextModelSnapshot.cs | 60 +- .../Repositories/UserRoleRepository.cs | 69 - .../RoleCapability.cs | 11 + .../RoleCapabilitiesAggregate/RoleId.cs | 14 + .../RoleCapabilitiesAggregate/RoleInfo.cs | 43 + .../UserRoleAggregate/RoleCapability.cs | 41 - .../UserRoleAggregate/RoleId.cs | 14 - .../UserRoleAggregate/RoleInfo.cs | 23 - .../UserRoleAggregate/IUserRoleRepository.cs | 13 - .../UserRoleAggregate/UserRole.cs | 32 - .../UserRoleAggregate/IUserRole.cs | 15 - .../Query/IRoleCapabilitiesQueryService.cs | 9 + .../Query/IUserRoleQueryService.cs | 13 - .../RoleCapabilitiesModel.cs | 4 +- .../ServiceModels/UserRole/UserRoleModel.cs | 11 - .../UserRole/UserRoleSearchModel.cs | 12 - .../CreateUserRoleCommandValidator.cs | 27 - .../UserRole/SetUserRoleCommandValidator.cs | 19 - .../UserRole/CreateUserRoleCommand.cs | 15 - .../UserRole/CreateUserRoleCommandHandler.cs | 25 - .../Commands/UserRole/SetUserRoleCommand.cs | 13 - .../UserRole/SetUserRoleCommandHandler.cs | 29 - .../Queries/RoleCapabilitiesQueryService.cs | 16 + .../Queries/UserRoleQueryService.cs | 27 - .../ApiIntegrationTestBase.cs | 6 +- .../RoleCapabilities/RoleCapabilitiesTests.cs | 49 + .../UserRole/UserRoleTests.cs | 216 -- .../Utils/HttpResponseMessageExtensions.cs | 3 - .../Controllers/ProjectGroupController.cs | 6 +- .../Controllers/RoleCapabilitiesController.cs | 28 + .../Controllers/UserRoleController.cs | 74 - Dfe.Academies.Academisation.WebApi/Program.cs | 21 +- .../appsettings.json | 6 +- 36 files changed, 2532 insertions(+), 796 deletions(-) create mode 100644 Dfe.Academies.Academisation.Data/Migrations/20240913151403_Remove-UserRole-Tbl.Designer.cs create mode 100644 Dfe.Academies.Academisation.Data/Migrations/20240913151403_Remove-UserRole-Tbl.cs delete mode 100644 Dfe.Academies.Academisation.Data/Repositories/UserRoleRepository.cs create mode 100644 Dfe.Academies.Academisation.Domain.Core/RoleCapabilitiesAggregate/RoleCapability.cs create mode 100644 Dfe.Academies.Academisation.Domain.Core/RoleCapabilitiesAggregate/RoleId.cs create mode 100644 Dfe.Academies.Academisation.Domain.Core/RoleCapabilitiesAggregate/RoleInfo.cs delete mode 100644 Dfe.Academies.Academisation.Domain.Core/UserRoleAggregate/RoleCapability.cs delete mode 100644 Dfe.Academies.Academisation.Domain.Core/UserRoleAggregate/RoleId.cs delete mode 100644 Dfe.Academies.Academisation.Domain.Core/UserRoleAggregate/RoleInfo.cs delete mode 100644 Dfe.Academies.Academisation.Domain/UserRoleAggregate/IUserRoleRepository.cs delete mode 100644 Dfe.Academies.Academisation.Domain/UserRoleAggregate/UserRole.cs delete mode 100644 Dfe.Academies.Academisation.IDomain/UserRoleAggregate/IUserRole.cs create mode 100644 Dfe.Academies.Academisation.IService/Query/IRoleCapabilitiesQueryService.cs delete mode 100644 Dfe.Academies.Academisation.IService/Query/IUserRoleQueryService.cs rename Dfe.Academies.Academisation.IService/ServiceModels/{UserRole => RoleCapabilities}/RoleCapabilitiesModel.cs (50%) delete mode 100644 Dfe.Academies.Academisation.IService/ServiceModels/UserRole/UserRoleModel.cs delete mode 100644 Dfe.Academies.Academisation.IService/ServiceModels/UserRole/UserRoleSearchModel.cs delete mode 100644 Dfe.Academies.Academisation.Service/CommandValidations/UserRole/CreateUserRoleCommandValidator.cs delete mode 100644 Dfe.Academies.Academisation.Service/CommandValidations/UserRole/SetUserRoleCommandValidator.cs delete mode 100644 Dfe.Academies.Academisation.Service/Commands/UserRole/CreateUserRoleCommand.cs delete mode 100644 Dfe.Academies.Academisation.Service/Commands/UserRole/CreateUserRoleCommandHandler.cs delete mode 100644 Dfe.Academies.Academisation.Service/Commands/UserRole/SetUserRoleCommand.cs delete mode 100644 Dfe.Academies.Academisation.Service/Commands/UserRole/SetUserRoleCommandHandler.cs create mode 100644 Dfe.Academies.Academisation.Service/Queries/RoleCapabilitiesQueryService.cs delete mode 100644 Dfe.Academies.Academisation.Service/Queries/UserRoleQueryService.cs create mode 100644 Dfe.Academies.Academisation.SubcutaneousTest/RoleCapabilities/RoleCapabilitiesTests.cs delete mode 100644 Dfe.Academies.Academisation.SubcutaneousTest/UserRole/UserRoleTests.cs create mode 100644 Dfe.Academies.Academisation.WebApi/Controllers/RoleCapabilitiesController.cs delete mode 100644 Dfe.Academies.Academisation.WebApi/Controllers/UserRoleController.cs diff --git a/Dfe.Academies.Academisation.Data/AcademisationContext.cs b/Dfe.Academies.Academisation.Data/AcademisationContext.cs index 07895d65a..2ab574345 100644 --- a/Dfe.Academies.Academisation.Data/AcademisationContext.cs +++ b/Dfe.Academies.Academisation.Data/AcademisationContext.cs @@ -12,8 +12,7 @@ using Dfe.Academies.Academisation.Domain.ProjectAggregate; using Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate; using Dfe.Academies.Academisation.Domain.SeedWork; -using Dfe.Academies.Academisation.Domain.TransferProjectAggregate; -using Dfe.Academies.Academisation.Domain.UserRoleAggregate; +using Dfe.Academies.Academisation.Domain.TransferProjectAggregate; using MediatR; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; @@ -55,7 +54,6 @@ public class AcademisationContext(DbContextOptions options public DbSet TransferProjects { get; set; } = null!; public DbSet ProjectGroups { get; set; } = null!; - public DbSet UserRoles { get; set; } = null!; public override int SaveChanges() { @@ -239,7 +237,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(ConfigureFormAMatProject); modelBuilder.Entity(ConfigureProjectGroup); - modelBuilder.Entity(ConfigureUserRole); modelBuilder.Entity(ConfigureOpeningDateHistory); // Replicatiing functionality to generate urn, this will have to be ofset as part of the migration when we go live @@ -263,19 +260,6 @@ private void ConfigureProjectGroup(EntityTypeBuilder builder) }); } - private static void ConfigureUserRole(EntityTypeBuilder builder) - { - builder.ToTable("UserRoles", DEFAULT_SCHEMA); - builder.HasKey(e => e.Id); - - builder.OwnsOne(a => a.AssignedUser, a => - { - a.Property(p => p.Id).HasColumnName(Assigned_User_Id); - a.Property(p => p.EmailAddress).HasColumnName(Assigned_User_Email_Address); - a.Property(p => p.FullName).HasColumnName(Assigned_User_Full_Name); - }); - } - private void ConfigureOpeningDateHistory(EntityTypeBuilder builder) { builder.ToTable("OpeningDateHistories", DEFAULT_SCHEMA); diff --git a/Dfe.Academies.Academisation.Data/Migrations/20240913151403_Remove-UserRole-Tbl.Designer.cs b/Dfe.Academies.Academisation.Data/Migrations/20240913151403_Remove-UserRole-Tbl.Designer.cs new file mode 100644 index 000000000..449ba7d65 --- /dev/null +++ b/Dfe.Academies.Academisation.Data/Migrations/20240913151403_Remove-UserRole-Tbl.Designer.cs @@ -0,0 +1,2304 @@ +// +using System; +using Dfe.Academies.Academisation.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Dfe.Academies.Academisation.Data.Migrations +{ + [DbContext(typeof(AcademisationContext))] + [Migration("20240913151403_Remove-UserRole-Tbl")] + partial class RemoveUserRoleTbl + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationReference") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("nvarchar(max)") + .HasComputedColumnSql("'A2B_' + CAST([Id] AS NVARCHAR(255))", true); + + b.Property("ApplicationStatus") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ApplicationSubmittedDate") + .HasColumnType("datetime2"); + + b.Property("ApplicationType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DynamicsApplicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("FormTrustId") + .HasColumnType("int"); + + b.Property("JoinTrustId") + .HasColumnType("int"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("FormTrustId") + .IsUnique() + .HasFilter("[FormTrustId] IS NOT NULL"); + + b.HasIndex("JoinTrustId") + .IsUnique() + .HasFilter("[JoinTrustId] IS NOT NULL"); + + b.ToTable("ConversionApplication", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Contributor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConversionApplicationId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsApplicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("ConversionApplicationId"); + + b.ToTable("ConversionApplicationContributor", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.Lease", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationSchoolId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsSchoolLeaseId") + .HasColumnType("uniqueidentifier"); + + b.Property("InterestRate") + .HasColumnType("decimal(18,2)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("LeaseTerm") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentsToDate") + .HasColumnType("decimal(18,2)"); + + b.Property("Purpose") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("RepaymentAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("ResponsibleForAssets") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ValueOfAssets") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationSchoolId"); + + b.ToTable("ApplicationSchoolLease", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.Loan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Amount") + .HasColumnType("decimal(18,2)"); + + b.Property("ApplicationSchoolId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsSchoolLoanId") + .HasColumnType("uniqueidentifier"); + + b.Property("InterestRate") + .HasColumnType("decimal(18,2)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Purpose") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Schedule") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationSchoolId"); + + b.ToTable("ApplicationSchoolLoan", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConversionApplicationId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DioceseFolderIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("DioceseName") + .HasColumnType("nvarchar(max)"); + + b.Property("DynamicsApplyingSchoolId") + .HasColumnType("uniqueidentifier"); + + b.Property("ExemptionEndDate") + .HasColumnType("datetimeoffset"); + + b.Property("FoundationConsentFolderIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("FoundationTrustOrBodyName") + .HasColumnType("nvarchar(max)"); + + b.Property("FurtherInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("HasLeases") + .HasColumnType("bit"); + + b.Property("HasLoans") + .HasColumnType("bit"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("LocalAuthorityClosurePlanDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("LocalAuthorityReorganisationDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("MainFeederSchools") + .HasColumnType("nvarchar(max)"); + + b.Property("OfstedInspectionDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("PartOfFederation") + .HasColumnType("bit"); + + b.Property("ProtectedCharacteristics") + .HasColumnType("int"); + + b.Property("ResolutionConsentFolderIdentifier") + .HasColumnType("nvarchar(max)"); + + b.Property("Safeguarding") + .HasColumnType("bit"); + + b.Property("TrustBenefitDetails") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ConversionApplicationId"); + + b.ToTable("ApplicationSchool", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsApplicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("ApplicationFormTrust", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.JoinTrust", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChangesToLaGovernance") + .HasColumnType("bit"); + + b.Property("ChangesToLaGovernanceExplained") + .HasColumnType("nvarchar(max)"); + + b.Property("ChangesToTrust") + .HasColumnType("int"); + + b.Property("ChangesToTrustExplained") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DynamicsApplicationId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("TrustName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TrustReference") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UKPRN") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ApplicationJoinTrust", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPerson", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationFormTrustId") + .HasColumnType("int"); + + b.Property("Biography") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DateOfBirth") + .HasColumnType("datetime2"); + + b.Property("DynamicsKeyPersonId") + .HasColumnType("uniqueidentifier"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationFormTrustId"); + + b.ToTable("ApplicationFormTrustKeyPerson", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPersonRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationFormTrustKeyPersonRoleId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Role") + .HasColumnType("int"); + + b.Property("TimeInRole") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationFormTrustKeyPersonRoleId"); + + b.ToTable("ApplicationFormTrustKeyPersonRole", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("ConversionAdvisoryBoardDecision", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDAORevokedReasonDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AdvisoryBoardDecisionId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("Details") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AdvisoryBoardDecisionId"); + + b.ToTable("AdvisoryBoardDecisionDAORevokedReason", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDeclinedReasonDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AdvisoryBoardDecisionId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("Details") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AdvisoryBoardDecisionId"); + + b.ToTable("ConversionAdvisoryBoardDecisionDeclinedReason", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDeferredReasonDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AdvisoryBoardDecisionId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("Details") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AdvisoryBoardDecisionId"); + + b.ToTable("ConversionAdvisoryBoardDecisionDeferredReason", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardWithdrawnReasonDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AdvisoryBoardDecisionId") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("Details") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AdvisoryBoardDecisionId"); + + b.ToTable("AdvisoryBoardDecisionWithdrawnReason", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.ProjectNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Author") + .HasColumnType("nvarchar(max)"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("Note") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("Subject") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectNotes", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.FormAMatProjectAggregate.FormAMatProject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationReference") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("ProposedTrustName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ReferenceNumber") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("FormAMatProject", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.OpeningDateHistoryAggregate.OpeningDateHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChangedAt") + .HasColumnType("datetime2"); + + b.Property("ChangedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("EntityId") + .HasColumnType("int"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("NewDate") + .HasColumnType("datetime2"); + + b.Property("OldDate") + .HasColumnType("datetime2"); + + b.Property("ReasonsChanged") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("OpeningDateHistories", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ApplicationSharePointId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedOn") + .HasColumnType("datetime2") + .HasColumnName("CreatedOn"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("FormAMatProjectId") + .HasColumnType("int") + .HasColumnName("FormAMatProjectId"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("ProjectGroupId") + .HasColumnType("int"); + + b.Property("SchoolSharePointId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("Project", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.SchoolImprovementPlan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ArrangedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ArrangedByOther") + .HasColumnType("nvarchar(max)"); + + b.Property("ConfidenceLevel") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("ExpectedEndDate") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ExpectedEndDateOther") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("PlanComments") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("ProvidedBy") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("SchoolImprovementPlans", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate.ProjectGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("ReferenceNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("TrustName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TrustReference") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TrustUkprn") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("ProjectGroups", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.IntendedTransferBenefit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("SelectedBenefit") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TransferProjectId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TransferProjectId"); + + b.ToTable("IntendedTransferBenefit", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferProject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 10003000L); + + b.Property("AnyRisks") + .HasColumnType("bit"); + + b.Property("AssignedUserEmailAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("AssignedUserFullName") + .HasColumnType("nvarchar(max)"); + + b.Property("AssignedUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Author") + .HasColumnType("nvarchar(max)"); + + b.Property("BenefitsSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("ComplexLandAndBuildingFurtherSpecification") + .HasColumnType("nvarchar(max)"); + + b.Property("ComplexLandAndBuildingShouldBeConsidered") + .HasColumnType("bit"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DiocesanConsent") + .HasColumnType("nvarchar(max)"); + + b.Property("EqualitiesImpactAssessmentConsidered") + .HasColumnType("bit"); + + b.Property("FeatureSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("FinanceAndDebtFurtherSpecification") + .HasColumnType("nvarchar(max)"); + + b.Property("FinanceAndDebtShouldBeConsidered") + .HasColumnType("bit"); + + b.Property("HasHtbDate") + .HasColumnType("bit"); + + b.Property("HasTargetDateForTransfer") + .HasColumnType("bit"); + + b.Property("HasTransferFirstDiscussedDate") + .HasColumnType("bit"); + + b.Property("HighProfileFurtherSpecification") + .HasColumnType("nvarchar(max)"); + + b.Property("HighProfileShouldBeConsidered") + .HasColumnType("bit"); + + b.Property("HtbDate") + .HasColumnType("datetime2"); + + b.Property("IncomingTrustAgreement") + .HasColumnType("nvarchar(max)"); + + b.Property("IsFormAMat") + .HasColumnType("bit"); + + b.Property("LastModifiedOn") + .HasColumnType("datetime2"); + + b.Property("LegalRequirementsSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("OtherBenefitValue") + .HasColumnType("nvarchar(max)"); + + b.Property("OtherRisksFurtherSpecification") + .HasMaxLength(20000) + .HasColumnType("nvarchar(max)"); + + b.Property("OtherRisksShouldBeConsidered") + .HasColumnType("bit"); + + b.Property("OtherTransferTypeDescription") + .HasColumnType("nvarchar(max)"); + + b.Property("OutgoingTrustConsent") + .HasColumnType("nvarchar(max)"); + + b.Property("OutgoingTrustName") + .HasColumnType("nvarchar(max)"); + + b.Property("OutgoingTrustUkprn") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PreviousAdvisoryBoardDate") + .HasColumnType("datetime2"); + + b.Property("ProjectGroupId") + .HasColumnType("int"); + + b.Property("ProjectRationale") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectReference") + .HasColumnType("nvarchar(max)"); + + b.Property("RationaleSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("RddOrEsfaIntervention") + .HasColumnType("bit"); + + b.Property("RddOrEsfaInterventionDetail") + .HasColumnType("nvarchar(max)"); + + b.Property("Recommendation") + .HasColumnType("nvarchar(max)"); + + b.Property("SpecificReasonsForTransfer") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("State") + .HasColumnType("nvarchar(max)"); + + b.Property("Status") + .HasColumnType("nvarchar(max)"); + + b.Property("TargetDateForTransfer") + .HasColumnType("datetime2"); + + b.Property("TransferDatesSectionIsCompleted") + .HasColumnType("bit"); + + b.Property("TransferFirstDiscussed") + .HasColumnType("datetime2"); + + b.Property("TrustSponsorRationale") + .HasColumnType("nvarchar(max)"); + + b.Property("TypeOfTransfer") + .HasColumnType("nvarchar(max)"); + + b.Property("Urn") + .HasColumnType("int"); + + b.Property("WhoInitiatedTheTransfer") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("TransferProject", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferringAcademy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DistanceFromAcademyToTrustHq") + .HasColumnType("nvarchar(max)"); + + b.Property("DistanceFromAcademyToTrustHqDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("FinancialDeficit") + .HasColumnType("nvarchar(max)"); + + b.Property("IncomingTrustName") + .HasColumnType("nvarchar(max)"); + + b.Property("IncomingTrustUkprn") + .HasColumnType("nvarchar(max)"); + + b.Property("KeyStage2PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("KeyStage4PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("KeyStage5PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("LatestOfstedReportAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("LocalAuthority") + .HasColumnType("nvarchar(max)"); + + b.Property("MPNameAndParty") + .HasColumnType("nvarchar(max)"); + + b.Property("OutgoingAcademyUkprn") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PFIScheme") + .HasColumnType("nvarchar(max)"); + + b.Property("PFISchemeDetails") + .HasColumnType("nvarchar(max)"); + + b.Property("PublishedAdmissionNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PupilNumbersAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("Region") + .HasColumnType("nvarchar(max)"); + + b.Property("TransferProjectId") + .HasColumnType("int"); + + b.Property("ViabilityIssues") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("TransferProjectId"); + + b.ToTable("TransferringAcademy", "academisation"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", "FormTrust") + .WithOne() + .HasForeignKey("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", "FormTrustId"); + + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.JoinTrust", "JoinTrust") + .WithOne() + .HasForeignKey("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", "JoinTrustId"); + + b.Navigation("FormTrust"); + + b.Navigation("JoinTrust"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Contributor", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", null) + .WithMany("Contributors") + .HasForeignKey("ConversionApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.ContributorDetails", "Details", b1 => + { + b1.Property("ContributorId") + .HasColumnType("int"); + + b1.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("EmailAddress"); + + b1.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("FirstName"); + + b1.Property("LastName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("LastName"); + + b1.Property("OtherRoleName") + .HasColumnType("nvarchar(max)") + .HasColumnName("OtherRoleName"); + + b1.Property("Role") + .HasColumnType("int") + .HasColumnName("Role"); + + b1.HasKey("ContributorId"); + + b1.ToTable("ConversionApplicationContributor", "academisation"); + + b1.WithOwner() + .HasForeignKey("ContributorId"); + }); + + b.Navigation("Details") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.Lease", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", null) + .WithMany("Leases") + .HasForeignKey("ApplicationSchoolId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.Loan", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", null) + .WithMany("Loans") + .HasForeignKey("ApplicationSchoolId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", null) + .WithMany("Schools") + .HasForeignKey("ConversionApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.SchoolDetails", "Details", b1 => + { + b1.Property("SchoolId") + .HasColumnType("int"); + + b1.Property("ApplicationJoinTrustReason") + .HasColumnType("nvarchar(max)") + .HasColumnName("JoinTrustReason"); + + b1.Property("ApproverContactEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("ApproverContactEmail"); + + b1.Property("ApproverContactName") + .HasColumnType("nvarchar(max)") + .HasColumnName("ApproverContactName"); + + b1.Property("CapacityAssumptions") + .HasColumnType("nvarchar(max)") + .HasColumnName("CapacityAssumptions"); + + b1.Property("CapacityPublishedAdmissionsNumber") + .HasColumnType("int") + .HasColumnName("CapacityPublishedAdmissionsNumber"); + + b1.Property("ConfirmPaySupportGrantToSchool") + .HasColumnType("bit") + .HasColumnName("ConfirmPaySupportGrantToSchool"); + + b1.Property("ContactChairEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactChairEmail"); + + b1.Property("ContactChairName") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactChairName"); + + b1.Property("ContactHeadEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactHeadEmail"); + + b1.Property("ContactHeadName") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactHeadName"); + + b1.Property("ContactRole") + .HasColumnType("nvarchar(max)") + .HasColumnName("ContactRole"); + + b1.Property("ConversionChangeNamePlanned") + .HasColumnType("bit") + .HasColumnName("ConversionChangeNamePlanned"); + + b1.Property("ConversionTargetDate") + .HasColumnType("datetime2") + .HasColumnName("ConversionTargetDate"); + + b1.Property("ConversionTargetDateExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("ConversionTargetDateExplained"); + + b1.Property("ConversionTargetDateSpecified") + .HasColumnType("bit") + .HasColumnName("ConversionTargetDateSpecified"); + + b1.Property("DeclarationBodyAgree") + .HasColumnType("bit") + .HasColumnName("DeclarationBodyAgree"); + + b1.Property("DeclarationIAmTheChairOrHeadteacher") + .HasColumnType("bit") + .HasColumnName("DeclarationIAmTheChairOrHeadteacher"); + + b1.Property("DeclarationSignedByName") + .HasColumnType("nvarchar(max)") + .HasColumnName("DeclarationSignedByName"); + + b1.Property("FinanceOngoingInvestigations") + .HasColumnType("bit") + .HasColumnName("FinanceOngoingInvestigations"); + + b1.Property("FinancialInvestigationsExplain") + .HasColumnType("nvarchar(max)") + .HasColumnName("FinancialInvestigationsExplain"); + + b1.Property("FinancialInvestigationsTrustAware") + .HasColumnType("bit") + .HasColumnName("FinancialInvestigationsTrustAware"); + + b1.Property("MainContactOtherEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("MainContactOtherEmail"); + + b1.Property("MainContactOtherName") + .HasColumnType("nvarchar(max)") + .HasColumnName("MainContactOtherName"); + + b1.Property("MainContactOtherRole") + .HasColumnType("nvarchar(max)") + .HasColumnName("MainContactOtherRole"); + + b1.Property("ProjectedPupilNumbersYear1") + .HasColumnType("int") + .HasColumnName("ProjectedPupilNumbersYear1"); + + b1.Property("ProjectedPupilNumbersYear2") + .HasColumnType("int") + .HasColumnName("ProjectedPupilNumbersYear2"); + + b1.Property("ProjectedPupilNumbersYear3") + .HasColumnType("int") + .HasColumnName("ProjectedPupilNumbersYear3"); + + b1.Property("ProposedNewSchoolName") + .HasColumnType("nvarchar(max)") + .HasColumnName("ProposedNewSchoolName"); + + b1.Property("SchoolConversionReasonsForJoining") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolConversionReasonsForJoining"); + + b1.Property("SchoolHasConsultedStakeholders") + .HasColumnType("bit") + .HasColumnName("SchoolHasConsultedStakeholders"); + + b1.Property("SchoolName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolName"); + + b1.Property("SchoolPlanToConsultStakeholders") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolPlanToConsultStakeholders"); + + b1.Property("SchoolSupportGrantFundsPaidTo") + .HasColumnType("int") + .HasColumnName("SupportGrantFundsPaidTo"); + + b1.Property("Urn") + .HasColumnType("int") + .HasColumnName("Urn"); + + b1.HasKey("SchoolId"); + + b1.ToTable("ApplicationSchool", "academisation"); + + b1.WithOwner() + .HasForeignKey("SchoolId"); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.LandAndBuildings", "LandAndBuildings", b2 => + { + b2.Property("SchoolDetailsSchoolId") + .HasColumnType("int"); + + b2.Property("FacilitiesShared") + .HasColumnType("bit") + .HasColumnName("FacilitiesShared"); + + b2.Property("FacilitiesSharedExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("FacilitiesSharedExplained"); + + b2.Property("Grants") + .HasColumnType("bit") + .HasColumnName("Grants"); + + b2.Property("GrantsAwardingBodies") + .HasColumnType("nvarchar(max)") + .HasColumnName("GrantsAwardingBodies"); + + b2.Property("OwnerExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("OwnerExplained"); + + b2.Property("PartOfBuildingSchoolsForFutureProgramme") + .HasColumnType("bit") + .HasColumnName("PartOfBuildingSchoolsForFutureProgramme"); + + b2.Property("PartOfPfiScheme") + .HasColumnType("bit") + .HasColumnName("PartOfPfiScheme"); + + b2.Property("PartOfPfiSchemeType") + .HasColumnType("nvarchar(max)") + .HasColumnName("PartOfPfiSchemeType"); + + b2.Property("PartOfPrioritySchoolsBuildingProgramme") + .HasColumnType("bit") + .HasColumnName("PartOfPrioritySchoolsBuildingProgramme"); + + b2.Property("WorksPlanned") + .HasColumnType("bit") + .HasColumnName("WorksPlanned"); + + b2.Property("WorksPlannedDate") + .HasColumnType("datetime2") + .HasColumnName("WorksPlannedDate"); + + b2.Property("WorksPlannedExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("WorksPlannedExplained"); + + b2.HasKey("SchoolDetailsSchoolId"); + + b2.ToTable("ApplicationSchool", "academisation"); + + b2.WithOwner() + .HasForeignKey("SchoolDetailsSchoolId"); + }); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.FinancialYear", "CurrentFinancialYear", b2 => + { + b2.Property("SchoolDetailsSchoolId") + .HasColumnType("int"); + + b2.Property("CapitalCarryForward") + .HasColumnType("decimal(18,2)") + .HasColumnName("CurrentFinancialYearCapitalCarryForward"); + + b2.Property("CapitalCarryForwardExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("CurrentFinancialYearCapitalCarryForwardExplained"); + + b2.Property("CapitalCarryForwardFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("CurrentFinancialYearCapitalCarryForwardFileLink"); + + b2.Property("CapitalCarryForwardStatus") + .HasColumnType("int") + .HasColumnName("CurrentFinancialYearCapitalCarryForwardStatus"); + + b2.Property("FinancialYearEndDate") + .HasColumnType("datetime2") + .HasColumnName("CurrentFinancialYearEndDate"); + + b2.Property("Revenue") + .HasColumnType("decimal(18,2)") + .HasColumnName("CurrentFinancialYearRevenue"); + + b2.Property("RevenueStatus") + .HasColumnType("int") + .HasColumnName("CurrentFinancialYearRevenueStatus"); + + b2.Property("RevenueStatusExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("CurrentFinancialYearRevenueStatusExplained"); + + b2.Property("RevenueStatusFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("CurrentFinancialYearRevenueStatusFileLink"); + + b2.HasKey("SchoolDetailsSchoolId"); + + b2.ToTable("ApplicationSchool", "academisation"); + + b2.WithOwner() + .HasForeignKey("SchoolDetailsSchoolId"); + }); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.FinancialYear", "NextFinancialYear", b2 => + { + b2.Property("SchoolDetailsSchoolId") + .HasColumnType("int"); + + b2.Property("CapitalCarryForward") + .HasColumnType("decimal(18,2)") + .HasColumnName("NextFinancialYearCapitalCarryForward"); + + b2.Property("CapitalCarryForwardExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("NextFinancialYearCapitalCarryForwardExplained"); + + b2.Property("CapitalCarryForwardFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("NextFinancialYearCapitalCarryForwardFileLink"); + + b2.Property("CapitalCarryForwardStatus") + .HasColumnType("int") + .HasColumnName("NextFinancialYearCapitalCarryForwardStatus"); + + b2.Property("FinancialYearEndDate") + .HasColumnType("datetime2") + .HasColumnName("NextFinancialYearEndDate"); + + b2.Property("Revenue") + .HasColumnType("decimal(18,2)") + .HasColumnName("NextFinancialYearRevenue"); + + b2.Property("RevenueStatus") + .HasColumnType("int") + .HasColumnName("NextFinancialYearRevenueStatus"); + + b2.Property("RevenueStatusExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("NextFinancialYearRevenueStatusExplained"); + + b2.Property("RevenueStatusFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("NextFinancialYearRevenueStatusFileLink"); + + b2.HasKey("SchoolDetailsSchoolId"); + + b2.ToTable("ApplicationSchool", "academisation"); + + b2.WithOwner() + .HasForeignKey("SchoolDetailsSchoolId"); + }); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.FinancialYear", "PreviousFinancialYear", b2 => + { + b2.Property("SchoolDetailsSchoolId") + .HasColumnType("int"); + + b2.Property("CapitalCarryForward") + .HasColumnType("decimal(18,2)") + .HasColumnName("PreviousFinancialYearCapitalCarryForward"); + + b2.Property("CapitalCarryForwardExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousFinancialYearCapitalCarryForwardExplained"); + + b2.Property("CapitalCarryForwardFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousFinancialYearCapitalCarryForwardFileLink"); + + b2.Property("CapitalCarryForwardStatus") + .HasColumnType("int") + .HasColumnName("PreviousFinancialYearCapitalCarryForwardStatus"); + + b2.Property("FinancialYearEndDate") + .HasColumnType("datetime2") + .HasColumnName("PreviousFinancialYearEndDate"); + + b2.Property("Revenue") + .HasColumnType("decimal(18,2)") + .HasColumnName("PreviousFinancialYearRevenue"); + + b2.Property("RevenueStatus") + .HasColumnType("int") + .HasColumnName("PreviousFinancialYearRevenueStatus"); + + b2.Property("RevenueStatusExplained") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousFinancialYearRevenueStatusExplained"); + + b2.Property("RevenueStatusFileLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousFinancialYearRevenueStatusFileLink"); + + b2.HasKey("SchoolDetailsSchoolId"); + + b2.ToTable("ApplicationSchool", "academisation"); + + b2.WithOwner() + .HasForeignKey("SchoolDetailsSchoolId"); + }); + + b1.Navigation("CurrentFinancialYear"); + + b1.Navigation("LandAndBuildings"); + + b1.Navigation("NextFinancialYear"); + + b1.Navigation("PreviousFinancialYear"); + }); + + b.Navigation("Details") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ApplicationAggregate.FormTrustDetails", "TrustDetails", b1 => + { + b1.Property("FormTrustId") + .HasColumnType("int"); + + b1.Property("FormTrustGrowthPlansYesNo") + .HasColumnType("bit") + .HasColumnName("FormTrustGrowthPlansYesNo"); + + b1.Property("FormTrustImprovementApprovedSponsor") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustImprovementApprovedSponsor"); + + b1.Property("FormTrustImprovementStrategy") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustImprovementStrategy"); + + b1.Property("FormTrustImprovementSupport") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustImprovementSupport"); + + b1.Property("FormTrustOpeningDate") + .HasColumnType("datetime2") + .HasColumnName("FormTrustOpeningDate"); + + b1.Property("FormTrustPlanForGrowth") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustPlanForGrowth"); + + b1.Property("FormTrustPlansForNoGrowth") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustPlansForNoGrowth"); + + b1.Property("FormTrustProposedNameOfTrust") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustProposedNameOfTrust"); + + b1.Property("FormTrustReasonApprovaltoConvertasSAT") + .HasColumnType("bit") + .HasColumnName("FormTrustReasonApprovaltoConvertasSAT"); + + b1.Property("FormTrustReasonApprovedPerson") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonApprovedPerson"); + + b1.Property("FormTrustReasonForming") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonForming"); + + b1.Property("FormTrustReasonFreedom") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonFreedom"); + + b1.Property("FormTrustReasonGeoAreas") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonGeoAreas"); + + b1.Property("FormTrustReasonImproveTeaching") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonImproveTeaching"); + + b1.Property("FormTrustReasonVision") + .HasColumnType("nvarchar(max)") + .HasColumnName("FormTrustReasonVision"); + + b1.Property("TrustApproverEmail") + .HasColumnType("nvarchar(max)") + .HasColumnName("TrustApproverEmail"); + + b1.Property("TrustApproverName") + .HasColumnType("nvarchar(max)") + .HasColumnName("TrustApproverName"); + + b1.HasKey("FormTrustId"); + + b1.ToTable("ApplicationFormTrust", "academisation"); + + b1.WithOwner() + .HasForeignKey("FormTrustId"); + }); + + b.Navigation("TrustDetails") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPerson", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", null) + .WithMany("KeyPeople") + .HasForeignKey("ApplicationFormTrustId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPersonRole", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPerson", null) + .WithMany("Roles") + .HasForeignKey("ApplicationFormTrustKeyPersonRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDecisionDetails", "AdvisoryBoardDecisionDetails", b1 => + { + b1.Property("ConversionAdvisoryBoardDecisionId") + .HasColumnType("int"); + + b1.Property("AcademyOrderDate") + .HasColumnType("datetime2") + .HasColumnName("AcademyOrderDate"); + + b1.Property("AdvisoryBoardDecisionDate") + .HasColumnType("datetime2") + .HasColumnName("AdvisoryBoardDecisionDate"); + + b1.Property("ApprovedConditionsDetails") + .HasColumnType("nvarchar(max)") + .HasColumnName("ApprovedConditionsDetails"); + + b1.Property("ApprovedConditionsSet") + .HasColumnType("bit") + .HasColumnName("ApprovedConditionsSet"); + + b1.Property("ConversionProjectId") + .HasColumnType("int") + .HasColumnName("ConversionProjectId"); + + b1.Property("Decision") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("Decision"); + + b1.Property("DecisionMadeBy") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("DecisionMadeBy"); + + b1.Property("DecisionMakerName") + .HasColumnType("nvarchar(max)") + .HasColumnName("DecisionMakerName"); + + b1.Property("TransferProjectId") + .HasColumnType("int") + .HasColumnName("TransferProjectId"); + + b1.HasKey("ConversionAdvisoryBoardDecisionId"); + + b1.ToTable("ConversionAdvisoryBoardDecision", "academisation"); + + b1.WithOwner() + .HasForeignKey("ConversionAdvisoryBoardDecisionId"); + }); + + b.Navigation("AdvisoryBoardDecisionDetails") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDAORevokedReasonDetails", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", null) + .WithMany("DaoRevokedReasons") + .HasForeignKey("AdvisoryBoardDecisionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDeclinedReasonDetails", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", null) + .WithMany("DeclinedReasons") + .HasForeignKey("AdvisoryBoardDecisionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardDeferredReasonDetails", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", null) + .WithMany("DeferredReasons") + .HasForeignKey("AdvisoryBoardDecisionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ConversionAdvisoryBoardDecisionAggregate.AdvisoryBoardWithdrawnReasonDetails", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", null) + .WithMany("WithdrawnReasons") + .HasForeignKey("AdvisoryBoardDecisionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.ProjectNote", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", null) + .WithMany("Notes") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.FormAMatProjectAggregate.FormAMatProject", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.User", "AssignedUser", b1 => + { + b1.Property("FormAMatProjectId") + .HasColumnType("int"); + + b1.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserEmailAddress"); + + b1.Property("FullName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserFullName"); + + b1.Property("Id") + .HasColumnType("uniqueidentifier") + .HasColumnName("AssignedUserId"); + + b1.HasKey("FormAMatProjectId"); + + b1.ToTable("FormAMatProject", "academisation"); + + b1.WithOwner() + .HasForeignKey("FormAMatProjectId"); + }); + + b.Navigation("AssignedUser"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.ProjectDetails", "Details", b1 => + { + b1.Property("ProjectId") + .HasColumnType("int"); + + b1.Property("AcademyTypeAndRoute") + .HasColumnType("nvarchar(max)") + .HasColumnName("AcademyTypeAndRoute"); + + b1.Property("ActualPupilNumbers") + .HasColumnType("int") + .HasColumnName("ActualPupilNumbers"); + + b1.Property("AgeRange") + .HasColumnType("nvarchar(max)") + .HasColumnName("AgeRange"); + + b1.Property("AnnexBFormReceived") + .HasColumnType("bit") + .HasColumnName("AnnexBFormReceived"); + + b1.Property("AnnexBFormUrl") + .HasColumnType("nvarchar(max)") + .HasColumnName("AnnexBFormUrl"); + + b1.Property("ApplicationReceivedDate") + .HasColumnType("datetime2") + .HasColumnName("ApplicationReceivedDate"); + + b1.Property("ApplicationReferenceNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("ApplicationReferenceNumber"); + + b1.Property("AssignedDate") + .HasColumnType("datetime2") + .HasColumnName("AssignedDate"); + + b1.Property("Author") + .HasColumnType("nvarchar(max)") + .HasColumnName("Author"); + + b1.Property("BaselineDate") + .HasColumnType("datetime2") + .HasColumnName("BaselineDate"); + + b1.Property("Capacity") + .HasColumnType("int") + .HasColumnName("Capacity"); + + b1.Property("CapitalCarryForwardAtEndMarchCurrentYear") + .HasColumnType("decimal(18,2)") + .HasColumnName("CapitalCarryForwardAtEndMarchCurrentYear"); + + b1.Property("CapitalCarryForwardAtEndMarchNextYear") + .HasColumnType("decimal(18,2)") + .HasColumnName("CapitalCarryForwardAtEndMarchNextYear"); + + b1.Property("ClearedBy") + .HasColumnType("nvarchar(max)") + .HasColumnName("ClearedBy"); + + b1.Property("Consultation") + .HasColumnType("nvarchar(max)") + .HasColumnName("Consultation"); + + b1.Property("ConversionSupportGrantAmount") + .HasColumnType("decimal(18,2)") + .HasColumnName("ConversionSupportGrantAmount"); + + b1.Property("ConversionSupportGrantAmountChanged") + .HasColumnType("bit") + .HasColumnName("ConversionSupportGrantAmountChanged"); + + b1.Property("ConversionSupportGrantChangeReason") + .HasColumnType("nvarchar(max)") + .HasColumnName("ConversionSupportGrantChangeReason"); + + b1.Property("ConversionSupportGrantEnvironmentalImprovementGrant") + .HasColumnType("nvarchar(max)") + .HasColumnName("ConversionSupportGrantEnvironmentalImprovementGrant"); + + b1.Property("ConversionSupportGrantNumberOfSites") + .HasColumnType("nvarchar(max)"); + + b1.Property("ConversionSupportGrantType") + .HasColumnType("nvarchar(max)") + .HasColumnName("ConversionSupportGrantType"); + + b1.Property("DaoPackSentDate") + .HasColumnType("datetime2") + .HasColumnName("DaoPackSentDate"); + + b1.Property("DiocesanConsent") + .HasColumnType("nvarchar(max)") + .HasColumnName("DiocesanConsent"); + + b1.Property("DiocesanTrust") + .HasColumnType("nvarchar(max)") + .HasColumnName("DiocesanTrust"); + + b1.Property("DistanceFromSchoolToTrustHeadquarters") + .HasColumnType("decimal(18,2)") + .HasColumnName("DistanceFromSchoolToTrustHeadquarters"); + + b1.Property("DistanceFromSchoolToTrustHeadquartersAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("DistanceFromSchoolToTrustHeadquartersAdditionalInformation"); + + b1.Property("EducationalAttendanceAdditionalInformation") + .HasColumnType("nvarchar(max)"); + + b1.Property("EndOfCurrentFinancialYear") + .HasColumnType("datetime2") + .HasColumnName("EndOfCurrentFinancialYear"); + + b1.Property("EndOfNextFinancialYear") + .HasColumnType("datetime2") + .HasColumnName("EndOfNextFinancialYear"); + + b1.Property("ExternalApplicationFormSaved") + .HasColumnType("bit") + .HasColumnName("ExternalApplicationFormSaved"); + + b1.Property("ExternalApplicationFormUrl") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExternalApplicationFormUrl"); + + b1.Property("FinancialDeficit") + .HasColumnType("nvarchar(max)") + .HasColumnName("FinancialDeficit"); + + b1.Property("Form7Received") + .HasColumnType("nvarchar(max)") + .HasColumnName("Form7Received"); + + b1.Property("Form7ReceivedDate") + .HasColumnType("datetime2") + .HasColumnName("Form7ReceivedDate"); + + b1.Property("FoundationConsent") + .HasColumnType("nvarchar(max)") + .HasColumnName("FoundationConsent"); + + b1.Property("GoverningBodyResolution") + .HasColumnType("nvarchar(max)") + .HasColumnName("GoverningBodyResolution"); + + b1.Property("HeadTeacherBoardDate") + .HasColumnType("datetime2") + .HasColumnName("HeadTeacherBoardDate"); + + b1.Property("IfdPipelineId") + .HasColumnType("int") + .HasColumnName("IfdPipelineId"); + + b1.Property("IsFormAMat") + .HasColumnType("bit") + .HasColumnName("IsFormAMat"); + + b1.Property("KeyStage2PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("KeyStage2PerformanceAdditionalInformation"); + + b1.Property("KeyStage4PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("KeyStage4PerformanceAdditionalInformation"); + + b1.Property("KeyStage5PerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("KeyStage5PerformanceAdditionalInformation"); + + b1.Property("LegalRequirementsSectionComplete") + .HasColumnType("bit") + .HasColumnName("LegalRequirementsSectionComplete"); + + b1.Property("LocalAuthority") + .HasColumnType("nvarchar(max)") + .HasColumnName("LocalAuthority"); + + b1.Property("LocalAuthorityInformationTemplateComments") + .HasColumnType("nvarchar(max)") + .HasColumnName("LocalAuthorityInformationTemplateComments"); + + b1.Property("LocalAuthorityInformationTemplateLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("LocalAuthorityInformationTemplateLink"); + + b1.Property("LocalAuthorityInformationTemplateReturnedDate") + .HasColumnType("datetime2") + .HasColumnName("LocalAuthorityInformationTemplateReturnedDate"); + + b1.Property("LocalAuthorityInformationTemplateSectionComplete") + .HasColumnType("bit") + .HasColumnName("LocalAuthorityInformationTemplateSectionComplete"); + + b1.Property("LocalAuthorityInformationTemplateSentDate") + .HasColumnType("datetime2") + .HasColumnName("LocalAuthorityInformationTemplateSentDate"); + + b1.Property("MemberOfParliamentNameAndParty") + .HasColumnType("nvarchar(max)") + .HasColumnName("MemberOfParliamentNameAndParty"); + + b1.Property("NameOfTrust") + .HasColumnType("nvarchar(max)") + .HasColumnName("NameOfTrust"); + + b1.Property("NumberOfAlternativeProvisionPlaces") + .HasColumnType("int"); + + b1.Property("NumberOfFundedResidentialPlaces") + .HasColumnType("decimal(18,2)"); + + b1.Property("NumberOfMedicalPlaces") + .HasColumnType("int"); + + b1.Property("NumberOfPlacesFundedFor") + .HasColumnType("decimal(18,2)"); + + b1.Property("NumberOfPost16Places") + .HasColumnType("int"); + + b1.Property("NumberOfResidentialPlaces") + .HasColumnType("decimal(18,2)"); + + b1.Property("NumberOfSENUnitPlaces") + .HasColumnType("int"); + + b1.Property("PartOfPfiScheme") + .HasColumnType("nvarchar(max)") + .HasColumnName("PartOfPfiScheme"); + + b1.Property("PercentageFreeSchoolMeals") + .HasColumnType("decimal(18,2)") + .HasColumnName("PercentageFreeSchoolMeals"); + + b1.Property("PercentageOfGoodOrOutstandingSchoolsInTheDiocesanTrust") + .HasColumnType("decimal(18,2)") + .HasColumnName("PercentageOfGoodOrOutstandingSchoolsInTheDiocesanTrust"); + + b1.Property("PfiSchemeDetails") + .HasColumnType("nvarchar(max)") + .HasColumnName("PfiSchemeDetails"); + + b1.Property("PreviousHeadTeacherBoardDate") + .HasColumnType("datetime2") + .HasColumnName("PreviousHeadTeacherBoardDate"); + + b1.Property("PreviousHeadTeacherBoardDateQuestion") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousHeadTeacherBoardDateQuestion"); + + b1.Property("PreviousHeadTeacherBoardLink") + .HasColumnType("nvarchar(max)") + .HasColumnName("PreviousHeadTeacherBoardLink"); + + b1.Property("ProjectDatesSectionComplete") + .HasColumnType("bit") + .HasColumnName("ProjectDatesSectionComplete"); + + b1.Property("ProjectStatus") + .HasColumnType("nvarchar(max)") + .HasColumnName("ProjectStatus"); + + b1.Property("ProjectedRevenueBalanceAtEndMarchNextYear") + .HasColumnType("decimal(18,2)") + .HasColumnName("ProjectedRevenueBalanceAtEndMarchNextYear"); + + b1.Property("ProposedConversionDate") + .HasColumnType("datetime2") + .HasColumnName("ProposedAcademyOpeningDate"); + + b1.Property("PublishedAdmissionNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("PublishedAdmissionNumber"); + + b1.Property("PupilsAttendingGroupMedicalAndHealthNeeds") + .HasColumnType("bit"); + + b1.Property("PupilsAttendingGroupPermanentlyExcluded") + .HasColumnType("bit"); + + b1.Property("PupilsAttendingGroupTeenageMums") + .HasColumnType("bit"); + + b1.Property("RationaleForProject") + .HasColumnType("nvarchar(max)") + .HasColumnName("RationaleForProject"); + + b1.Property("RationaleForTrust") + .HasColumnType("nvarchar(max)") + .HasColumnName("RationaleForTrust"); + + b1.Property("RationaleSectionComplete") + .HasColumnType("bit") + .HasColumnName("RationaleSectionComplete"); + + b1.Property("RecommendationForProject") + .HasColumnType("nvarchar(max)") + .HasColumnName("RecommendationForProject"); + + b1.Property("Region") + .HasColumnType("nvarchar(max)") + .HasColumnName("Region"); + + b1.Property("RevenueCarryForwardAtEndMarchCurrentYear") + .HasColumnType("decimal(18,2)") + .HasColumnName("RevenueCarryForwardAtEndMarchCurrentYear"); + + b1.Property("RisksAndIssues") + .HasColumnType("nvarchar(max)") + .HasColumnName("RisksAndIssues"); + + b1.Property("RisksAndIssuesSectionComplete") + .HasColumnType("bit") + .HasColumnName("RisksAndIssuesSectionComplete"); + + b1.Property("SchoolAndTrustInformationSectionComplete") + .HasColumnType("bit") + .HasColumnName("SchoolAndTrustInformationSectionComplete"); + + b1.Property("SchoolBudgetInformationAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolBudgetInformationAdditionalInformation"); + + b1.Property("SchoolBudgetInformationSectionComplete") + .HasColumnType("bit") + .HasColumnName("SchoolBudgetInformationSectionComplete"); + + b1.Property("SchoolName") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolName"); + + b1.Property("SchoolOverviewSectionComplete") + .HasColumnType("bit") + .HasColumnName("SchoolOverviewSectionComplete"); + + b1.Property("SchoolPerformanceAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolPerformanceAdditionalInformation"); + + b1.Property("SchoolPhase") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolPhase"); + + b1.Property("SchoolPupilForecastsAdditionalInformation") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolPupilForecastsAdditionalInformation"); + + b1.Property("SchoolType") + .HasColumnType("nvarchar(max)") + .HasColumnName("SchoolType"); + + b1.Property("SponsorName") + .HasColumnType("nvarchar(max)") + .HasColumnName("SponsorName"); + + b1.Property("SponsorReferenceNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("SponsorReferenceNumber"); + + b1.Property("TrustReferenceNumber") + .HasColumnType("nvarchar(max)") + .HasColumnName("TrustReferenceNumber"); + + b1.Property("Urn") + .HasColumnType("int") + .HasColumnName("Urn"); + + b1.Property("Version") + .HasColumnType("nvarchar(max)") + .HasColumnName("Version"); + + b1.Property("ViabilityIssues") + .HasColumnType("nvarchar(max)") + .HasColumnName("ViabilityIssues"); + + b1.Property("YearOneProjectedCapacity") + .HasColumnType("int") + .HasColumnName("YearOneProjectedCapacity"); + + b1.Property("YearOneProjectedPupilNumbers") + .HasColumnType("int") + .HasColumnName("YearOneProjectedPupilNumbers"); + + b1.Property("YearThreeProjectedCapacity") + .HasColumnType("int") + .HasColumnName("YearThreeProjectedCapacity"); + + b1.Property("YearThreeProjectedPupilNumbers") + .HasColumnType("int") + .HasColumnName("YearThreeProjectedPupilNumbers"); + + b1.Property("YearTwoProjectedCapacity") + .HasColumnType("int") + .HasColumnName("YearTwoProjectedCapacity"); + + b1.Property("YearTwoProjectedPupilNumbers") + .HasColumnType("int") + .HasColumnName("YearTwoProjectedPupilNumbers"); + + b1.HasKey("ProjectId"); + + b1.ToTable("Project", "academisation"); + + b1.WithOwner() + .HasForeignKey("ProjectId"); + + b1.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.User", "AssignedUser", b2 => + { + b2.Property("ProjectDetailsProjectId") + .HasColumnType("int"); + + b2.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserEmailAddress"); + + b2.Property("FullName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserFullName"); + + b2.Property("Id") + .HasColumnType("uniqueidentifier") + .HasColumnName("AssignedUserId"); + + b2.HasKey("ProjectDetailsProjectId"); + + b2.ToTable("Project", "academisation"); + + b2.WithOwner() + .HasForeignKey("ProjectDetailsProjectId"); + }); + + b1.Navigation("AssignedUser"); + }); + + b.Navigation("Details") + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.SchoolImprovementPlan", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", null) + .WithMany("SchoolImprovementPlans") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate.ProjectGroup", b => + { + b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.User", "AssignedUser", b1 => + { + b1.Property("ProjectGroupId") + .HasColumnType("int"); + + b1.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserEmailAddress"); + + b1.Property("FullName") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("AssignedUserFullName"); + + b1.Property("Id") + .HasColumnType("uniqueidentifier") + .HasColumnName("AssignedUserId"); + + b1.HasKey("ProjectGroupId"); + + b1.ToTable("ProjectGroups", "academisation"); + + b1.WithOwner() + .HasForeignKey("ProjectGroupId"); + }); + + b.Navigation("AssignedUser"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.IntendedTransferBenefit", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferProject", null) + .WithMany("IntendedTransferBenefits") + .HasForeignKey("TransferProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferringAcademy", b => + { + b.HasOne("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferProject", null) + .WithMany("TransferringAcademies") + .HasForeignKey("TransferProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", b => + { + b.Navigation("Contributors"); + + b.Navigation("Schools"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Schools.School", b => + { + b.Navigation("Leases"); + + b.Navigation("Loans"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", b => + { + b.Navigation("KeyPeople"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.TrustKeyPerson", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate.ConversionAdvisoryBoardDecision", b => + { + b.Navigation("DaoRevokedReasons"); + + b.Navigation("DeclinedReasons"); + + b.Navigation("DeferredReasons"); + + b.Navigation("WithdrawnReasons"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ProjectAggregate.Project", b => + { + b.Navigation("Notes"); + + b.Navigation("SchoolImprovementPlans"); + }); + + modelBuilder.Entity("Dfe.Academies.Academisation.Domain.TransferProjectAggregate.TransferProject", b => + { + b.Navigation("IntendedTransferBenefits"); + + b.Navigation("TransferringAcademies"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Dfe.Academies.Academisation.Data/Migrations/20240913151403_Remove-UserRole-Tbl.cs b/Dfe.Academies.Academisation.Data/Migrations/20240913151403_Remove-UserRole-Tbl.cs new file mode 100644 index 000000000..c6862497a --- /dev/null +++ b/Dfe.Academies.Academisation.Data/Migrations/20240913151403_Remove-UserRole-Tbl.cs @@ -0,0 +1,42 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Dfe.Academies.Academisation.Data.Migrations +{ + /// + public partial class RemoveUserRoleTbl : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "UserRoles", + schema: "academisation"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "UserRoles", + schema: "academisation", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CreatedOn = table.Column(type: "datetime2", nullable: false), + IsEnabled = table.Column(type: "bit", nullable: false), + LastModifiedOn = table.Column(type: "datetime2", nullable: false), + RoleId = table.Column(type: "nvarchar(max)", nullable: false), + AssignedUserEmailAddress = table.Column(type: "nvarchar(max)", nullable: true), + AssignedUserFullName = table.Column(type: "nvarchar(max)", nullable: true), + AssignedUserId = table.Column(type: "uniqueidentifier", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserRoles", x => x.Id); + }); + } + } +} diff --git a/Dfe.Academies.Academisation.Data/Migrations/AcademisationContextModelSnapshot.cs b/Dfe.Academies.Academisation.Data/Migrations/AcademisationContextModelSnapshot.cs index b74264f80..7890651e8 100644 --- a/Dfe.Academies.Academisation.Data/Migrations/AcademisationContextModelSnapshot.cs +++ b/Dfe.Academies.Academisation.Data/Migrations/AcademisationContextModelSnapshot.cs @@ -17,7 +17,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.7") + .HasAnnotation("ProductVersion", "8.0.8") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); @@ -1046,32 +1046,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("TransferringAcademy", "academisation"); }); - modelBuilder.Entity("Dfe.Academies.Academisation.Domain.UserRoleAggregate.UserRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedOn") - .HasColumnType("datetime2"); - - b.Property("IsEnabled") - .HasColumnType("bit"); - - b.Property("LastModifiedOn") - .HasColumnType("datetime2"); - - b.Property("RoleId") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.ToTable("UserRoles", "academisation"); - }); - modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", b => { b.HasOne("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Trusts.FormTrust", "FormTrust") @@ -2273,38 +2247,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired(); }); - modelBuilder.Entity("Dfe.Academies.Academisation.Domain.UserRoleAggregate.UserRole", b => - { - b.OwnsOne("Dfe.Academies.Academisation.Domain.Core.ProjectAggregate.User", "AssignedUser", b1 => - { - b1.Property("UserRoleId") - .HasColumnType("int"); - - b1.Property("EmailAddress") - .IsRequired() - .HasColumnType("nvarchar(max)") - .HasColumnName("AssignedUserEmailAddress"); - - b1.Property("FullName") - .IsRequired() - .HasColumnType("nvarchar(max)") - .HasColumnName("AssignedUserFullName"); - - b1.Property("Id") - .HasColumnType("uniqueidentifier") - .HasColumnName("AssignedUserId"); - - b1.HasKey("UserRoleId"); - - b1.ToTable("UserRoles", "academisation"); - - b1.WithOwner() - .HasForeignKey("UserRoleId"); - }); - - b.Navigation("AssignedUser"); - }); - modelBuilder.Entity("Dfe.Academies.Academisation.Domain.ApplicationAggregate.Application", b => { b.Navigation("Contributors"); diff --git a/Dfe.Academies.Academisation.Data/Repositories/UserRoleRepository.cs b/Dfe.Academies.Academisation.Data/Repositories/UserRoleRepository.cs deleted file mode 100644 index f883fcbb0..000000000 --- a/Dfe.Academies.Academisation.Data/Repositories/UserRoleRepository.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; -using Dfe.Academies.Academisation.Domain.SeedWork; -using Dfe.Academies.Academisation.Domain.UserRoleAggregate; -using Dfe.Academies.Academisation.IDomain.UserRoleAggregate; -using Microsoft.EntityFrameworkCore; -using Microsoft.IdentityModel.Tokens; - -namespace Dfe.Academies.Academisation.Data.Repositories -{ - public class UserRoleRepository(AcademisationContext context, IRoleInfo roleInfo) : GenericRepository(context), IUserRoleRepository - { - private readonly AcademisationContext _context = context ?? throw new ArgumentNullException(nameof(context)); - private readonly IRoleInfo _roleInfo = roleInfo ?? throw new ArgumentNullException(nameof(roleInfo)); - - public IUnitOfWork UnitOfWork => _context; - - public async Task> SearchUsersAsync(string? searchTerm, RoleId? roleId, CancellationToken cancellationToken) - { - var queryable = DefaultIncludes(); - queryable = FilterBySearchTerm(searchTerm, queryable); - queryable = FilterByRoleId(roleId, queryable); - - var projects = await queryable - .OrderByDescending(acp => acp.CreatedOn) - .ToListAsync(cancellationToken); - - return projects; - } - public async Task GetUserWithRoleAsync(string email, CancellationToken cancellationToken) - => await DefaultIncludes().FirstOrDefaultAsync(x => x.AssignedUser!.EmailAddress == email, cancellationToken); - - public async Task> GetUserRoleCapabilitiesAsync(string email, CancellationToken cancellationToken) - { - var userRole = await DefaultIncludes().FirstOrDefaultAsync(x => x.AssignedUser!.EmailAddress == email, cancellationToken); - return userRole == null ? Roles.GetRoleCapabilities(RoleId.Standard) : Roles.GetRoleCapabilities(_roleInfo.GetEnum(userRole.RoleId)); - } - private static IQueryable FilterBySearchTerm(string? searchTerm, IQueryable queryable) - { - if (!searchTerm.IsNullOrEmpty()) - { - searchTerm = searchTerm!.ToLower(); - queryable = queryable.Where(p => (p.AssignedUser != null && p.AssignedUser.EmailAddress.Contains(searchTerm)) || - p.AssignedUser!.FullName.Contains(searchTerm)); - } - - return queryable; - } - - private IQueryable FilterByRoleId(RoleId? roleId, IQueryable queryable) - { - if (roleId != null) - { - var id = _roleInfo.GetId(roleId.Value); - queryable = queryable.Where(p => p.RoleId == id); - } - - return queryable; - } - - private IQueryable DefaultIncludes() - { - var x = dbSet - .Include(x => x.AssignedUser) - .AsQueryable(); - - return x; - } - } -} diff --git a/Dfe.Academies.Academisation.Domain.Core/RoleCapabilitiesAggregate/RoleCapability.cs b/Dfe.Academies.Academisation.Domain.Core/RoleCapabilitiesAggregate/RoleCapability.cs new file mode 100644 index 000000000..3760b1852 --- /dev/null +++ b/Dfe.Academies.Academisation.Domain.Core/RoleCapabilitiesAggregate/RoleCapability.cs @@ -0,0 +1,11 @@ + +namespace Dfe.Academies.Academisation.Domain.Core.RoleCapabilitiesAggregate +{ + public enum RoleCapability + { + CreateConversionProject, + CreateTransferProject, + DeleteConversionProject, + DeleteTransferProject, + } +} diff --git a/Dfe.Academies.Academisation.Domain.Core/RoleCapabilitiesAggregate/RoleId.cs b/Dfe.Academies.Academisation.Domain.Core/RoleCapabilitiesAggregate/RoleId.cs new file mode 100644 index 000000000..63d7f2339 --- /dev/null +++ b/Dfe.Academies.Academisation.Domain.Core/RoleCapabilitiesAggregate/RoleId.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Dfe.Academies.Academisation.Domain.Core.RoleCapabilitiesAggregate +{ + public enum RoleId + { + [Description("SuperAdmin")] + SuperAdmin = 1, + [Description("ConversionCreation")] + ConversionCreation = 2, + [Description("TransferCreation")] + TransferCreation = 3 + } +} diff --git a/Dfe.Academies.Academisation.Domain.Core/RoleCapabilitiesAggregate/RoleInfo.cs b/Dfe.Academies.Academisation.Domain.Core/RoleCapabilitiesAggregate/RoleInfo.cs new file mode 100644 index 000000000..bab67cefe --- /dev/null +++ b/Dfe.Academies.Academisation.Domain.Core/RoleCapabilitiesAggregate/RoleInfo.cs @@ -0,0 +1,43 @@ +namespace Dfe.Academies.Academisation.Domain.Core.RoleCapabilitiesAggregate +{ + public interface IRoleInfo + { + List GetRoleCapabilities(string roleId); + } + + public class RoleInfo(Dictionary roleIds) : IRoleInfo + { + private RoleId GetEnum(string roleId) + { + var role = roleIds.FirstOrDefault(kvp => kvp.Value == roleId).Key; + return (RoleId)Enum.Parse(typeof(RoleId), role); + } + public List GetRoleCapabilities(string roleId) + { + switch (GetEnum(roleId)) + { + case RoleId.SuperAdmin: + return SuperAdminRoleCapabilities(); + case RoleId.ConversionCreation: + return ConversionCreationRoleCapabilities(); + case RoleId.TransferCreation: + return TransferCreationRoleCapabilities(); + default: + return []; + } + } + private static List TransferCreationRoleCapabilities() => [ + RoleCapability.CreateTransferProject + ]; + + private static List ConversionCreationRoleCapabilities() => [ + RoleCapability.CreateConversionProject + ]; + + private static List SuperAdminRoleCapabilities() + => ConversionCreationRoleCapabilities().Concat(TransferCreationRoleCapabilities()).Concat([ + RoleCapability.DeleteConversionProject, + RoleCapability.DeleteTransferProject + ]).Distinct().ToList(); + } +} diff --git a/Dfe.Academies.Academisation.Domain.Core/UserRoleAggregate/RoleCapability.cs b/Dfe.Academies.Academisation.Domain.Core/UserRoleAggregate/RoleCapability.cs deleted file mode 100644 index d2f424a98..000000000 --- a/Dfe.Academies.Academisation.Domain.Core/UserRoleAggregate/RoleCapability.cs +++ /dev/null @@ -1,41 +0,0 @@ - -namespace Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate -{ - public enum RoleCapability - { - DeleteTransferProject, - DeleteGroupProject, - DeleteConversionProject, - UserAdministrator - } - public static class Roles - { - public static List GetRoleCapabilities(RoleId roleId) - { - return roleId == RoleId.SuperAdmin - ? SuperAdminRoleCapabilities() : (roleId == RoleId.Manager - ? ManagerRoleCapabilities() : StandardRoleCapabilities()); - } - private static List StandardRoleCapabilities() - { - return [ - RoleCapability.DeleteGroupProject - ]; - } - - private static List ManagerRoleCapabilities() - { - return StandardRoleCapabilities().Concat([ - RoleCapability.DeleteConversionProject, - RoleCapability.DeleteTransferProject - ]).Distinct().ToList(); - } - - private static List SuperAdminRoleCapabilities() - { - return StandardRoleCapabilities().Concat(ManagerRoleCapabilities()).Concat([ - RoleCapability.UserAdministrator - ]).Distinct().ToList(); - } - } -} diff --git a/Dfe.Academies.Academisation.Domain.Core/UserRoleAggregate/RoleId.cs b/Dfe.Academies.Academisation.Domain.Core/UserRoleAggregate/RoleId.cs deleted file mode 100644 index 518a9ddd9..000000000 --- a/Dfe.Academies.Academisation.Domain.Core/UserRoleAggregate/RoleId.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.ComponentModel; - -namespace Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate -{ - public enum RoleId - { - [Description("SuperAdmin")] - SuperAdmin = 1, - [Description("Manager")] - Manager = 2, - [Description("Standard")] - Standard = 3 - } -} diff --git a/Dfe.Academies.Academisation.Domain.Core/UserRoleAggregate/RoleInfo.cs b/Dfe.Academies.Academisation.Domain.Core/UserRoleAggregate/RoleInfo.cs deleted file mode 100644 index b44619e2e..000000000 --- a/Dfe.Academies.Academisation.Domain.Core/UserRoleAggregate/RoleInfo.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate -{ - public interface IRoleInfo - { - string GetId(RoleId roleId); - RoleId GetEnum(string roleId); - } - - public class RoleInfo(Dictionary roleIds) : IRoleInfo - { - public string GetId(RoleId roleId) - { - var key = roleId.ToString(); - return roleIds.FirstOrDefault(kvp => kvp.Key == key && kvp.Value != "").Value; - } - - public RoleId GetEnum(string roleId) - { - var role = roleIds.FirstOrDefault(kvp => kvp.Value == roleId).Key; - return (RoleId)Enum.Parse(typeof(RoleId), role); - } - } -} diff --git a/Dfe.Academies.Academisation.Domain/UserRoleAggregate/IUserRoleRepository.cs b/Dfe.Academies.Academisation.Domain/UserRoleAggregate/IUserRoleRepository.cs deleted file mode 100644 index df703e397..000000000 --- a/Dfe.Academies.Academisation.Domain/UserRoleAggregate/IUserRoleRepository.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; -using Dfe.Academies.Academisation.Domain.SeedWork; -using Dfe.Academies.Academisation.IDomain.UserRoleAggregate; - -namespace Dfe.Academies.Academisation.Domain.UserRoleAggregate -{ - public interface IUserRoleRepository : IRepository, IGenericRepository - { - Task> GetUserRoleCapabilitiesAsync(string email, CancellationToken cancellationToken); - Task GetUserWithRoleAsync(string email, CancellationToken cancellationToken); - Task> SearchUsersAsync(string? searchTerm, RoleId? roleId, CancellationToken cancellationToken); - } -} diff --git a/Dfe.Academies.Academisation.Domain/UserRoleAggregate/UserRole.cs b/Dfe.Academies.Academisation.Domain/UserRoleAggregate/UserRole.cs deleted file mode 100644 index ba752edc4..000000000 --- a/Dfe.Academies.Academisation.Domain/UserRoleAggregate/UserRole.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Dfe.Academies.Academisation.Domain.Core.ProjectAggregate; -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; -using Dfe.Academies.Academisation.Domain.SeedWork; -using Dfe.Academies.Academisation.IDomain.UserRoleAggregate; - -namespace Dfe.Academies.Academisation.Domain.UserRoleAggregate -{ - public class UserRole : Entity, IUserRole, IAggregateRoot - { - public string RoleId { private set; get; } - public User? AssignedUser { private set; get; } - public bool IsEnabled { private set; get; } - - public UserRole(string roleId, bool isEnabled, DateTime createdOn) - { - RoleId = roleId; - IsEnabled = isEnabled; - CreatedOn = createdOn; - } - public void SetAssignedUser(Guid userId, string fullName, string emailAddress) - { - AssignedUser = new User(userId, fullName, emailAddress); - } - - public void SetRole(string roleId, DateTime lastModifiedOn, bool isEnabled = true) - { - RoleId = roleId; - IsEnabled = isEnabled; - LastModifiedOn = lastModifiedOn; - } - } -} diff --git a/Dfe.Academies.Academisation.IDomain/UserRoleAggregate/IUserRole.cs b/Dfe.Academies.Academisation.IDomain/UserRoleAggregate/IUserRole.cs deleted file mode 100644 index eed2751da..000000000 --- a/Dfe.Academies.Academisation.IDomain/UserRoleAggregate/IUserRole.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Dfe.Academies.Academisation.Domain.Core.ProjectAggregate; -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; - -namespace Dfe.Academies.Academisation.IDomain.UserRoleAggregate -{ - public interface IUserRole - { - int Id { get; } - string RoleId { get; } - public User? AssignedUser { get; } - bool IsEnabled { get; } - void SetAssignedUser(Guid userId, string fullName, string emailAddress); - void SetRole(string roleId, DateTime lastModifiedOn, bool isEnabled = true); - } -} diff --git a/Dfe.Academies.Academisation.IService/Query/IRoleCapabilitiesQueryService.cs b/Dfe.Academies.Academisation.IService/Query/IRoleCapabilitiesQueryService.cs new file mode 100644 index 000000000..228955b83 --- /dev/null +++ b/Dfe.Academies.Academisation.IService/Query/IRoleCapabilitiesQueryService.cs @@ -0,0 +1,9 @@ +using Dfe.Academies.Academisation.IService.ServiceModels.RoleCapabilities; + +namespace Dfe.Academies.Academisation.IService.Query +{ + public interface IRoleCapabilitiesQueryService + { + RoleCapabilitiesModel GetRolesCapabilitiesAsync(List roles); + } +} diff --git a/Dfe.Academies.Academisation.IService/Query/IUserRoleQueryService.cs b/Dfe.Academies.Academisation.IService/Query/IUserRoleQueryService.cs deleted file mode 100644 index 23185ae32..000000000 --- a/Dfe.Academies.Academisation.IService/Query/IUserRoleQueryService.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; -using Dfe.Academies.Academisation.IService.ServiceModels.Legacy.ProjectAggregate; -using Dfe.Academies.Academisation.IService.ServiceModels.UserRole; - -namespace Dfe.Academies.Academisation.IService.Query -{ - public interface IUserRoleQueryService - { - Task GetUserRoleCapabilitiesAsync(string email, CancellationToken cancellationToken); - - Task> SearchUsersAsync(string? searchTerm, RoleId? roleId, int page, int count, CancellationToken cancellationToken); - } -} diff --git a/Dfe.Academies.Academisation.IService/ServiceModels/UserRole/RoleCapabilitiesModel.cs b/Dfe.Academies.Academisation.IService/ServiceModels/RoleCapabilities/RoleCapabilitiesModel.cs similarity index 50% rename from Dfe.Academies.Academisation.IService/ServiceModels/UserRole/RoleCapabilitiesModel.cs rename to Dfe.Academies.Academisation.IService/ServiceModels/RoleCapabilities/RoleCapabilitiesModel.cs index dea528038..7a8962254 100644 --- a/Dfe.Academies.Academisation.IService/ServiceModels/UserRole/RoleCapabilitiesModel.cs +++ b/Dfe.Academies.Academisation.IService/ServiceModels/RoleCapabilities/RoleCapabilitiesModel.cs @@ -1,6 +1,6 @@ -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; +using Dfe.Academies.Academisation.Domain.Core.RoleCapabilitiesAggregate; -namespace Dfe.Academies.Academisation.IService.ServiceModels.UserRole +namespace Dfe.Academies.Academisation.IService.ServiceModels.RoleCapabilities { public class RoleCapabilitiesModel(List capabilities) { diff --git a/Dfe.Academies.Academisation.IService/ServiceModels/UserRole/UserRoleModel.cs b/Dfe.Academies.Academisation.IService/ServiceModels/UserRole/UserRoleModel.cs deleted file mode 100644 index b13fb9f24..000000000 --- a/Dfe.Academies.Academisation.IService/ServiceModels/UserRole/UserRoleModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; - -namespace Dfe.Academies.Academisation.IService.ServiceModels.UserRole -{ - public class UserRoleModel(RoleId roleId, string fullName, string email) - { - public RoleId RoleId { get; set; } = roleId; - public string FullName { get; set; } = fullName; - public string Email { get; set; } = email; - } -} diff --git a/Dfe.Academies.Academisation.IService/ServiceModels/UserRole/UserRoleSearchModel.cs b/Dfe.Academies.Academisation.IService/ServiceModels/UserRole/UserRoleSearchModel.cs deleted file mode 100644 index 2dab24106..000000000 --- a/Dfe.Academies.Academisation.IService/ServiceModels/UserRole/UserRoleSearchModel.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; - -namespace Dfe.Academies.Academisation.IService.ServiceModels.UserRole -{ - public class UserRoleSearchModel(int page, int count, string? searchTerm, RoleId? roleId) - { - public int Page { get; set; } = page; - public int Count { get; set; } = count; - public string? searchTerm { get; set; } = searchTerm; - public RoleId? RoleId { get; set; } = roleId; - } -} diff --git a/Dfe.Academies.Academisation.Service/CommandValidations/UserRole/CreateUserRoleCommandValidator.cs b/Dfe.Academies.Academisation.Service/CommandValidations/UserRole/CreateUserRoleCommandValidator.cs deleted file mode 100644 index 992f7536f..000000000 --- a/Dfe.Academies.Academisation.Service/CommandValidations/UserRole/CreateUserRoleCommandValidator.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Dfe.Academies.Academisation.Service.Commands.UserRole; -using FluentValidation; - -namespace Dfe.Academies.Academisation.Service.CommandValidations.UserRole -{ - public class CreateUserRoleCommandValidator : AbstractValidator - { - public CreateUserRoleCommandValidator() - { - RuleFor(x => x.FullName) - .NotEmpty().WithMessage("Full name must not be empty") - .NotNull().WithMessage("Full name must not be null"); - - RuleFor(x => x.UserId) - .NotNull().WithMessage("User Id cannot be null.") - .NotEmpty().WithMessage("User Id cannot be an empty GUID."); - - RuleFor(x => x.EmailAddress) - .NotNull().WithMessage("Email address cannot be null.") - .NotEmpty().WithMessage("Email address cannot be empty.") - .EmailAddress().WithMessage("Email address must be a valid email address."); - - RuleFor(x => x.RoleId) - .IsInEnum().WithMessage("Role Id must be a valid value."); - } - } -} diff --git a/Dfe.Academies.Academisation.Service/CommandValidations/UserRole/SetUserRoleCommandValidator.cs b/Dfe.Academies.Academisation.Service/CommandValidations/UserRole/SetUserRoleCommandValidator.cs deleted file mode 100644 index 6cfe702df..000000000 --- a/Dfe.Academies.Academisation.Service/CommandValidations/UserRole/SetUserRoleCommandValidator.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Dfe.Academies.Academisation.Service.Commands.UserRole; -using FluentValidation; - -namespace Dfe.Academies.Academisation.Service.CommandValidations.UserRole -{ - public class SetUserRoleCommandValidator : AbstractValidator - { - public SetUserRoleCommandValidator() - { - RuleFor(x => x.EmailAddress) - .NotNull().WithMessage("Email address cannot be null.") - .NotEmpty().WithMessage("Email address cannot be empty.") - .EmailAddress().WithMessage("Email address must be a valid email address."); - - RuleFor(x => x.RoleId) - .IsInEnum().WithMessage("Role Id must be a valid value."); - } - } -} diff --git a/Dfe.Academies.Academisation.Service/Commands/UserRole/CreateUserRoleCommand.cs b/Dfe.Academies.Academisation.Service/Commands/UserRole/CreateUserRoleCommand.cs deleted file mode 100644 index e283086f2..000000000 --- a/Dfe.Academies.Academisation.Service/Commands/UserRole/CreateUserRoleCommand.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Dfe.Academies.Academisation.Core; -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; -using MediatR; - -namespace Dfe.Academies.Academisation.Service.Commands.UserRole -{ - public class CreateUserRoleCommand(Guid userId, string fullName, string emailAddress, RoleId roleId, bool isEnabled) : IRequest - { - public RoleId RoleId { get; set; } = roleId; - public bool IsEnabled { get; set; } = isEnabled; - public Guid UserId { get; set; } = userId; - public string FullName { get; set; } = fullName; - public string EmailAddress { get; set; } = emailAddress; - } -} diff --git a/Dfe.Academies.Academisation.Service/Commands/UserRole/CreateUserRoleCommandHandler.cs b/Dfe.Academies.Academisation.Service/Commands/UserRole/CreateUserRoleCommandHandler.cs deleted file mode 100644 index 1cc8fafd7..000000000 --- a/Dfe.Academies.Academisation.Service/Commands/UserRole/CreateUserRoleCommandHandler.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Dfe.Academies.Academisation.Core; -using Dfe.Academies.Academisation.Core.Utils; -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; -using Dfe.Academies.Academisation.Domain.UserRoleAggregate; -using MediatR; -using Microsoft.Extensions.Logging; - -namespace Dfe.Academies.Academisation.Service.Commands.UserRole -{ - public class CreateUserRoleCommandHandler(IUserRoleRepository userRoleRepository, IDateTimeProvider dateTimeProvider, IRoleInfo roleInfo, ILogger logger) : IRequestHandler - { - public async Task Handle(CreateUserRoleCommand message, CancellationToken cancellationToken) - { - logger.LogInformation("Creating user role: {value}", message); - - var userRole = new Domain.UserRoleAggregate.UserRole(roleInfo.GetId(message.RoleId), message.IsEnabled, dateTimeProvider.Now); - userRole.SetAssignedUser(message.UserId, message.FullName, message.EmailAddress); - - userRoleRepository.Insert(userRole); - await userRoleRepository.UnitOfWork.SaveChangesAsync(cancellationToken); - - return new CommandSuccessResult(); - } - } -} diff --git a/Dfe.Academies.Academisation.Service/Commands/UserRole/SetUserRoleCommand.cs b/Dfe.Academies.Academisation.Service/Commands/UserRole/SetUserRoleCommand.cs deleted file mode 100644 index 1ba4ab902..000000000 --- a/Dfe.Academies.Academisation.Service/Commands/UserRole/SetUserRoleCommand.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Dfe.Academies.Academisation.Core; -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; -using MediatR; - -namespace Dfe.Academies.Academisation.Service.Commands.UserRole -{ - public class SetUserRoleCommand(RoleId roleId, bool isEnabled) : IRequest - { - public RoleId RoleId { get; set; } = roleId; - public bool IsEnabled { get; set; } = isEnabled; - public string EmailAddress { get; set; } = string.Empty; - } -} diff --git a/Dfe.Academies.Academisation.Service/Commands/UserRole/SetUserRoleCommandHandler.cs b/Dfe.Academies.Academisation.Service/Commands/UserRole/SetUserRoleCommandHandler.cs deleted file mode 100644 index eabd2aed5..000000000 --- a/Dfe.Academies.Academisation.Service/Commands/UserRole/SetUserRoleCommandHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Dfe.Academies.Academisation.Core; -using Dfe.Academies.Academisation.Core.Utils; -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; -using Dfe.Academies.Academisation.Domain.UserRoleAggregate; -using MediatR; -using Microsoft.Extensions.Logging; - -namespace Dfe.Academies.Academisation.Service.Commands.UserRole -{ - public class SetUserRoleCommandHandler(IUserRoleRepository userRoleRepository, IDateTimeProvider dateTimeProvider, ILogger logger, IRoleInfo roleInfo) : IRequestHandler - { - public async Task Handle(SetUserRoleCommand message, CancellationToken cancellationToken) - { - logger.LogInformation("Creating user role: {value}", message); - - var userRole = await userRoleRepository.GetUserWithRoleAsync(message.EmailAddress, cancellationToken); - if(userRole == null) - { - return new NotFoundCommandResult(); - } - userRole.SetRole(roleInfo.GetId(message.RoleId), dateTimeProvider.Now, message.IsEnabled); - - userRoleRepository.Update((Domain.UserRoleAggregate.UserRole)userRole); - await userRoleRepository.UnitOfWork.SaveChangesAsync(cancellationToken); - - return new CommandSuccessResult(); - } - } -} diff --git a/Dfe.Academies.Academisation.Service/Queries/RoleCapabilitiesQueryService.cs b/Dfe.Academies.Academisation.Service/Queries/RoleCapabilitiesQueryService.cs new file mode 100644 index 000000000..70432e6c1 --- /dev/null +++ b/Dfe.Academies.Academisation.Service/Queries/RoleCapabilitiesQueryService.cs @@ -0,0 +1,16 @@ +using Dfe.Academies.Academisation.Domain.Core.RoleCapabilitiesAggregate; +using Dfe.Academies.Academisation.IService.Query; +using Dfe.Academies.Academisation.IService.ServiceModels.RoleCapabilities; + +namespace Dfe.Academies.Academisation.Service.Queries +{ + public class RoleCapabilitiesQueryService(IRoleInfo roleInfo): IRoleCapabilitiesQueryService + { + public RoleCapabilitiesModel GetRolesCapabilitiesAsync(List roles) + { + var capabilities = new List(); + roles.ForEach(role => capabilities.AddRange(roleInfo.GetRoleCapabilities(role))); + return new RoleCapabilitiesModel(capabilities.Distinct().ToList()); + } + } +} diff --git a/Dfe.Academies.Academisation.Service/Queries/UserRoleQueryService.cs b/Dfe.Academies.Academisation.Service/Queries/UserRoleQueryService.cs deleted file mode 100644 index eaff14e96..000000000 --- a/Dfe.Academies.Academisation.Service/Queries/UserRoleQueryService.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; -using Dfe.Academies.Academisation.Domain.UserRoleAggregate; -using Dfe.Academies.Academisation.IService.Query; -using Dfe.Academies.Academisation.IService.ServiceModels.Legacy.ProjectAggregate; -using Dfe.Academies.Academisation.IService.ServiceModels.UserRole; -using Dfe.Academies.Academisation.Service.Factories; - -namespace Dfe.Academies.Academisation.Service.Queries -{ - public class UserRoleQueryService(IUserRoleRepository userRoleRepository, IRoleInfo roleInfo): IUserRoleQueryService - { - public async Task GetUserRoleCapabilitiesAsync(string email, CancellationToken cancellationToken) - => new RoleCapabilitiesModel(await userRoleRepository.GetUserRoleCapabilitiesAsync(email, cancellationToken)); - - public async Task> SearchUsersAsync(string? searchTerm, RoleId? roleId, int page, int count, CancellationToken cancellationToken) - { - var userRoles = await userRoleRepository.SearchUsersAsync(searchTerm, roleId, cancellationToken); - - var pageResponse = PagingResponseFactory.Create("user-role/users", page, count, userRoles.Count(), []); - - var data = userRoles.Select(userRole - => new UserRoleModel(roleInfo.GetEnum(userRole.RoleId), userRole.AssignedUser!.FullName, userRole.AssignedUser!.EmailAddress)).ToList(); - - return new PagedDataResponse(data, pageResponse); - } - } -} diff --git a/Dfe.Academies.Academisation.SubcutaneousTest/ApiIntegrationTestBase.cs b/Dfe.Academies.Academisation.SubcutaneousTest/ApiIntegrationTestBase.cs index 1a13e1ce0..1a2ad7d01 100644 --- a/Dfe.Academies.Academisation.SubcutaneousTest/ApiIntegrationTestBase.cs +++ b/Dfe.Academies.Academisation.SubcutaneousTest/ApiIntegrationTestBase.cs @@ -175,9 +175,9 @@ private static void ConfigureAppConfiguration(IWebHostBuilder builder, string ap new ("AuthenticationConfig:ApiKeys:0", apiKey), new ("AcademiesUrl", "https://localhost:2730"), new ("AcademiesApiKey", "f6cbde5b-1252-4439-864c-16956af671d2"), - new ("RoleIds:Manager", "71eaea6e-44e2-45b4-bc1b-7542b38200b3"), - new ("RoleIds:Standard", "e9f6ef60-0b4d-439a-ba98-52d11c4d6737"), - new ("RoleIds:SuperAdmin", "f61975e2-8669-4524-89e1-e970ca792f03") + new ("RoleIds:ConversionCreation", "ConversionCreation"), + new ("RoleIds:TransferCreation", "TransferCreation"), + new ("RoleIds:Support", "Support") }; configBuilder.AddInMemoryCollection(inMemorySettings!); }); diff --git a/Dfe.Academies.Academisation.SubcutaneousTest/RoleCapabilities/RoleCapabilitiesTests.cs b/Dfe.Academies.Academisation.SubcutaneousTest/RoleCapabilities/RoleCapabilitiesTests.cs new file mode 100644 index 000000000..b86d5a9b8 --- /dev/null +++ b/Dfe.Academies.Academisation.SubcutaneousTest/RoleCapabilities/RoleCapabilitiesTests.cs @@ -0,0 +1,49 @@ +using System.Net; +using Dfe.Academies.Academisation.Domain.Core.RoleCapabilitiesAggregate; +using Dfe.Academies.Academisation.SubcutaneousTest.Utils; +using Dfe.Academies.Academisation.IService.ServiceModels.RoleCapabilities; +using Microsoft.Extensions.DependencyInjection; + +namespace Dfe.Academies.Academisation.SubcutaneousTest.RoleCapabilities +{ + public class RoleCapabilitiesTests : ApiIntegrationTestBase + { + private readonly HttpClient _client; + private readonly IRoleInfo _roleInfo; + + public RoleCapabilitiesTests() + { + _client = CreateClient(); + _roleInfo = ServiceProvider.GetRequiredService(); + } + + [Theory] + [InlineData("ConversionCreation")] + [InlineData("ConversionCreation", "TransferCreation")] + [InlineData("ConversionCreation", "TransferCreation", "Support")] + public async Task GetUserRoleCapabilities_ShouldReturnCapabilities(params string[] roles) + { + // Arrange + var capabilities = new List(); + roles.ToList().ForEach(role => capabilities.AddRange(_roleInfo.GetRoleCapabilities(role))); + + // Action + var httpResponseMessage = await _client.PostAsJsonAsync("role-capabilities/capabilities", roles, CancellationToken); + + // Assert + await VerifyRoleCapabilities(httpResponseMessage, capabilities.Distinct().ToList()); + } + + private static async Task VerifyRoleCapabilities(HttpResponseMessage httpResponseMessage, List capabilities) + { + Assert.True(httpResponseMessage.IsSuccessStatusCode); + Assert.Equal(httpResponseMessage.StatusCode.GetHashCode(), HttpStatusCode.OK.GetHashCode()); + var roleCapabilitiesModel = await httpResponseMessage.ConvertResponseToEnumTypeAsync(); + Assert.Equal(roleCapabilitiesModel.Capabilities.Count, capabilities.Count); + for (int i = 0; i < capabilities.Count; i++) + { + Assert.Equal(capabilities[i], roleCapabilitiesModel.Capabilities[i]); + } + } + } +} diff --git a/Dfe.Academies.Academisation.SubcutaneousTest/UserRole/UserRoleTests.cs b/Dfe.Academies.Academisation.SubcutaneousTest/UserRole/UserRoleTests.cs deleted file mode 100644 index ff009bd37..000000000 --- a/Dfe.Academies.Academisation.SubcutaneousTest/UserRole/UserRoleTests.cs +++ /dev/null @@ -1,216 +0,0 @@ -using System.Net; -using AutoFixture; -using Dfe.Academies.Academisation.Data; -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; -using Dfe.Academies.Academisation.IDomain.UserRoleAggregate; -using Dfe.Academies.Academisation.Service.Commands.UserRole; -using Dfe.Academies.Academisation.WebApi.Models; -using Microsoft.EntityFrameworkCore; -using Dfe.Academies.Academisation.SubcutaneousTest.Utils; -using Dfe.Academies.Academisation.IService.ServiceModels.UserRole; -using Microsoft.Extensions.DependencyInjection; - -namespace Dfe.Academies.Academisation.SubcutaneousTest.UserRole -{ - public class UserRoleTests : ApiIntegrationTestBase - { - private readonly HttpClient _client; - private readonly AcademisationContext _context; - private readonly IRoleInfo _roleInfo; - - public UserRoleTests() - { - _client = CreateClient(); - _context = GetDBContext(); - _roleInfo = ServiceProvider.GetRequiredService(); - } - - [Fact] - public async Task CreateUserRole_ShouldCreateSuccessfully() - { - // Arrange - var command = new CreateUserRoleCommand(Guid.NewGuid(), - Fixture.Create()[..7], $"{Fixture.Create()[..5]}@email.com", RoleId.Standard, true); - - // Action - var httpResponseMessage = await _client.PostAsJsonAsync("user-role/create-user-role", command, CancellationToken); - - // Assert - Assert.True(httpResponseMessage.IsSuccessStatusCode); - var userRole = await _context.UserRoles.AsNoTracking().FirstOrDefaultAsync(x => x.AssignedUser!.EmailAddress == command.EmailAddress); - Assert.NotNull(userRole); - Assert.Equal(userRole.RoleId, _roleInfo.GetId(command.RoleId)); - Assert.Equal(userRole.IsEnabled, command.IsEnabled); - Assert.Equal(userRole.AssignedUser!.FullName, command.FullName); - Assert.Equal(userRole.AssignedUser!.Id, command.UserId); - } - - [Fact] - public async Task CreateUserRole_ShouldReturnValidationError() - { - // Arrange - var errorCount = 2; - var errorTitle = "One or more validation errors occurred."; - var command = new CreateUserRoleCommand(Guid.NewGuid(), string.Empty, $"{Fixture.Create()[..5]}", RoleId.Standard, true); - - // Action - var httpResponseMessage = await _client.PostAsJsonAsync("user-role/create-user-role", command, CancellationToken); - - // Assert - Assert.False(httpResponseMessage.IsSuccessStatusCode); - var userRole = await _context.UserRoles.AsNoTracking().FirstOrDefaultAsync(x => x.AssignedUser!.EmailAddress == command.EmailAddress); - Assert.Null(userRole); - var errorModel = await httpResponseMessage.ConvertResponseToTypeAsync(); - Assert.NotNull(errorModel); - Assert.Equal(errorModel.Status, HttpStatusCode.BadRequest.GetHashCode()); - Assert.Equal(errorModel.Title, errorTitle); - Assert.Equal(errorModel.Errors.DomainValidations.Count, errorCount); - } - - [Fact] - public async Task SetUserRole_ShouldCreateSuccessfully() - { - // Arrange - var userRole = await CreateUserRole(); - var command = new SetUserRoleCommand(RoleId.Standard, true); - - // Action - var httpResponseMessage = await _client.PutAsJsonAsync($"user-role/{userRole.AssignedUser!.EmailAddress}/assign-user-role", command, CancellationToken); - - // Assert - Assert.True(httpResponseMessage.IsSuccessStatusCode); - var dbUserRole = await _context.UserRoles.AsNoTracking().FirstOrDefaultAsync(x => x.AssignedUser!.EmailAddress == userRole.AssignedUser!.EmailAddress); - Assert.NotNull(dbUserRole); - Assert.Equal(dbUserRole!.RoleId, _roleInfo.GetId(command.RoleId)); - Assert.Equal(dbUserRole.IsEnabled, command.IsEnabled); - } - - [Fact] - public async Task SetUserRole_ShouldReturnValidationError() - { - // Arrange - var userRole = await CreateUserRole(); - var errorCount = 1; - var email = $"{Fixture.Create()[..5]}"; - var errorTitle = "One or more validation errors occurred."; - var command = new SetUserRoleCommand(RoleId.Standard, true); - - // Action - var httpResponseMessage = await _client.PutAsJsonAsync($"user-role/{email}/assign-user-role", command, CancellationToken); - - // Assert - Assert.False(httpResponseMessage.IsSuccessStatusCode); - var dbUserRole = await _context.UserRoles.AsNoTracking().FirstOrDefaultAsync(x => x.AssignedUser!.EmailAddress == userRole.AssignedUser!.EmailAddress); - Assert.NotNull(dbUserRole); - Assert.Equal(dbUserRole.RoleId, userRole.RoleId); - Assert.Equal(dbUserRole.IsEnabled, userRole.IsEnabled); - var errorModel = await httpResponseMessage.ConvertResponseToTypeAsync(); - Assert.NotNull(errorModel); - Assert.Equal(errorModel.Status, HttpStatusCode.BadRequest.GetHashCode()); - Assert.Equal(errorModel.Title, errorTitle); - Assert.Equal(errorModel.Errors.DomainValidations.Count, errorCount); - } - - [Fact] - public async Task SetUserRole_ShouldReturnNotFound() - { - // Arrange - var userRole = await CreateUserRole(); - var email = $"{Fixture.Create()[..5]}@email.com"; - var errorTitle = "Not Found"; - var command = new SetUserRoleCommand(RoleId.Standard, true); - - // Action - var httpResponseMessage = await _client.PutAsJsonAsync($"user-role/{email}/assign-user-role", command, CancellationToken); - - // Assert - Assert.False(httpResponseMessage.IsSuccessStatusCode); - var dbUserRole = await _context.UserRoles.AsNoTracking().FirstOrDefaultAsync(x => x.AssignedUser!.EmailAddress == userRole.AssignedUser!.EmailAddress); - Assert.NotNull(dbUserRole); - Assert.Equal(dbUserRole.RoleId, userRole.RoleId); - Assert.Equal(dbUserRole.IsEnabled, userRole.IsEnabled); - var errorModel = await httpResponseMessage.ConvertResponseToTypeAsync(); - Assert.NotNull(errorModel); - Assert.Equal(errorModel.Status, HttpStatusCode.NotFound.GetHashCode()); - Assert.Equal(errorModel.Title, errorTitle); - } - - [Fact] - public async Task GetUserRoleCapabilities_ShouldReturnCapabilities() - { - // Arrange - var userRole = await CreateUserRole(); - var capabilities = Roles.GetRoleCapabilities(_roleInfo.GetEnum(userRole.RoleId)); - - // Action - var httpResponseMessage = await _client.GetAsync($"user-role/{userRole.AssignedUser!.EmailAddress}", CancellationToken); - - // Assert - await VerifyRoleCapabilities(httpResponseMessage, capabilities); - } - - [Fact] - public async Task GetUserRoleCapabilities_ShouldReturnStandardRoleCapabilitiesIfUserDoesNotExists() - { - // Arrange - var email = $"{Fixture.Create()}@notfound.com"; - var capabilities = Roles.GetRoleCapabilities(RoleId.Standard); - - // Action - var httpResponseMessage = await _client.GetAsync($"user-role/{email}", CancellationToken); - - // Assert - await VerifyRoleCapabilities(httpResponseMessage, capabilities); - } - - [Theory] - [InlineData("","first.lastname@email.com", null)] - [InlineData("Full Name", "", null)] - [InlineData("", "", RoleId.Standard)] - public async Task SearchUsers_ShouldReturnUsers(string fullName, string email, RoleId? roleId) - { - // Arrange - var searchItem = !string.IsNullOrEmpty(fullName) ? fullName : (!string.IsNullOrEmpty(email) ? email : null); - var searchModel = new UserRoleSearchModel(1, 1, searchItem, roleId); - var userRole = await CreateUserRole(); - - // Action - var httpResponseMessage = await _client.PostAsJsonAsync("/user-role/search-users", searchModel, CancellationToken); - - // Assert - Assert.True(httpResponseMessage.IsSuccessStatusCode); - Assert.Equal(httpResponseMessage.StatusCode.GetHashCode(), HttpStatusCode.OK.GetHashCode()); - var usersModel = await httpResponseMessage.ConvertResponseToPagedDataResponseAsync(); - - usersModel.Data.ToList().ForEach(user => - { - Assert.Equal(user.Email, userRole.AssignedUser!.EmailAddress); - Assert.Equal(user.FullName, userRole.AssignedUser!.FullName); - Assert.Equal(_roleInfo.GetId(user.RoleId), userRole.RoleId); - }); - } - - private async Task CreateUserRole(string fullName = "Full Name", string emailAddress = "first.lastname@email.com") - { - var userRole = new Domain.UserRoleAggregate.UserRole(_roleInfo.GetId(RoleId.Standard), true, DateTime.Now); - userRole.SetAssignedUser(Guid.NewGuid(), fullName, emailAddress); - - _context.UserRoles.Add(userRole); - await _context.SaveChangesAsync(CancellationToken); - - return userRole; - } - - private static async Task VerifyRoleCapabilities(HttpResponseMessage httpResponseMessage, List capabilities) - { - Assert.True(httpResponseMessage.IsSuccessStatusCode); - Assert.Equal(httpResponseMessage.StatusCode.GetHashCode(), HttpStatusCode.OK.GetHashCode()); - var roleCapabilitiesModel = await httpResponseMessage.ConvertResponseToEnumTypeAsync(); - - for (int i = 0; i < capabilities.Count; i++) - { - Assert.Equal(capabilities[i], roleCapabilitiesModel.Capabilities[i]); - } - } - } -} diff --git a/Dfe.Academies.Academisation.SubcutaneousTest/Utils/HttpResponseMessageExtensions.cs b/Dfe.Academies.Academisation.SubcutaneousTest/Utils/HttpResponseMessageExtensions.cs index d2267ffc7..f88df5f2e 100644 --- a/Dfe.Academies.Academisation.SubcutaneousTest/Utils/HttpResponseMessageExtensions.cs +++ b/Dfe.Academies.Academisation.SubcutaneousTest/Utils/HttpResponseMessageExtensions.cs @@ -1,10 +1,7 @@ using System.Text.Json.Serialization; using System.Text.Json; using System.Net.Http.Json; -using Microsoft.Extensions.Options; using Dfe.Academies.Academisation.IService.ServiceModels.Legacy.ProjectAggregate; -using Azure; -using Dfe.Academies.Academisation.IService.ServiceModels.UserRole; namespace Dfe.Academies.Academisation.SubcutaneousTest.Utils { diff --git a/Dfe.Academies.Academisation.WebApi/Controllers/ProjectGroupController.cs b/Dfe.Academies.Academisation.WebApi/Controllers/ProjectGroupController.cs index 0477fb6f8..a28d64c1e 100644 --- a/Dfe.Academies.Academisation.WebApi/Controllers/ProjectGroupController.cs +++ b/Dfe.Academies.Academisation.WebApi/Controllers/ProjectGroupController.cs @@ -9,13 +9,13 @@ namespace Dfe.Academies.Academisation.WebApi.Controllers { - [Route("project-group")] + [Route("project-group/")] [ApiController] [ProducesResponseType(StatusCodes.Status401Unauthorized)] public class ProjectGroupController(IMediator mediator, ILogger logger, IProjectGroupQueryService projectGroupQueryService) : ControllerBase { - [HttpPost("/project-group/create-project-group", Name = "CreateProjectGroup")] + [HttpPost("create-project-group", Name = "CreateProjectGroup")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task> CreateProjectGroup( @@ -69,7 +69,7 @@ public async Task AssignProjectGroupUser(string referenceNumber, }; } - [HttpPost("/project-group/get-project-groups", Name = "GetProjectGroups")] + [HttpPost("get-project-groups", Name = "GetProjectGroups")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetProjectGroups(ConversionProjectSearchModel? searchModel, CancellationToken cancellationToken) diff --git a/Dfe.Academies.Academisation.WebApi/Controllers/RoleCapabilitiesController.cs b/Dfe.Academies.Academisation.WebApi/Controllers/RoleCapabilitiesController.cs new file mode 100644 index 000000000..9b3fd2fdd --- /dev/null +++ b/Dfe.Academies.Academisation.WebApi/Controllers/RoleCapabilitiesController.cs @@ -0,0 +1,28 @@ +using Dfe.Academies.Academisation.IService.Query; +using Dfe.Academies.Academisation.IService.ServiceModels.RoleCapabilities; +using Microsoft.AspNetCore.Mvc; + +namespace Dfe.Academies.Academisation.WebApi.Controllers +{ + [Route("role-capabilities/")] + [ApiController] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + public class RoleCapabilitiesController(ILogger logger, IRoleCapabilitiesQueryService userRoleQueryService) : ControllerBase + { + [HttpPost("capabilities", Name = "GetRolesCapabilities")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public ActionResult GetRolesCapabilities(List roles, CancellationToken cancellationToken) + { + logger.LogInformation("Getting roles capablities with roles: {roles}", roles); + var roleCapabiltiesModel = userRoleQueryService.GetRolesCapabilitiesAsync(roles); + + if (roleCapabiltiesModel == null || roleCapabiltiesModel.Capabilities.Count == 0) + { + return NotFound($"User role capabilities with {roles} email not found."); + } + + return Ok(roleCapabiltiesModel); + } + } +} diff --git a/Dfe.Academies.Academisation.WebApi/Controllers/UserRoleController.cs b/Dfe.Academies.Academisation.WebApi/Controllers/UserRoleController.cs deleted file mode 100644 index 1bc6e0bb8..000000000 --- a/Dfe.Academies.Academisation.WebApi/Controllers/UserRoleController.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Dfe.Academies.Academisation.Core; -using Dfe.Academies.Academisation.IService.Query; -using Dfe.Academies.Academisation.IService.ServiceModels.Legacy.ProjectAggregate; -using Dfe.Academies.Academisation.IService.ServiceModels.UserRole; -using Dfe.Academies.Academisation.Service.Commands.UserRole; -using Dfe.Academies.Academisation.WebApi.ActionResults; -using MediatR; -using Microsoft.AspNetCore.Mvc; - -namespace Dfe.Academies.Academisation.WebApi.Controllers -{ - [Route("user-role")] - [ApiController] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public class UserRoleController(IMediator mediator, ILogger logger, IUserRoleQueryService userRoleQueryService) : ControllerBase - { - [HttpPost("/user-role/create-user-role", Name = "CreateUserRole")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task CreateUserRole([FromBody] CreateUserRoleCommand command, CancellationToken cancellationToken) - { - logger.LogInformation("Creating user role: {value}", command); - var result = await mediator.Send(command, cancellationToken); - - return result switch - { - CommandSuccessResult => Ok(), - _ => new InternalServerErrorObjectResult("Error serving request") - }; - } - [HttpPut("{email}/assign-user-role", Name = "SetUserRole")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task SetUserRole(string email, [FromBody] SetUserRoleCommand command, CancellationToken cancellationToken) - { - logger.LogInformation("Setting user with a different role: {value}", command); - command.EmailAddress = email; - var result = await mediator.Send(command, cancellationToken).ConfigureAwait(false); - - return result switch - { - CommandSuccessResult => Ok(), - NotFoundCommandResult => NotFound(), - CommandValidationErrorResult validationErrorResult => new BadRequestObjectResult(validationErrorResult.ValidationErrors), - _ => new InternalServerErrorObjectResult("Error serving request") - }; - } - - [HttpGet("{email}", Name = "GetUserRoleCapabilities")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task> GetUserRoleCapabilities(string email, CancellationToken cancellationToken) - { - var roleCapabiltiesModel = await userRoleQueryService.GetUserRoleCapabilitiesAsync(email, cancellationToken); - - if (roleCapabiltiesModel == null || roleCapabiltiesModel.Capabilities.Count == 0) - { - return NotFound($"User role capabilities with {email} email not found."); - } - - return Ok(roleCapabiltiesModel); - } - - [HttpPost("/user-role/search-users", Name = "SearchUsers")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> SearchUsers(UserRoleSearchModel searchModel, CancellationToken cancellationToken) - { - var result = await userRoleQueryService.SearchUsersAsync(searchModel.searchTerm, searchModel.RoleId, searchModel.Page, searchModel.Count, cancellationToken); - - return result is null ? NotFound() : Ok(result); - } - } -} diff --git a/Dfe.Academies.Academisation.WebApi/Program.cs b/Dfe.Academies.Academisation.WebApi/Program.cs index 546c92b84..4bcc105d9 100644 --- a/Dfe.Academies.Academisation.WebApi/Program.cs +++ b/Dfe.Academies.Academisation.WebApi/Program.cs @@ -9,13 +9,12 @@ using Dfe.Academies.Academisation.Domain; using Dfe.Academies.Academisation.Domain.ApplicationAggregate; using Dfe.Academies.Academisation.Domain.ConversionAdvisoryBoardDecisionAggregate; -using Dfe.Academies.Academisation.Domain.Core.UserRoleAggregate; +using Dfe.Academies.Academisation.Domain.Core.RoleCapabilitiesAggregate; using Dfe.Academies.Academisation.Domain.FormAMatProjectAggregate; using Dfe.Academies.Academisation.Domain.OpeningDateHistoryAggregate; using Dfe.Academies.Academisation.Domain.ProjectAggregate; using Dfe.Academies.Academisation.Domain.ProjectGroupsAggregate; using Dfe.Academies.Academisation.Domain.TransferProjectAggregate; -using Dfe.Academies.Academisation.Domain.UserRoleAggregate; using Dfe.Academies.Academisation.IDomain.ApplicationAggregate; using Dfe.Academies.Academisation.IDomain.ConversionAdvisoryBoardDecisionAggregate; using Dfe.Academies.Academisation.IDomain.ProjectAggregate; @@ -29,10 +28,8 @@ using Dfe.Academies.Academisation.Service.Commands.ProjectGroup; using Dfe.Academies.Academisation.Service.Commands.ProjectGroup.QueryService; using Dfe.Academies.Academisation.Service.Commands.TransferProject; -using Dfe.Academies.Academisation.Service.Commands.UserRole; using Dfe.Academies.Academisation.Service.CommandValidations; using Dfe.Academies.Academisation.Service.CommandValidations.ProjectGroup; -using Dfe.Academies.Academisation.Service.CommandValidations.UserRole; using Dfe.Academies.Academisation.Service.Mappers.OpeningDateHistoryMapper; using Dfe.Academies.Academisation.Service.Queries; using Dfe.Academies.Academisation.WebApi.AutoMapper; @@ -50,13 +47,6 @@ using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; using Swashbuckle.AspNetCore.SwaggerUI; -using System.Linq; -using Microsoft.IdentityModel.Tokens; -using DocumentFormat.OpenXml.InkML; -using Microsoft.Extensions.Options; -using Microsoft.Extensions.DependencyInjection; -using JsonSerializer = System.Text.Json.JsonSerializer; -using System.Configuration; var builder = WebApplication.CreateBuilder(args); @@ -123,9 +113,6 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); -builder.Services.AddScoped(); - - // Queries and services builder.Services.AddScoped(); @@ -138,7 +125,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); -builder.Services.AddScoped(); +builder.Services.AddScoped(); // utils builder.Services.AddSingleton(); @@ -212,8 +199,6 @@ builder.Services.AddScoped(typeof(IValidator), typeof(CreateTransferProjectCommandValidator)); builder.Services.AddScoped(typeof(IValidator), typeof(CreateProjectGroupCommandValidator)); builder.Services.AddScoped(typeof(IValidator), typeof(SetProjectGroupCommandValidator)); -builder.Services.AddScoped(typeof(IValidator), typeof(CreateUserRoleCommandValidator)); -builder.Services.AddScoped(typeof(IValidator), typeof(SetUserRoleCommandValidator)); builder.Services.AddScoped(typeof(IValidator), typeof(SetProjectGroupAssignUserCommandValidator)); builder.Services.AddHostedService(); @@ -329,7 +314,7 @@ public partial class Program public static string GetAppName() { - var appName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name ?? string.Empty; + var appName = Assembly.GetExecutingAssembly().GetName().Name ?? string.Empty; return appName; } diff --git a/Dfe.Academies.Academisation.WebApi/appsettings.json b/Dfe.Academies.Academisation.WebApi/appsettings.json index 4632b9a9d..f9fed0cab 100644 --- a/Dfe.Academies.Academisation.WebApi/appsettings.json +++ b/Dfe.Academies.Academisation.WebApi/appsettings.json @@ -17,8 +17,8 @@ "ConnectionString": "" }, "RoleIds": { - "SuperAdmin": "", - "Manager": "", - "Standard": "" + "ConversionCreation": "", + "TransferCreation": "", + "SuperAdmin": "" } }