From 25f444fd42dead8e9e66e13fcc82a392fef45228 Mon Sep 17 00:00:00 2001 From: Maxim Rychkov Date: Wed, 25 Mar 2026 14:10:46 +0500 Subject: [PATCH 1/2] feat: add CanViewAllProjects and CanViewAllTimeTrackerEntries perms --- Core/Models/Permissions.cs | 2 ++ DataAccess/Mapping/MappingData.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Core/Models/Permissions.cs b/Core/Models/Permissions.cs index 1fc87ab..32c9b3b 100644 --- a/Core/Models/Permissions.cs +++ b/Core/Models/Permissions.cs @@ -42,6 +42,8 @@ public static class Permissions public const string AUTO_TESTS_ONLY_IsEntriesHardDeleteAllowed = "AUTO_TESTS_ONLY_IsEntriesHardDeleteAllowed"; public const string CanManagePersonalTimeTracker = "CanManagePersonalTimeTracker"; + public const string CanViewAllTimeTrackerEntries = "CanViewAllTimeTrackerEntries"; + public const string CanViewAllProjects = "CanViewAllProjects"; public const string CanViewInvoices = "CanViewInvoices"; diff --git a/DataAccess/Mapping/MappingData.cs b/DataAccess/Mapping/MappingData.cs index 2a44f7d..4c54d51 100644 --- a/DataAccess/Mapping/MappingData.cs +++ b/DataAccess/Mapping/MappingData.cs @@ -43,6 +43,8 @@ internal static class MappingData new Permission(Permissions.CanViewItems), new Permission(Permissions.AUTO_TESTS_ONLY_IsEntriesHardDeleteAllowed), new Permission(Permissions.CanManagePersonalTimeTracker), + new Permission(Permissions.CanViewAllTimeTrackerEntries), + new Permission(Permissions.CanViewAllProjects), new Permission(Permissions.CanViewInvoices), }; From 2d0bddf673d344f3f0a1e64f2261f4b5160fbfc7 Mon Sep 17 00:00:00 2001 From: Maxim Rychkov Date: Wed, 25 Mar 2026 14:12:16 +0500 Subject: [PATCH 2/2] feat: add migration for new permissions --- ...tsAndAllTimeEntriesPermissions.Designer.cs | 256 ++++++++++++++++++ ...AddProjectsAndAllTimeEntriesPermissions.cs | 44 +++ .../Migrations/UsersDbContextModelSnapshot.cs | 4 +- 3 files changed, 302 insertions(+), 2 deletions(-) create mode 100644 DataAccess/Migrations/20260325091144_AddProjectsAndAllTimeEntriesPermissions.Designer.cs create mode 100644 DataAccess/Migrations/20260325091144_AddProjectsAndAllTimeEntriesPermissions.cs diff --git a/DataAccess/Migrations/20260325091144_AddProjectsAndAllTimeEntriesPermissions.Designer.cs b/DataAccess/Migrations/20260325091144_AddProjectsAndAllTimeEntriesPermissions.Designer.cs new file mode 100644 index 0000000..36a8825 --- /dev/null +++ b/DataAccess/Migrations/20260325091144_AddProjectsAndAllTimeEntriesPermissions.Designer.cs @@ -0,0 +1,256 @@ +// +using System; +using DataAccess; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NodaTime; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace UserManagementService.DataAccess.Migrations +{ + [DbContext(typeof(AccountsDbContext))] + [Migration("20260325091144_AddProjectsAndAllTimeEntriesPermissions")] + partial class AddProjectsAndAllTimeEntriesPermissions + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Core.Entities.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CorporateEmail") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedAtUtc") + .HasColumnType("timestamp with time zone"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsBlocked") + .HasColumnType("boolean"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("MiddleName") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("TenantId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasDefaultValue(1L); + + b.HasKey("Id"); + + b.HasIndex("CorporateEmail") + .IsUnique(); + + b.HasIndex("TenantId"); + + b.ToTable("Accounts"); + + b.HasData( + new + { + Id = 2L, + CorporateEmail = "inner-circle-admin@tourmalinecore.com", + CreatedAt = NodaTime.Instant.FromUnixTimeTicks(15778368000000000L), + FirstName = "Admin", + IsBlocked = false, + LastName = "Admin", + MiddleName = "Admin", + TenantId = 1L + }, + new + { + Id = 1L, + CorporateEmail = "ceo@tourmalinecore.com", + CreatedAt = NodaTime.Instant.FromUnixTimeTicks(15778368000000000L), + FirstName = "Ceo", + IsBlocked = false, + LastName = "Ceo", + MiddleName = "Ceo", + TenantId = 1L + }, + new + { + Id = 3L, + CorporateEmail = "trial@tourmalinecore.com", + CreatedAt = NodaTime.Instant.FromUnixTimeTicks(15778368000000000L), + FirstName = "Trial", + IsBlocked = false, + LastName = "Trial", + MiddleName = "Trial", + TenantId = 1L + }); + }); + + modelBuilder.Entity("Core.Entities.AccountRole", b => + { + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("RoleId") + .HasColumnType("bigint"); + + b.HasKey("AccountId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AccountRoles"); + + b.HasData( + new + { + AccountId = 2L, + RoleId = 1L + }, + new + { + AccountId = 1L, + RoleId = 2L + }, + new + { + AccountId = 3L, + RoleId = 2L + }); + }); + + modelBuilder.Entity("Core.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Permissions") + .IsRequired() + .HasColumnType("text[]"); + + b.HasKey("Id"); + + b.ToTable("Roles"); + + b.HasData( + new + { + Id = 1L, + Name = "Admin", + Permissions = new[] { "ViewPersonalProfile", "ViewContacts", "ViewSalaryAndDocumentsData", "EditFullEmployeesData", "AccessAnalyticalForecastsPage", "ViewAccounts", "ManageAccounts", "ViewRoles", "ManageRoles", "CanRequestCompensations", "CanManageCompensations", "CanManageDocuments", "CanManageTenants", "IsTenantsHardDeleteAllowed", "IsAccountsHardDeleteAllowed", "IsCompensationsHardDeleteAllowed", "CanViewBooks", "CanManageBooks", "IsBooksHardDeleteAllowed", "AUTO_TESTS_ONLY_IsSetUserPasswordBypassingEmailConfirmationAllowed", "AUTO_TESTS_ONLY_IsItemTypesHardDeleteAllowed", "CanManageItemsTypes", "CanViewItemsTypes", "AUTO_TESTS_ONLY_IsItemsHardDeleteAllowed", "CanManageItems", "CanViewItems", "AUTO_TESTS_ONLY_IsEntriesHardDeleteAllowed", "CanManagePersonalTimeTracker", "CanViewAllTimeTrackerEntries", "CanViewAllProjects", "CanViewInvoices" } + }, + new + { + Id = 2L, + Name = "CEO", + Permissions = new[] { "ViewPersonalProfile", "ViewContacts", "ViewSalaryAndDocumentsData", "EditFullEmployeesData", "AccessAnalyticalForecastsPage", "ViewAccounts", "ManageAccounts", "ViewRoles", "ManageRoles", "CanRequestCompensations", "CanManageCompensations", "CanManageDocuments", "CanManageTenants", "IsTenantsHardDeleteAllowed", "IsAccountsHardDeleteAllowed", "IsCompensationsHardDeleteAllowed", "CanViewBooks", "CanManageBooks", "IsBooksHardDeleteAllowed", "AUTO_TESTS_ONLY_IsSetUserPasswordBypassingEmailConfirmationAllowed", "AUTO_TESTS_ONLY_IsItemTypesHardDeleteAllowed", "CanManageItemsTypes", "CanViewItemsTypes", "AUTO_TESTS_ONLY_IsItemsHardDeleteAllowed", "CanManageItems", "CanViewItems", "AUTO_TESTS_ONLY_IsEntriesHardDeleteAllowed", "CanManagePersonalTimeTracker", "CanViewAllTimeTrackerEntries", "CanViewAllProjects", "CanViewInvoices" } + }); + }); + + modelBuilder.Entity("Core.Entities.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Tenants"); + + b.HasData( + new + { + Id = 1L, + Name = "TourmalineCore" + }, + new + { + Id = 2L, + Name = "Test" + }); + }); + + modelBuilder.Entity("Core.Entities.Account", b => + { + b.HasOne("Core.Entities.Tenant", "Tenant") + .WithMany("Accounts") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Core.Entities.AccountRole", b => + { + b.HasOne("Core.Entities.Account", "Account") + .WithMany("AccountRoles") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Core.Entities.Role", "Role") + .WithMany("AccountRoles") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("Core.Entities.Account", b => + { + b.Navigation("AccountRoles"); + }); + + modelBuilder.Entity("Core.Entities.Role", b => + { + b.Navigation("AccountRoles"); + }); + + modelBuilder.Entity("Core.Entities.Tenant", b => + { + b.Navigation("Accounts"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DataAccess/Migrations/20260325091144_AddProjectsAndAllTimeEntriesPermissions.cs b/DataAccess/Migrations/20260325091144_AddProjectsAndAllTimeEntriesPermissions.cs new file mode 100644 index 0000000..0a82a08 --- /dev/null +++ b/DataAccess/Migrations/20260325091144_AddProjectsAndAllTimeEntriesPermissions.cs @@ -0,0 +1,44 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace UserManagementService.DataAccess.Migrations +{ + public partial class AddProjectsAndAllTimeEntriesPermissions : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.UpdateData( + table: "Roles", + keyColumn: "Id", + keyValue: 1L, + column: "Permissions", + value: new[] { "ViewPersonalProfile", "ViewContacts", "ViewSalaryAndDocumentsData", "EditFullEmployeesData", "AccessAnalyticalForecastsPage", "ViewAccounts", "ManageAccounts", "ViewRoles", "ManageRoles", "CanRequestCompensations", "CanManageCompensations", "CanManageDocuments", "CanManageTenants", "IsTenantsHardDeleteAllowed", "IsAccountsHardDeleteAllowed", "IsCompensationsHardDeleteAllowed", "CanViewBooks", "CanManageBooks", "IsBooksHardDeleteAllowed", "AUTO_TESTS_ONLY_IsSetUserPasswordBypassingEmailConfirmationAllowed", "AUTO_TESTS_ONLY_IsItemTypesHardDeleteAllowed", "CanManageItemsTypes", "CanViewItemsTypes", "AUTO_TESTS_ONLY_IsItemsHardDeleteAllowed", "CanManageItems", "CanViewItems", "AUTO_TESTS_ONLY_IsEntriesHardDeleteAllowed", "CanManagePersonalTimeTracker", "CanViewAllTimeTrackerEntries", "CanViewAllProjects", "CanViewInvoices" }); + + migrationBuilder.UpdateData( + table: "Roles", + keyColumn: "Id", + keyValue: 2L, + column: "Permissions", + value: new[] { "ViewPersonalProfile", "ViewContacts", "ViewSalaryAndDocumentsData", "EditFullEmployeesData", "AccessAnalyticalForecastsPage", "ViewAccounts", "ManageAccounts", "ViewRoles", "ManageRoles", "CanRequestCompensations", "CanManageCompensations", "CanManageDocuments", "CanManageTenants", "IsTenantsHardDeleteAllowed", "IsAccountsHardDeleteAllowed", "IsCompensationsHardDeleteAllowed", "CanViewBooks", "CanManageBooks", "IsBooksHardDeleteAllowed", "AUTO_TESTS_ONLY_IsSetUserPasswordBypassingEmailConfirmationAllowed", "AUTO_TESTS_ONLY_IsItemTypesHardDeleteAllowed", "CanManageItemsTypes", "CanViewItemsTypes", "AUTO_TESTS_ONLY_IsItemsHardDeleteAllowed", "CanManageItems", "CanViewItems", "AUTO_TESTS_ONLY_IsEntriesHardDeleteAllowed", "CanManagePersonalTimeTracker", "CanViewAllTimeTrackerEntries", "CanViewAllProjects", "CanViewInvoices" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.UpdateData( + table: "Roles", + keyColumn: "Id", + keyValue: 1L, + column: "Permissions", + value: new[] { "ViewPersonalProfile", "ViewContacts", "ViewSalaryAndDocumentsData", "EditFullEmployeesData", "AccessAnalyticalForecastsPage", "ViewAccounts", "ManageAccounts", "ViewRoles", "ManageRoles", "CanRequestCompensations", "CanManageCompensations", "CanManageDocuments", "CanManageTenants", "IsTenantsHardDeleteAllowed", "IsAccountsHardDeleteAllowed", "IsCompensationsHardDeleteAllowed", "CanViewBooks", "CanManageBooks", "IsBooksHardDeleteAllowed", "AUTO_TESTS_ONLY_IsSetUserPasswordBypassingEmailConfirmationAllowed", "AUTO_TESTS_ONLY_IsItemTypesHardDeleteAllowed", "CanManageItemsTypes", "CanViewItemsTypes", "AUTO_TESTS_ONLY_IsItemsHardDeleteAllowed", "CanManageItems", "CanViewItems", "AUTO_TESTS_ONLY_IsEntriesHardDeleteAllowed", "CanManagePersonalTimeTracker", "CanViewInvoices" }); + + migrationBuilder.UpdateData( + table: "Roles", + keyColumn: "Id", + keyValue: 2L, + column: "Permissions", + value: new[] { "ViewPersonalProfile", "ViewContacts", "ViewSalaryAndDocumentsData", "EditFullEmployeesData", "AccessAnalyticalForecastsPage", "ViewAccounts", "ManageAccounts", "ViewRoles", "ManageRoles", "CanRequestCompensations", "CanManageCompensations", "CanManageDocuments", "CanManageTenants", "IsTenantsHardDeleteAllowed", "IsAccountsHardDeleteAllowed", "IsCompensationsHardDeleteAllowed", "CanViewBooks", "CanManageBooks", "IsBooksHardDeleteAllowed", "AUTO_TESTS_ONLY_IsSetUserPasswordBypassingEmailConfirmationAllowed", "AUTO_TESTS_ONLY_IsItemTypesHardDeleteAllowed", "CanManageItemsTypes", "CanViewItemsTypes", "AUTO_TESTS_ONLY_IsItemsHardDeleteAllowed", "CanManageItems", "CanViewItems", "AUTO_TESTS_ONLY_IsEntriesHardDeleteAllowed", "CanManagePersonalTimeTracker", "CanViewInvoices" }); + } + } +} diff --git a/DataAccess/Migrations/UsersDbContextModelSnapshot.cs b/DataAccess/Migrations/UsersDbContextModelSnapshot.cs index 09136c8..0895d97 100644 --- a/DataAccess/Migrations/UsersDbContextModelSnapshot.cs +++ b/DataAccess/Migrations/UsersDbContextModelSnapshot.cs @@ -165,13 +165,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) { Id = 1L, Name = "Admin", - Permissions = new[] { "ViewPersonalProfile", "ViewContacts", "ViewSalaryAndDocumentsData", "EditFullEmployeesData", "AccessAnalyticalForecastsPage", "ViewAccounts", "ManageAccounts", "ViewRoles", "ManageRoles", "CanRequestCompensations", "CanManageCompensations", "CanManageDocuments", "CanManageTenants", "IsTenantsHardDeleteAllowed", "IsAccountsHardDeleteAllowed", "IsCompensationsHardDeleteAllowed", "CanViewBooks", "CanManageBooks", "IsBooksHardDeleteAllowed", "AUTO_TESTS_ONLY_IsSetUserPasswordBypassingEmailConfirmationAllowed", "AUTO_TESTS_ONLY_IsItemTypesHardDeleteAllowed", "CanManageItemsTypes", "CanViewItemsTypes", "AUTO_TESTS_ONLY_IsItemsHardDeleteAllowed", "CanManageItems", "CanViewItems", "AUTO_TESTS_ONLY_IsEntriesHardDeleteAllowed", "CanManagePersonalTimeTracker", "CanViewInvoices" } + Permissions = new[] { "ViewPersonalProfile", "ViewContacts", "ViewSalaryAndDocumentsData", "EditFullEmployeesData", "AccessAnalyticalForecastsPage", "ViewAccounts", "ManageAccounts", "ViewRoles", "ManageRoles", "CanRequestCompensations", "CanManageCompensations", "CanManageDocuments", "CanManageTenants", "IsTenantsHardDeleteAllowed", "IsAccountsHardDeleteAllowed", "IsCompensationsHardDeleteAllowed", "CanViewBooks", "CanManageBooks", "IsBooksHardDeleteAllowed", "AUTO_TESTS_ONLY_IsSetUserPasswordBypassingEmailConfirmationAllowed", "AUTO_TESTS_ONLY_IsItemTypesHardDeleteAllowed", "CanManageItemsTypes", "CanViewItemsTypes", "AUTO_TESTS_ONLY_IsItemsHardDeleteAllowed", "CanManageItems", "CanViewItems", "AUTO_TESTS_ONLY_IsEntriesHardDeleteAllowed", "CanManagePersonalTimeTracker", "CanViewAllTimeTrackerEntries", "CanViewAllProjects", "CanViewInvoices" } }, new { Id = 2L, Name = "CEO", - Permissions = new[] { "ViewPersonalProfile", "ViewContacts", "ViewSalaryAndDocumentsData", "EditFullEmployeesData", "AccessAnalyticalForecastsPage", "ViewAccounts", "ManageAccounts", "ViewRoles", "ManageRoles", "CanRequestCompensations", "CanManageCompensations", "CanManageDocuments", "CanManageTenants", "IsTenantsHardDeleteAllowed", "IsAccountsHardDeleteAllowed", "IsCompensationsHardDeleteAllowed", "CanViewBooks", "CanManageBooks", "IsBooksHardDeleteAllowed", "AUTO_TESTS_ONLY_IsSetUserPasswordBypassingEmailConfirmationAllowed", "AUTO_TESTS_ONLY_IsItemTypesHardDeleteAllowed", "CanManageItemsTypes", "CanViewItemsTypes", "AUTO_TESTS_ONLY_IsItemsHardDeleteAllowed", "CanManageItems", "CanViewItems", "AUTO_TESTS_ONLY_IsEntriesHardDeleteAllowed", "CanManagePersonalTimeTracker", "CanViewInvoices" } + Permissions = new[] { "ViewPersonalProfile", "ViewContacts", "ViewSalaryAndDocumentsData", "EditFullEmployeesData", "AccessAnalyticalForecastsPage", "ViewAccounts", "ManageAccounts", "ViewRoles", "ManageRoles", "CanRequestCompensations", "CanManageCompensations", "CanManageDocuments", "CanManageTenants", "IsTenantsHardDeleteAllowed", "IsAccountsHardDeleteAllowed", "IsCompensationsHardDeleteAllowed", "CanViewBooks", "CanManageBooks", "IsBooksHardDeleteAllowed", "AUTO_TESTS_ONLY_IsSetUserPasswordBypassingEmailConfirmationAllowed", "AUTO_TESTS_ONLY_IsItemTypesHardDeleteAllowed", "CanManageItemsTypes", "CanViewItemsTypes", "AUTO_TESTS_ONLY_IsItemsHardDeleteAllowed", "CanManageItems", "CanViewItems", "AUTO_TESTS_ONLY_IsEntriesHardDeleteAllowed", "CanManagePersonalTimeTracker", "CanViewAllTimeTrackerEntries", "CanViewAllProjects", "CanViewInvoices" } }); });