diff --git a/CLAUDE.md b/CLAUDE.md
index 554b66c..9853dae 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -54,7 +54,7 @@ Two independent mechanisms — don't cross-wire them:
- PostgreSQL via `Npgsql.EntityFrameworkCore.PostgreSQL` 10. Connection string key is `ConnectionStrings:Default` (see [Mws.Api/appsettings.json](Mws.Api/appsettings.json)); fallback to `localhost:5432` dev creds `mws/mws`. Override via env if you must.
- Enum columns are stored as `varchar(20)` (not ints) — preserve that for any new enum.
- Self-referencing `Document.ParentId` uses `Restrict` to block accidental cycles. Cascade delete is implemented in `DeleteDocumentHandler` via a manual descendant walk (`DocumentAccess.DeleteDescendantsAsync`); do not switch the FK to cascade.
-- `DbSeeder` ([Mws.Infrastructure/Persistence/DbSeeder.cs](Mws.Infrastructure/Persistence/DbSeeder.cs)) seeds two system roles (`Admin` — full CRUD on every screen; `Member` — view-only on Projects, CRUD on Tasks/Documents (no delete), and no access to Users/Permissions/Master Data) plus admin/alice/bob (password: `password`, admin → Admin role, alice/bob → Member) and one demo project on first boot. System roles are re-synced to this canonical permission matrix on every startup (`SyncSystemRoleAsync`), so edits made to them through the Roles UI do not persist across restarts. Skips user/project seeding if any users exist. System roles (`Role.IsSystem = true`) can't be deleted via `DeleteRoleCommand`.
+- `DbSeeder` ([Mws.Infrastructure/Persistence/DbSeeder.cs](Mws.Infrastructure/Persistence/DbSeeder.cs)) seeds two system roles (`Admin` — full CRUD on every screen; `Member` — view-only on Projects, CRUD on Tasks/Documents (no delete), and no access to Users/Permissions/Master Data) plus admin/namdh (password: `password`, admin → Admin role, namdh → Member) and one demo project on first boot. System roles are re-synced to this canonical permission matrix on every startup (`SyncSystemRoleAsync`), so edits made to them through the Roles UI do not persist across restarts. Skips user/project seeding if any users exist. System roles (`Role.IsSystem = true`) can't be deleted via `DeleteRoleCommand`.
### Config
diff --git a/infrastructure/Migrations/20260809054503_InitialCreate.Designer.cs b/infrastructure/Migrations/20260809054503_InitialCreate.Designer.cs
deleted file mode 100644
index 100c055..0000000
--- a/infrastructure/Migrations/20260809054503_InitialCreate.Designer.cs
+++ /dev/null
@@ -1,264 +0,0 @@
-//
-using System;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using mws.backend.dotnet.infrastructure.Persistence;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#nullable disable
-
-namespace mws.backend.dotnet.infrastructure.Migrations
-{
- [DbContext(typeof(AppDbContext))]
- [Migration("20260809054503_InitialCreate")]
- partial class InitialCreate
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "10.0.10")
- .HasAnnotation("Relational:MaxIdentifierLength", 63);
-
- NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Documents.Document", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("Content")
- .HasColumnType("text");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("CreatedBy")
- .HasColumnType("uuid");
-
- b.Property("ParentId")
- .HasColumnType("uuid");
-
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("Title")
- .IsRequired()
- .HasMaxLength(300)
- .HasColumnType("character varying(300)");
-
- b.Property("Type")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("UpdatedBy")
- .HasColumnType("uuid");
-
- b.HasKey("Id");
-
- b.HasIndex("ParentId");
-
- b.HasIndex("ProjectId", "ParentId");
-
- b.ToTable("documents", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.Project", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Description")
- .HasMaxLength(2000)
- .HasColumnType("character varying(2000)");
-
- b.Property("Name")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("Status")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.ToTable("projects", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.ProjectMember", b =>
- {
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("UserId")
- .HasColumnType("uuid");
-
- b.Property("Role")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.HasKey("ProjectId", "UserId");
-
- b.HasIndex("UserId");
-
- b.ToTable("project_members", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Tasks.TaskItem", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("AssigneeId")
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("CreatedBy")
- .HasColumnType("uuid");
-
- b.Property("Description")
- .HasColumnType("text");
-
- b.Property("DueDate")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Priority")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("Status")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("Title")
- .IsRequired()
- .HasMaxLength(300)
- .HasColumnType("character varying(300)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.HasIndex("AssigneeId");
-
- b.HasIndex("ProjectId");
-
- b.HasIndex("Status");
-
- b.ToTable("tasks", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Users.User", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("DisplayName")
- .IsRequired()
- .HasMaxLength(150)
- .HasColumnType("character varying(150)");
-
- b.Property("PasswordHash")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Username")
- .IsRequired()
- .HasMaxLength(100)
- .HasColumnType("character varying(100)");
-
- b.HasKey("Id");
-
- b.HasIndex("Username")
- .IsUnique();
-
- b.ToTable("users", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Documents.Document", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Documents.Document", "Parent")
- .WithMany("Children")
- .HasForeignKey("ParentId")
- .OnDelete(DeleteBehavior.Restrict);
-
- b.Navigation("Parent");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.ProjectMember", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Projects.Project", "Project")
- .WithMany("Members")
- .HasForeignKey("ProjectId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("mws.backend.dotnet.domain.Users.User", "User")
- .WithMany()
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Project");
-
- b.Navigation("User");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Tasks.TaskItem", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Users.User", "Assignee")
- .WithMany()
- .HasForeignKey("AssigneeId")
- .OnDelete(DeleteBehavior.SetNull);
-
- b.Navigation("Assignee");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Documents.Document", b =>
- {
- b.Navigation("Children");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.Project", b =>
- {
- b.Navigation("Members");
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/infrastructure/Migrations/20260811133605_AddRolesAndPermissions.Designer.cs b/infrastructure/Migrations/20260811133605_AddRolesAndPermissions.Designer.cs
deleted file mode 100644
index 1569700..0000000
--- a/infrastructure/Migrations/20260811133605_AddRolesAndPermissions.Designer.cs
+++ /dev/null
@@ -1,353 +0,0 @@
-//
-using System;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using mws.backend.dotnet.infrastructure.Persistence;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#nullable disable
-
-namespace mws.backend.dotnet.infrastructure.Migrations
-{
- [DbContext(typeof(AppDbContext))]
- [Migration("20260811133605_AddRolesAndPermissions")]
- partial class AddRolesAndPermissions
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "10.0.10")
- .HasAnnotation("Relational:MaxIdentifierLength", 63);
-
- NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Documents.Document", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("Content")
- .HasColumnType("text");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("CreatedBy")
- .HasColumnType("uuid");
-
- b.Property("ParentId")
- .HasColumnType("uuid");
-
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("Title")
- .IsRequired()
- .HasMaxLength(300)
- .HasColumnType("character varying(300)");
-
- b.Property("Type")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("UpdatedBy")
- .HasColumnType("uuid");
-
- b.HasKey("Id");
-
- b.HasIndex("ParentId");
-
- b.HasIndex("ProjectId", "ParentId");
-
- b.ToTable("documents", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.Project", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Description")
- .HasMaxLength(2000)
- .HasColumnType("character varying(2000)");
-
- b.Property("Name")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("Status")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.ToTable("projects", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.ProjectMember", b =>
- {
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("UserId")
- .HasColumnType("uuid");
-
- b.Property("Role")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.HasKey("ProjectId", "UserId");
-
- b.HasIndex("UserId");
-
- b.ToTable("project_members", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Roles.Role", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("IsSystem")
- .HasColumnType("boolean");
-
- b.Property("Name")
- .IsRequired()
- .HasMaxLength(100)
- .HasColumnType("character varying(100)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.HasIndex("Name")
- .IsUnique();
-
- b.ToTable("roles", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Roles.RolePermission", b =>
- {
- b.Property("RoleId")
- .HasColumnType("uuid");
-
- b.Property("Screen")
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("CanCreate")
- .HasColumnType("boolean");
-
- b.Property("CanDelete")
- .HasColumnType("boolean");
-
- b.Property("CanEdit")
- .HasColumnType("boolean");
-
- b.Property("CanView")
- .HasColumnType("boolean");
-
- b.HasKey("RoleId", "Screen");
-
- b.ToTable("role_permissions", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Tasks.TaskItem", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("AssigneeId")
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("CreatedBy")
- .HasColumnType("uuid");
-
- b.Property("Description")
- .HasColumnType("text");
-
- b.Property("DueDate")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Priority")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("Status")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("Title")
- .IsRequired()
- .HasMaxLength(300)
- .HasColumnType("character varying(300)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.HasIndex("AssigneeId");
-
- b.HasIndex("ProjectId");
-
- b.HasIndex("Status");
-
- b.ToTable("tasks", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Users.User", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("DisplayName")
- .IsRequired()
- .HasMaxLength(150)
- .HasColumnType("character varying(150)");
-
- b.Property("IsActive")
- .HasColumnType("boolean");
-
- b.Property("PasswordHash")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("RoleId")
- .HasColumnType("uuid");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Username")
- .IsRequired()
- .HasMaxLength(100)
- .HasColumnType("character varying(100)");
-
- b.HasKey("Id");
-
- b.HasIndex("RoleId");
-
- b.HasIndex("Username")
- .IsUnique();
-
- b.ToTable("users", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Documents.Document", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Documents.Document", "Parent")
- .WithMany("Children")
- .HasForeignKey("ParentId")
- .OnDelete(DeleteBehavior.Restrict);
-
- b.Navigation("Parent");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.ProjectMember", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Projects.Project", "Project")
- .WithMany("Members")
- .HasForeignKey("ProjectId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("mws.backend.dotnet.domain.Users.User", "User")
- .WithMany()
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Project");
-
- b.Navigation("User");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Roles.RolePermission", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Roles.Role", "Role")
- .WithMany("Permissions")
- .HasForeignKey("RoleId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Role");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Tasks.TaskItem", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Users.User", "Assignee")
- .WithMany()
- .HasForeignKey("AssigneeId")
- .OnDelete(DeleteBehavior.SetNull);
-
- b.Navigation("Assignee");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Users.User", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Roles.Role", "Role")
- .WithMany()
- .HasForeignKey("RoleId")
- .OnDelete(DeleteBehavior.Restrict)
- .IsRequired();
-
- b.Navigation("Role");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Documents.Document", b =>
- {
- b.Navigation("Children");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.Project", b =>
- {
- b.Navigation("Members");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Roles.Role", b =>
- {
- b.Navigation("Permissions");
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/infrastructure/Migrations/20260811133605_AddRolesAndPermissions.cs b/infrastructure/Migrations/20260811133605_AddRolesAndPermissions.cs
deleted file mode 100644
index a18b315..0000000
--- a/infrastructure/Migrations/20260811133605_AddRolesAndPermissions.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-using System;
-using Microsoft.EntityFrameworkCore.Migrations;
-
-#nullable disable
-
-namespace mws.backend.dotnet.infrastructure.Migrations
-{
- ///
- public partial class AddRolesAndPermissions : Migration
- {
- ///
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.AddColumn(
- name: "IsActive",
- table: "users",
- type: "boolean",
- nullable: false,
- defaultValue: true);
-
- migrationBuilder.AddColumn(
- name: "RoleId",
- table: "users",
- type: "uuid",
- nullable: false,
- defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
-
- migrationBuilder.CreateTable(
- name: "roles",
- columns: table => new
- {
- Id = table.Column(type: "uuid", nullable: false),
- Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false),
- IsSystem = table.Column(type: "boolean", nullable: false),
- CreatedAt = table.Column(type: "timestamp with time zone", nullable: false),
- UpdatedAt = table.Column(type: "timestamp with time zone", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_roles", x => x.Id);
- });
-
- migrationBuilder.CreateTable(
- name: "role_permissions",
- columns: table => new
- {
- RoleId = table.Column(type: "uuid", nullable: false),
- Screen = table.Column(type: "character varying(50)", maxLength: 50, nullable: false),
- CanView = table.Column(type: "boolean", nullable: false),
- CanCreate = table.Column(type: "boolean", nullable: false),
- CanEdit = table.Column(type: "boolean", nullable: false),
- CanDelete = table.Column(type: "boolean", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_role_permissions", x => new { x.RoleId, x.Screen });
- table.ForeignKey(
- name: "FK_role_permissions_roles_RoleId",
- column: x => x.RoleId,
- principalTable: "roles",
- principalColumn: "Id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateIndex(
- name: "IX_users_RoleId",
- table: "users",
- column: "RoleId");
-
- migrationBuilder.CreateIndex(
- name: "IX_roles_Name",
- table: "roles",
- column: "Name",
- unique: true);
-
- migrationBuilder.AddForeignKey(
- name: "FK_users_roles_RoleId",
- table: "users",
- column: "RoleId",
- principalTable: "roles",
- principalColumn: "Id",
- onDelete: ReferentialAction.Restrict);
- }
-
- ///
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropForeignKey(
- name: "FK_users_roles_RoleId",
- table: "users");
-
- migrationBuilder.DropTable(
- name: "role_permissions");
-
- migrationBuilder.DropTable(
- name: "roles");
-
- migrationBuilder.DropIndex(
- name: "IX_users_RoleId",
- table: "users");
-
- migrationBuilder.DropColumn(
- name: "IsActive",
- table: "users");
-
- migrationBuilder.DropColumn(
- name: "RoleId",
- table: "users");
- }
- }
-}
diff --git a/infrastructure/Migrations/20260812124332_AddMemberDocumentPermissions.Designer.cs b/infrastructure/Migrations/20260812124332_AddMemberDocumentPermissions.Designer.cs
deleted file mode 100644
index 5a0bfc1..0000000
--- a/infrastructure/Migrations/20260812124332_AddMemberDocumentPermissions.Designer.cs
+++ /dev/null
@@ -1,365 +0,0 @@
-//
-using System;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using mws.backend.dotnet.infrastructure.Persistence;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#nullable disable
-
-namespace mws.backend.dotnet.infrastructure.Migrations
-{
- [DbContext(typeof(AppDbContext))]
- [Migration("20260812124332_AddMemberDocumentPermissions")]
- partial class AddMemberDocumentPermissions
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "10.0.10")
- .HasAnnotation("Relational:MaxIdentifierLength", 63);
-
- NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Documents.Document", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("Content")
- .HasColumnType("text");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("CreatedBy")
- .HasColumnType("uuid");
-
- b.Property("ParentId")
- .HasColumnType("uuid");
-
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("Title")
- .IsRequired()
- .HasMaxLength(300)
- .HasColumnType("character varying(300)");
-
- b.Property("Type")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("UpdatedBy")
- .HasColumnType("uuid");
-
- b.HasKey("Id");
-
- b.HasIndex("ParentId");
-
- b.HasIndex("ProjectId", "ParentId");
-
- b.ToTable("documents", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.Project", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Description")
- .HasMaxLength(2000)
- .HasColumnType("character varying(2000)");
-
- b.Property("Name")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("Status")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.ToTable("projects", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.ProjectMember", b =>
- {
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("UserId")
- .HasColumnType("uuid");
-
- b.Property("CanCreateDocuments")
- .HasColumnType("boolean");
-
- b.Property("CanDeleteDocuments")
- .HasColumnType("boolean");
-
- b.Property("CanEditDocuments")
- .HasColumnType("boolean");
-
- b.Property("CanViewDocuments")
- .HasColumnType("boolean");
-
- b.Property("Role")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.HasKey("ProjectId", "UserId");
-
- b.HasIndex("UserId");
-
- b.ToTable("project_members", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Roles.Role", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("IsSystem")
- .HasColumnType("boolean");
-
- b.Property("Name")
- .IsRequired()
- .HasMaxLength(100)
- .HasColumnType("character varying(100)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.HasIndex("Name")
- .IsUnique();
-
- b.ToTable("roles", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Roles.RolePermission", b =>
- {
- b.Property("RoleId")
- .HasColumnType("uuid");
-
- b.Property("Screen")
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("CanCreate")
- .HasColumnType("boolean");
-
- b.Property("CanDelete")
- .HasColumnType("boolean");
-
- b.Property("CanEdit")
- .HasColumnType("boolean");
-
- b.Property("CanView")
- .HasColumnType("boolean");
-
- b.HasKey("RoleId", "Screen");
-
- b.ToTable("role_permissions", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Tasks.TaskItem", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("AssigneeId")
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("CreatedBy")
- .HasColumnType("uuid");
-
- b.Property("Description")
- .HasColumnType("text");
-
- b.Property("DueDate")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Priority")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("Status")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("Title")
- .IsRequired()
- .HasMaxLength(300)
- .HasColumnType("character varying(300)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.HasIndex("AssigneeId");
-
- b.HasIndex("ProjectId");
-
- b.HasIndex("Status");
-
- b.ToTable("tasks", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Users.User", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("DisplayName")
- .IsRequired()
- .HasMaxLength(150)
- .HasColumnType("character varying(150)");
-
- b.Property("IsActive")
- .HasColumnType("boolean");
-
- b.Property("PasswordHash")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("RoleId")
- .HasColumnType("uuid");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Username")
- .IsRequired()
- .HasMaxLength(100)
- .HasColumnType("character varying(100)");
-
- b.HasKey("Id");
-
- b.HasIndex("RoleId");
-
- b.HasIndex("Username")
- .IsUnique();
-
- b.ToTable("users", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Documents.Document", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Documents.Document", "Parent")
- .WithMany("Children")
- .HasForeignKey("ParentId")
- .OnDelete(DeleteBehavior.Restrict);
-
- b.Navigation("Parent");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.ProjectMember", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Projects.Project", "Project")
- .WithMany("Members")
- .HasForeignKey("ProjectId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("mws.backend.dotnet.domain.Users.User", "User")
- .WithMany()
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Project");
-
- b.Navigation("User");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Roles.RolePermission", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Roles.Role", "Role")
- .WithMany("Permissions")
- .HasForeignKey("RoleId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Role");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Tasks.TaskItem", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Users.User", "Assignee")
- .WithMany()
- .HasForeignKey("AssigneeId")
- .OnDelete(DeleteBehavior.SetNull);
-
- b.Navigation("Assignee");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Users.User", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Roles.Role", "Role")
- .WithMany()
- .HasForeignKey("RoleId")
- .OnDelete(DeleteBehavior.Restrict)
- .IsRequired();
-
- b.Navigation("Role");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Documents.Document", b =>
- {
- b.Navigation("Children");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.Project", b =>
- {
- b.Navigation("Members");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Roles.Role", b =>
- {
- b.Navigation("Permissions");
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/infrastructure/Migrations/20260812124332_AddMemberDocumentPermissions.cs b/infrastructure/Migrations/20260812124332_AddMemberDocumentPermissions.cs
deleted file mode 100644
index edabd2f..0000000
--- a/infrastructure/Migrations/20260812124332_AddMemberDocumentPermissions.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using Microsoft.EntityFrameworkCore.Migrations;
-
-#nullable disable
-
-namespace mws.backend.dotnet.infrastructure.Migrations
-{
- ///
- public partial class AddMemberDocumentPermissions : Migration
- {
- ///
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.AddColumn(
- name: "CanCreateDocuments",
- table: "project_members",
- type: "boolean",
- nullable: false,
- defaultValue: false);
-
- migrationBuilder.AddColumn(
- name: "CanDeleteDocuments",
- table: "project_members",
- type: "boolean",
- nullable: false,
- defaultValue: false);
-
- migrationBuilder.AddColumn(
- name: "CanEditDocuments",
- table: "project_members",
- type: "boolean",
- nullable: false,
- defaultValue: false);
-
- migrationBuilder.AddColumn(
- name: "CanViewDocuments",
- table: "project_members",
- type: "boolean",
- nullable: false,
- defaultValue: false);
-
- migrationBuilder.Sql("UPDATE \"project_members\" SET \"CanViewDocuments\" = true, \"CanCreateDocuments\" = true, \"CanEditDocuments\" = true, \"CanDeleteDocuments\" = true WHERE \"Role\" = 'Owner';");
- migrationBuilder.Sql("UPDATE \"project_members\" SET \"CanViewDocuments\" = true WHERE \"Role\" = 'Member';");
- }
-
- ///
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropColumn(
- name: "CanCreateDocuments",
- table: "project_members");
-
- migrationBuilder.DropColumn(
- name: "CanDeleteDocuments",
- table: "project_members");
-
- migrationBuilder.DropColumn(
- name: "CanEditDocuments",
- table: "project_members");
-
- migrationBuilder.DropColumn(
- name: "CanViewDocuments",
- table: "project_members");
- }
- }
-}
diff --git a/infrastructure/Migrations/20260812130925_SplitProjectMemberPermissions.Designer.cs b/infrastructure/Migrations/20260812130925_SplitProjectMemberPermissions.Designer.cs
deleted file mode 100644
index 4e275d8..0000000
--- a/infrastructure/Migrations/20260812130925_SplitProjectMemberPermissions.Designer.cs
+++ /dev/null
@@ -1,391 +0,0 @@
-//
-using System;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using mws.backend.dotnet.infrastructure.Persistence;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#nullable disable
-
-namespace mws.backend.dotnet.infrastructure.Migrations
-{
- [DbContext(typeof(AppDbContext))]
- [Migration("20260812130925_SplitProjectMemberPermissions")]
- partial class SplitProjectMemberPermissions
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "10.0.10")
- .HasAnnotation("Relational:MaxIdentifierLength", 63);
-
- NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Documents.Document", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("Content")
- .HasColumnType("text");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("CreatedBy")
- .HasColumnType("uuid");
-
- b.Property("ParentId")
- .HasColumnType("uuid");
-
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("Title")
- .IsRequired()
- .HasMaxLength(300)
- .HasColumnType("character varying(300)");
-
- b.Property("Type")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("UpdatedBy")
- .HasColumnType("uuid");
-
- b.HasKey("Id");
-
- b.HasIndex("ParentId");
-
- b.HasIndex("ProjectId", "ParentId");
-
- b.ToTable("documents", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.Project", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Description")
- .HasMaxLength(2000)
- .HasColumnType("character varying(2000)");
-
- b.Property("Name")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("Status")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.ToTable("projects", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.ProjectMember", b =>
- {
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("UserId")
- .HasColumnType("uuid");
-
- b.Property("Role")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.HasKey("ProjectId", "UserId");
-
- b.HasIndex("UserId");
-
- b.ToTable("project_members", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.ProjectMemberPermission", b =>
- {
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("UserId")
- .HasColumnType("uuid");
-
- b.Property("Screen")
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("CanCreate")
- .HasColumnType("boolean");
-
- b.Property("CanDelete")
- .HasColumnType("boolean");
-
- b.Property("CanEdit")
- .HasColumnType("boolean");
-
- b.Property("CanView")
- .HasColumnType("boolean");
-
- b.HasKey("ProjectId", "UserId", "Screen");
-
- b.ToTable("project_member_permissions", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Roles.Role", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("IsSystem")
- .HasColumnType("boolean");
-
- b.Property("Name")
- .IsRequired()
- .HasMaxLength(100)
- .HasColumnType("character varying(100)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.HasIndex("Name")
- .IsUnique();
-
- b.ToTable("roles", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Roles.RolePermission", b =>
- {
- b.Property("RoleId")
- .HasColumnType("uuid");
-
- b.Property("Screen")
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("CanCreate")
- .HasColumnType("boolean");
-
- b.Property("CanDelete")
- .HasColumnType("boolean");
-
- b.Property("CanEdit")
- .HasColumnType("boolean");
-
- b.Property("CanView")
- .HasColumnType("boolean");
-
- b.HasKey("RoleId", "Screen");
-
- b.ToTable("role_permissions", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Tasks.TaskItem", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("AssigneeId")
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("CreatedBy")
- .HasColumnType("uuid");
-
- b.Property("Description")
- .HasColumnType("text");
-
- b.Property("DueDate")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Priority")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("Status")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("Title")
- .IsRequired()
- .HasMaxLength(300)
- .HasColumnType("character varying(300)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.HasIndex("AssigneeId");
-
- b.HasIndex("ProjectId");
-
- b.HasIndex("Status");
-
- b.ToTable("tasks", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Users.User", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("DisplayName")
- .IsRequired()
- .HasMaxLength(150)
- .HasColumnType("character varying(150)");
-
- b.Property("IsActive")
- .HasColumnType("boolean");
-
- b.Property("PasswordHash")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("RoleId")
- .HasColumnType("uuid");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Username")
- .IsRequired()
- .HasMaxLength(100)
- .HasColumnType("character varying(100)");
-
- b.HasKey("Id");
-
- b.HasIndex("RoleId");
-
- b.HasIndex("Username")
- .IsUnique();
-
- b.ToTable("users", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Documents.Document", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Documents.Document", "Parent")
- .WithMany("Children")
- .HasForeignKey("ParentId")
- .OnDelete(DeleteBehavior.Restrict);
-
- b.Navigation("Parent");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.ProjectMember", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Projects.Project", "Project")
- .WithMany("Members")
- .HasForeignKey("ProjectId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("mws.backend.dotnet.domain.Users.User", "User")
- .WithMany()
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Project");
-
- b.Navigation("User");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.ProjectMemberPermission", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Projects.ProjectMember", null)
- .WithMany()
- .HasForeignKey("ProjectId", "UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Roles.RolePermission", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Roles.Role", "Role")
- .WithMany("Permissions")
- .HasForeignKey("RoleId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Role");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Tasks.TaskItem", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Users.User", "Assignee")
- .WithMany()
- .HasForeignKey("AssigneeId")
- .OnDelete(DeleteBehavior.SetNull);
-
- b.Navigation("Assignee");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Users.User", b =>
- {
- b.HasOne("mws.backend.dotnet.domain.Roles.Role", "Role")
- .WithMany()
- .HasForeignKey("RoleId")
- .OnDelete(DeleteBehavior.Restrict)
- .IsRequired();
-
- b.Navigation("Role");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Documents.Document", b =>
- {
- b.Navigation("Children");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.Project", b =>
- {
- b.Navigation("Members");
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Roles.Role", b =>
- {
- b.Navigation("Permissions");
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/infrastructure/Migrations/20260812130925_SplitProjectMemberPermissions.cs b/infrastructure/Migrations/20260812130925_SplitProjectMemberPermissions.cs
deleted file mode 100644
index 864de73..0000000
--- a/infrastructure/Migrations/20260812130925_SplitProjectMemberPermissions.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-using System;
-using Microsoft.EntityFrameworkCore.Migrations;
-
-#nullable disable
-
-namespace mws.backend.dotnet.infrastructure.Migrations
-{
- ///
- public partial class SplitProjectMemberPermissions : Migration
- {
- ///
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.CreateTable(
- name: "project_member_permissions",
- columns: table => new
- {
- ProjectId = table.Column(type: "uuid", nullable: false),
- UserId = table.Column(type: "uuid", nullable: false),
- Screen = table.Column(type: "character varying(50)", maxLength: 50, nullable: false),
- CanView = table.Column(type: "boolean", nullable: false),
- CanCreate = table.Column(type: "boolean", nullable: false),
- CanEdit = table.Column(type: "boolean", nullable: false),
- CanDelete = table.Column(type: "boolean", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_project_member_permissions", x => new { x.ProjectId, x.UserId, x.Screen });
- table.ForeignKey(
- name: "FK_project_member_permissions_project_members_ProjectId_UserId",
- columns: x => new { x.ProjectId, x.UserId },
- principalTable: "project_members",
- principalColumns: new[] { "ProjectId", "UserId" },
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.Sql("""
- INSERT INTO "project_member_permissions" ("ProjectId", "UserId", "Screen", "CanView", "CanCreate", "CanEdit", "CanDelete")
- SELECT "ProjectId", "UserId", 'documents', "CanViewDocuments", "CanCreateDocuments", "CanEditDocuments", "CanDeleteDocuments"
- FROM "project_members";
- """);
-
- migrationBuilder.DropColumn(
- name: "CanCreateDocuments",
- table: "project_members");
-
- migrationBuilder.DropColumn(
- name: "CanDeleteDocuments",
- table: "project_members");
-
- migrationBuilder.DropColumn(
- name: "CanEditDocuments",
- table: "project_members");
-
- migrationBuilder.DropColumn(
- name: "CanViewDocuments",
- table: "project_members");
- }
-
- ///
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.AddColumn(
- name: "CanCreateDocuments",
- table: "project_members",
- type: "boolean",
- nullable: false,
- defaultValue: false);
-
- migrationBuilder.AddColumn(
- name: "CanDeleteDocuments",
- table: "project_members",
- type: "boolean",
- nullable: false,
- defaultValue: false);
-
- migrationBuilder.AddColumn(
- name: "CanEditDocuments",
- table: "project_members",
- type: "boolean",
- nullable: false,
- defaultValue: false);
-
- migrationBuilder.AddColumn(
- name: "CanViewDocuments",
- table: "project_members",
- type: "boolean",
- nullable: false,
- defaultValue: false);
-
- migrationBuilder.Sql("""
- UPDATE "project_members" m
- SET "CanViewDocuments" = p."CanView",
- "CanCreateDocuments" = p."CanCreate",
- "CanEditDocuments" = p."CanEdit",
- "CanDeleteDocuments" = p."CanDelete"
- FROM "project_member_permissions" p
- WHERE p."ProjectId" = m."ProjectId" AND p."UserId" = m."UserId" AND p."Screen" = 'documents';
- """);
-
- migrationBuilder.DropTable(
- name: "project_member_permissions");
- }
- }
-}
diff --git a/infrastructure/Migrations/20260819131445_AddMasterData.Designer.cs b/infrastructure/Migrations/20260819131445_AddMasterData.Designer.cs
deleted file mode 100644
index cb6a70c..0000000
--- a/infrastructure/Migrations/20260819131445_AddMasterData.Designer.cs
+++ /dev/null
@@ -1,432 +0,0 @@
-//
-using System;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using mws.backend.dotnet.infrastructure.Persistence;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#nullable disable
-
-namespace mws.backend.dotnet.infrastructure.Migrations
-{
- [DbContext(typeof(AppDbContext))]
- [Migration("20260819131445_AddMasterData")]
- partial class AddMasterData
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "10.0.11")
- .HasAnnotation("Relational:MaxIdentifierLength", 63);
-
- NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Documents.Document", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("Content")
- .HasColumnType("text");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("CreatedBy")
- .HasColumnType("uuid");
-
- b.Property("ParentId")
- .HasColumnType("uuid");
-
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("Title")
- .IsRequired()
- .HasMaxLength(300)
- .HasColumnType("character varying(300)");
-
- b.Property("Type")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("UpdatedBy")
- .HasColumnType("uuid");
-
- b.HasKey("Id");
-
- b.HasIndex("ParentId");
-
- b.HasIndex("ProjectId", "ParentId");
-
- b.ToTable("documents", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.MasterData.MasterDataEntry", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Group")
- .IsRequired()
- .HasMaxLength(100)
- .HasColumnType("character varying(100)");
-
- b.Property("IsActive")
- .HasColumnType("boolean");
-
- b.Property("Label")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("SortOrder")
- .HasColumnType("integer");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Value")
- .IsRequired()
- .HasMaxLength(100)
- .HasColumnType("character varying(100)");
-
- b.HasKey("Id");
-
- b.HasIndex("Group", "Value")
- .IsUnique();
-
- b.ToTable("master_data", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.Project", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Description")
- .HasMaxLength(2000)
- .HasColumnType("character varying(2000)");
-
- b.Property("Name")
- .IsRequired()
- .HasMaxLength(200)
- .HasColumnType("character varying(200)");
-
- b.Property("Status")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.ToTable("projects", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.ProjectMember", b =>
- {
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("UserId")
- .HasColumnType("uuid");
-
- b.Property("Role")
- .IsRequired()
- .HasMaxLength(20)
- .HasColumnType("character varying(20)");
-
- b.HasKey("ProjectId", "UserId");
-
- b.HasIndex("UserId");
-
- b.ToTable("project_members", (string)null);
- });
-
- modelBuilder.Entity("mws.backend.dotnet.domain.Projects.ProjectMemberPermission", b =>
- {
- b.Property("ProjectId")
- .HasColumnType("uuid");
-
- b.Property("UserId")
- .HasColumnType("uuid");
-
- b.Property("Screen")
- .HasMaxLength(50)
- .HasColumnType("character varying(50)");
-
- b.Property("CanCreate")
- .HasColumnType("boolean");
-
- b.Property("CanDelete")
- .HasColumnType("boolean");
-
- b.Property