-
Notifications
You must be signed in to change notification settings - Fork 297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adaptive learning
: Add learner profile
#9673
base: develop
Are you sure you want to change the base?
Conversation
src/main/java/de/tum/cit/aet/artemis/atlas/domain/profile/CourseLearnerProfile.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/atlas/service/profile/CourseLearnerProfileService.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (1)
src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java (1)
1060-1064
: Consider using the same course instance.The method fetches a new course instance with competencies but uses the original course instance for creating the learner profile. This could lead to inconsistencies.
if (group.equals(course.getStudentGroupName()) && course.getLearningPathsEnabled()) { Course courseWithCompetencies = courseRepository.findWithEagerCompetenciesAndPrerequisitesByIdElseThrow(course.getId()); - courseLearnerProfileService.createCourseLearnerProfile(course, user); - learningPathApi.generateLearningPathForUser(courseWithCompetencies, user); + courseLearnerProfileService.createCourseLearnerProfile(courseWithCompetencies, user); + learningPathApi.generateLearningPathForUser(courseWithCompetencies, user); }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (1)
src/main/resources/config/liquibase/master.xml
is excluded by!**/*.xml
📒 Files selected for processing (2)
src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java
(9 hunks)src/main/java/de/tum/cit/aet/artemis/core/web/CourseResource.java
(10 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java (1)
Pattern src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
src/main/java/de/tum/cit/aet/artemis/core/web/CourseResource.java (1)
Pattern src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
🔇 Additional comments (7)
src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java (4)
218-218
: LGTM: Clean dependency injection.
The CourseLearnerProfileService
is properly injected following constructor injection best practices.
Also applies to: 233-233, 277-277
515-515
: LGTM: Proper cleanup of learner profiles.
The deletion of learner profiles is correctly placed in the course deletion sequence, ensuring proper cleanup of all related data.
677-677
: LGTM: Proper cleanup on unenrollment.
The deletion of learner profiles on user unenrollment ensures proper cleanup of user data.
216-216
: 🛠️ Refactor suggestion
Remove redundant field.
The faqRepository
field appears to be redundant and should be removed.
- private final FaqRepository faqRepository;
Likely invalid or redundant comment.
src/main/java/de/tum/cit/aet/artemis/core/web/CourseResource.java (3)
70-70
: LGTM: Clean dependency injection implementation
The addition of CourseLearnerProfileService
follows best practices with constructor injection and immutable field declaration.
Also applies to: 181-182, 201-201, 225-225
1184-1184
: LGTM: Simplified method signatures
The removal of redundant role parameters simplifies the API while maintaining functionality. The implementation now directly uses group names, following the KISS principle.
Also applies to: 1199-1199, 1215-1215, 1230-1230
342-343
:
Add transaction boundary for data consistency
The creation of learner profiles and generation of learning paths involves multiple database operations. Without proper transaction boundaries, this could lead to inconsistent state if one operation fails.
Add @Transactional
annotation to ensure atomic operations:
+ @Transactional
public ResponseEntity<Course> updateCourse(@PathVariable Long courseId, @RequestPart("course") Course courseUpdate, @RequestPart(required = false) MultipartFile file)
src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (1)
src/main/java/de/tum/cit/aet/artemis/atlas/api/LearnerProfileApi.java (1)
1-51
: Add API documentation using OpenAPI/Swagger annotations.The API endpoints lack documentation. Consider adding OpenAPI annotations to document the API endpoints, parameters, and responses.
Add OpenAPI annotations, for example:
+@Operation(summary = "Delete all learner profiles for a course") +@ApiResponse(responseCode = "200", description = "Learner profiles deleted successfully") +@ApiResponse(responseCode = "403", description = "Forbidden") +@ApiResponse(responseCode = "500", description = "Internal server error") public void deleteAllForCourse(Course course) {
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (6)
src/main/java/de/tum/cit/aet/artemis/atlas/api/LearnerProfileApi.java
(1 hunks)src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java
(9 hunks)src/main/java/de/tum/cit/aet/artemis/core/service/UserScheduleService.java
(3 hunks)src/main/java/de/tum/cit/aet/artemis/core/service/user/UserCreationService.java
(5 hunks)src/main/java/de/tum/cit/aet/artemis/core/service/user/UserService.java
(4 hunks)src/main/java/de/tum/cit/aet/artemis/core/web/CourseResource.java
(10 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/main/java/de/tum/cit/aet/artemis/core/service/UserScheduleService.java
- src/main/java/de/tum/cit/aet/artemis/core/web/CourseResource.java
🧰 Additional context used
📓 Path-based instructions (4)
src/main/java/de/tum/cit/aet/artemis/core/service/user/UserCreationService.java (1)
Pattern src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
src/main/java/de/tum/cit/aet/artemis/core/service/user/UserService.java (1)
Pattern src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java (1)
Pattern src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
src/main/java/de/tum/cit/aet/artemis/atlas/api/LearnerProfileApi.java (1)
Pattern src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
🔇 Additional comments (6)
src/main/java/de/tum/cit/aet/artemis/core/service/user/UserCreationService.java (3)
26-26
: LGTM: Dependency injection is properly implemented
The new dependency follows best practices with constructor injection and immutability.
Also applies to: 78-78
82-82
: LGTM: Constructor properly initialized
The constructor correctly initializes all dependencies including the new LearnerProfileApi.
Also applies to: 91-91
149-150
:
Add transaction boundary and error handling for profile creation
The profile creation should be part of the same transaction as user creation to maintain data consistency. If profile creation fails, we might end up with users without profiles.
Consider wrapping the operations in a transaction and adding proper error handling:
- newUser = saveUser(newUser);
- learnerProfileApi.createProfile(newUser);
+ @Transactional
+ protected User createUserWithProfile(User newUser) {
+ try {
+ newUser = saveUser(newUser);
+ learnerProfileApi.createProfile(newUser);
+ return newUser;
+ } catch (Exception e) {
+ log.error("Failed to create user profile for user {}: {}", newUser.getLogin(), e.getMessage());
+ throw new UserProfileCreationException("Failed to create user profile", e);
+ }
+ }
Similar changes should be applied to both createUser methods.
Also applies to: 204-205
src/main/java/de/tum/cit/aet/artemis/core/service/user/UserService.java (1)
476-478
: Add error handling for profile deletion.
The profile deletion operation should include error handling to ensure the user deletion process continues even if profile deletion fails.
src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java (2)
626-628
: Extract duplicated learner profile creation logic.
The logic for creating a learner profile and generating a learning path is duplicated in multiple methods. Consider extracting it into a private helper method.
Also applies to: 660-664, 1060-1064
677-677
: Add learner profile cleanup for student group removal.
When removing a user from the student group, consider cleaning up their learner profile if learning paths are enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-approve code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reapprove code 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reapprove
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reapprove
5ec7732
Warning
This PR includes a migration! Do not deploy on testservers
Checklist
General
Server
Motivation and Context
Based on #9448
Description
Added LearnerProfile and CourseLearnerProfile. Each user has a LearnerProfile and each user in an active (current semester and not a test course) course with learning paths has automatically a course learner profile.
The CourseLearnerProfile is also created when a user enrolls in a course with learning paths or learning paths get enabled. The profiles are deleted if the user unenrolls or is deleted.
This PR does not add any UI!
Steps for Testing
🚨 🚨 Local setup to verify database entries 🚨 🚨
Course with enabled learning paths and some students
Review Progress
Performance Review
Code Review
Manual Tests
Performance Tests
Test Coverage
Summary by CodeRabbit
New Features
CourseLearnerProfile
andLearnerProfile
classes for enhanced profile management.Bug Fixes
Tests