- Add Role property to User entity with migration - Create BootstrapController for first admin user creation - Remove [AllowAnonymous] from all learning content controllers - Create AdminController with admin-only endpoints - Create AdminService for user management - Create UserReportService for progress reports - Add UserRepository implementation - Update AuthService with role support feat(frontend): Implement authentication system - Add AuthStore with React context for auth state management - Create Login, Register, Landing, and Home pages - Add ProtectedRoute and AdminRoute components - Create Auth API types and client - Configure Vite with @/ path alias - Add comprehensive CSS styles for auth and landing pages BREAKING CHANGE: All learning content now requires authentication. Users must register and sign in before accessing lessons, quizzes, and stories. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
106 lines
2.8 KiB
C#
106 lines
2.8 KiB
C#
namespace GermanApp.Domain.Entities;
|
|
|
|
/// <summary>
|
|
/// Represents a user in the DeutschLernen system.
|
|
/// </summary>
|
|
public class User
|
|
{
|
|
public int Id { get; private set; }
|
|
public string Username { get; private set; } = string.Empty;
|
|
public string Email { get; private set; } = string.Empty;
|
|
public string PasswordHash { get; private set; } = string.Empty;
|
|
public string CurrentLevel { get; private set; } = "A1";
|
|
public string Role { get; private set; } = "User"; // Default role is "User", "Admin" for administrators
|
|
public int Streak { get; private set; }
|
|
public int TotalPoints { get; private set; }
|
|
public DateTime CreatedAt { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Constructor for EF Core deserialization.
|
|
/// </summary>
|
|
private User() { }
|
|
|
|
/// <summary>
|
|
/// Factory method to create a new user.
|
|
/// </summary>
|
|
public static User Create(string username, string email, string passwordHash)
|
|
{
|
|
return new User
|
|
{
|
|
Username = username,
|
|
Email = email.ToLowerInvariant(),
|
|
PasswordHash = passwordHash,
|
|
CurrentLevel = "A1",
|
|
Streak = 0,
|
|
TotalPoints = 0,
|
|
CreatedAt = DateTime.UtcNow
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates user's gamification stats.
|
|
/// </summary>
|
|
public void AddPoints(int points)
|
|
{
|
|
TotalPoints += points;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates user's streak.
|
|
/// </summary>
|
|
public void UpdateStreak(int streak)
|
|
{
|
|
Streak = streak;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates user's current level.
|
|
/// </summary>
|
|
public void UpdateLevel(string level)
|
|
{
|
|
CurrentLevel = level;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Changes user's email.
|
|
/// </summary>
|
|
public void ChangeEmail(string newEmail)
|
|
{
|
|
Email = newEmail?.ToLowerInvariant() ?? string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Changes user's password hash.
|
|
/// </summary>
|
|
public void ChangePassword(string newPasswordHash)
|
|
{
|
|
PasswordHash = newPasswordHash;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Assigns admin role to user (bootstrap only).
|
|
/// </summary>
|
|
public void AssignAdminRole()
|
|
{
|
|
Role = "Admin";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the user's role.
|
|
/// </summary>
|
|
/// <param name="role">The role to assign (User or Admin)</param>
|
|
public void SetRole(string role)
|
|
{
|
|
if (role != "Admin" && role != "User")
|
|
throw new ArgumentException("Role must be 'Admin' or 'User'.", nameof(role));
|
|
Role = role;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if user has admin role.
|
|
/// </summary>
|
|
public bool IsAdmin() => Role == "Admin";
|
|
|
|
// Navigation properties
|
|
public virtual ICollection<StoryProgress> StoryProgress { get; private set; } = new List<StoryProgress>();
|
|
}
|