multi-tenant implementierung

This commit is contained in:
MarcWieland
2026-06-24 23:48:04 +02:00
parent d646cfd28d
commit ac06059e2a
41 changed files with 2530 additions and 238 deletions
+1
View File
@@ -4,6 +4,7 @@ public class AppSettings
{
public int Id { get; set; }
public int UserId { get; set; }
public int? TenantId { get; set; }
public double DailyTargetHours { get; set; } = 7.5;
public int MinimumBreakMinutes { get; set; } = 30;
public int VacationDaysPerYear { get; set; } = 30;
@@ -0,0 +1,3 @@
namespace timetracker.Shared;
public record AssignTenantRequest(int? TenantId);
+3
View File
@@ -8,4 +8,7 @@ public interface IAuthService
Task<string?> RenameUserAsync(int userId, string newUsername);
Task<string?> ChangePasswordAsync(int userId, string currentPassword, string newPassword);
Task<(User? User, string? Error)> RegisterAsync(string username, string password, string? honeypot = null);
Task<(Tenant? Tenant, string? Error)> RegisterFirmAsync(RegisterFirmRequest req);
Task<string?> AssignTenantAsync(int userId, int? tenantId);
Task<string?> ResetPasswordAsync(int userId, string newPassword);
}
@@ -0,0 +1,8 @@
namespace timetracker.Shared;
public record RegisterFirmRequest(
string CompanyName,
string Subdomain,
string AdminUsername,
string AdminPassword
);
@@ -0,0 +1,3 @@
namespace timetracker.Shared;
public record ResetPasswordRequest(string NewPassword);
+14
View File
@@ -0,0 +1,14 @@
using System;
namespace timetracker.Shared;
public class Tenant
{
public int Id { get; set; }
public string Name { get; set; } = "";
public string Subdomain { get; set; } = "";
public bool IsApproved { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public string PrimaryColor { get; set; } = "#0EA5E9";
public string SecondaryColor { get; set; } = "#0EA5E9";
}
+11
View File
@@ -0,0 +1,11 @@
namespace timetracker.Shared;
public class TenantInfo
{
public bool IsTenant { get; set; }
public string? Name { get; set; }
public string? Subdomain { get; set; }
public bool IsApproved { get; set; }
public string? PrimaryColor { get; set; }
public string? SecondaryColor { get; set; }
}
+8
View File
@@ -0,0 +1,8 @@
namespace timetracker.Shared;
public class TenantSettingsDto
{
public string Name { get; set; } = "";
public string PrimaryColor { get; set; } = "#0EA5E9";
public string SecondaryColor { get; set; } = "#0EA5E9";
}
+23
View File
@@ -0,0 +1,23 @@
using System;
namespace timetracker.Shared;
public class TenantStats
{
public int Id { get; set; }
public string Name { get; set; } = "";
public string Subdomain { get; set; } = "";
public bool IsApproved { get; set; }
public DateTime CreatedAt { get; set; }
public int UserCount { get; set; }
public int WorkDaysCount { get; set; }
public List<TenantUserDto> Users { get; set; } = new();
public bool ShowDetails { get; set; }
}
public class TenantUserDto
{
public int Id { get; set; }
public string Username { get; set; } = "";
public bool IsTenantAdmin { get; set; }
}
+4
View File
@@ -6,4 +6,8 @@ public class User
public string Username { get; set; } = "";
public string PasswordHash { get; set; } = "";
public string PasswordSalt { get; set; } = "";
public int? TenantId { get; set; }
public Tenant? Tenant { get; set; }
public bool IsTenantAdmin { get; set; }
}
+1
View File
@@ -4,4 +4,5 @@ public class UserInfo
{
public int Id { get; set; }
public string Username { get; set; } = "";
public bool IsTenantAdmin { get; set; }
}
+1
View File
@@ -4,6 +4,7 @@ public class VacationDay
{
public int Id { get; set; }
public int UserId { get; set; }
public int? TenantId { get; set; }
public DateOnly Date { get; set; }
public string? Note { get; set; }
}
+1
View File
@@ -4,6 +4,7 @@ public class WorkDay
{
public int Id { get; set; }
public int UserId { get; set; }
public int? TenantId { get; set; }
public DateOnly Date { get; set; }
public TimeOnly? StartTime { get; set; }
public TimeOnly? EndTime { get; set; }