- Updated Lesson entity to use LevelId (int) instead of Level (int) - Added navigation property Level (Level entity) - Added Order, Topic, and IsActive properties to Lesson - Updated Lesson.Create() factory method signature to accept levelId, title, order, topic, description - Split Update method into individual property update methods - Updated LessonDto to use LevelId, LevelName, LevelCode instead of Level int - Added CreateLessonDto and UpdateLessonDto with all required fields - Added UpdateFromDto extension method for Lesson - Updated CreateLessonCommand to validate LevelId instead of Level - Updated SeedDataExtension to seed Level entities first, then use new Lesson.Create() signature - Made SeedDatabaseAsync async and updated Program.cs to await it - Updated LessonsEndpoints to use GetByLevelAsync for beginner/advanced queries - Fixed missing using directive for Domain.Entities Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
82 lines
2.4 KiB
C#
82 lines
2.4 KiB
C#
namespace GermanApp.Domain.Entities;
|
|
|
|
/// <summary>
|
|
/// Represents a user's progress through lessons.
|
|
/// Tracks completion status and quiz scores.
|
|
/// </summary>
|
|
public class UserProgress
|
|
{
|
|
public int Id { get; private set; }
|
|
public int UserId { get; private set; }
|
|
public int LessonId { get; private set; }
|
|
public bool IsCompleted { get; private set; }
|
|
public int QuizScore { get; private set; }
|
|
public DateTime LastAttemptDate { get; private set; }
|
|
|
|
// Navigation properties
|
|
public virtual User? User { get; private set; }
|
|
public virtual Lesson? Lesson { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Constructor for EF Core deserialization.
|
|
/// </summary>
|
|
private UserProgress() { }
|
|
|
|
/// <summary>
|
|
/// Factory method to create a new user progress record.
|
|
/// </summary>
|
|
/// <param name="userId">ID of the user</param>
|
|
/// <param name="lessonId">ID of the lesson</param>
|
|
public static UserProgress Create(int userId, int lessonId)
|
|
{
|
|
return new UserProgress
|
|
{
|
|
UserId = userId,
|
|
LessonId = lessonId,
|
|
IsCompleted = false,
|
|
QuizScore = 0,
|
|
LastAttemptDate = DateTime.UtcNow
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Marks the lesson as completed.
|
|
/// </summary>
|
|
/// <param name="quizScore">The score achieved on the quiz (0-100)</param>
|
|
public void MarkAsCompleted(int quizScore)
|
|
{
|
|
if (quizScore < 0 || quizScore > 100)
|
|
throw new ArgumentOutOfRangeException(nameof(quizScore), "Score must be between 0 and 100");
|
|
|
|
IsCompleted = true;
|
|
QuizScore = quizScore;
|
|
LastAttemptDate = DateTime.UtcNow;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the quiz score without marking as completed.
|
|
/// </summary>
|
|
public void UpdateQuizScore(int quizScore)
|
|
{
|
|
if (quizScore < 0 || quizScore > 100)
|
|
throw new ArgumentOutOfRangeException(nameof(quizScore), "Score must be between 0 and 100");
|
|
|
|
QuizScore = quizScore;
|
|
LastAttemptDate = DateTime.UtcNow;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resets the progress (e.g., when user wants to redo a lesson).
|
|
/// </summary>
|
|
public void Reset()
|
|
{
|
|
IsCompleted = false;
|
|
QuizScore = 0;
|
|
LastAttemptDate = DateTime.UtcNow;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if the user passed the lesson (80% or higher).
|
|
/// </summary>
|
|
public bool HasPassed() => QuizScore >= 80;
|
|
}
|