K4: add Kassenwart role + policy

- UserRole.Treasurer = "Kassenwart"
- IdentityRoleSeeder: seed Kassenwart role
- ClubRoleRequirement: rank Admin=4, Kassenwart=3
- ClubTreasurer policy in DI

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
beo3000 2026-01-03 14:28:45 +01:00
parent 9719667cb7
commit 2f2e93ffce
5 changed files with 11 additions and 3 deletions

View File

@ -1702,7 +1702,7 @@ public enum CashBookEntryType { Income = 0, Expense = 1 }
| ✓ | K1 | Domain | Entities + Enums | 5 | | ✓ | K1 | Domain | Entities + Enums | 5 |
| ✓ | K2 | Infrastructure | EF Configurations | 4 | | ✓ | K2 | Infrastructure | EF Configurations | 4 |
| ✓ | K3 | Infrastructure | Migration | - | | ✓ | K3 | Infrastructure | Migration | - |
| | K4 | Security | Kassenwart Role + Policy | 4 | | | K4 | Security | Kassenwart Role + Policy | 4 |
| ☐ | K5 | Infrastructure | Repositories | 5 | | ☐ | K5 | Infrastructure | Repositories | 5 |
| ☐ | K6 | Application | DTOs | 3 | | ☐ | K6 | Application | DTOs | 3 |
| ☐ | K7 | Application | Service Interfaces | 2 | | ☐ | K7 | Application | Service Interfaces | 2 |

View File

@ -25,6 +25,12 @@ namespace Koogle.Domain.Enums
/// </summary> /// </summary>
public const string Admin = "Admin"; public const string Admin = "Admin";
/// <summary>
/// With this role, the user can manage the cash book within a club.
/// Rank between Editor and Admin.
/// </summary>
public const string Treasurer = "Kassenwart";
/// <summary> /// <summary>
/// With this role, the user can edit content within a club but does not have administrative rights. /// With this role, the user can edit content within a club but does not have administrative rights.
/// </summary> /// </summary>

View File

@ -74,6 +74,7 @@ public static class DependencyInjection
{ {
options.AddPolicy("ClubViewer", p => p.Requirements.Add(new ClubRoleRequirement("Viewer"))); options.AddPolicy("ClubViewer", p => p.Requirements.Add(new ClubRoleRequirement("Viewer")));
options.AddPolicy("ClubEditor", p => p.Requirements.Add(new ClubRoleRequirement("Editor"))); options.AddPolicy("ClubEditor", p => p.Requirements.Add(new ClubRoleRequirement("Editor")));
options.AddPolicy("ClubTreasurer", p => p.Requirements.Add(new ClubRoleRequirement("Kassenwart")));
options.AddPolicy("ClubAdmin", p => p.Requirements.Add(new ClubRoleRequirement("Admin"))); options.AddPolicy("ClubAdmin", p => p.Requirements.Add(new ClubRoleRequirement("Admin")));
}); });
services.AddSingleton<IAuthorizationHandler, ClubRoleHandler>(); services.AddSingleton<IAuthorizationHandler, ClubRoleHandler>();

View File

@ -16,7 +16,8 @@ public static class ClubRoleHelper
{ {
static int Rank(string role) => role switch static int Rank(string role) => role switch
{ {
"Admin" => 3, "Admin" => 4,
"Kassenwart" => 3,
"Editor" => 2, "Editor" => 2,
"Viewer" => 1, "Viewer" => 1,
_ => 0 _ => 0

View File

@ -16,7 +16,7 @@ public static class IdentityRoleSeeder
{ {
var roleManager = services.GetRequiredService<RoleManager<ApplicationRole>>(); var roleManager = services.GetRequiredService<RoleManager<ApplicationRole>>();
string[] roles = { "SuperAdmin", "Admin", "Editor", "Viewer" }; string[] roles = { "SuperAdmin", "Admin", "Kassenwart", "Editor", "Viewer" };
foreach (var roleName in roles) foreach (var roleName in roles)
{ {