-
Notifications
You must be signed in to change notification settings - Fork 305
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
Development
: Introduce tutorialgroup module API
#10266
base: develop
Are you sure you want to change the base?
Conversation
WalkthroughThe changes across multiple modules focus on replacing direct repository and service dependencies with Optional API interfaces. Existing classes in the communication, notification, core, and web layers have been updated to conditionally interact with these new APIs. Additionally, several new API classes have been introduced to encapsulate tutorial group functionalities such as communication details, channel management, notifications, and registrations. A new architecture test for the tutorial group module has also been added. Changes
Sequence Diagram(s)sequenceDiagram
participant Service as ConversationDTOService
participant API as TutorialGroupCommunicationApi
participant DTO as ChannelDTO
Service->>API: Check if Optional API is present
alt API Present
Service->>API: getTutorialGroupCommunicationDetails(channelId)
API-->>Service: Return (tutorialGroupId, tutorialGroupTitle)
Service->>DTO: Set tutorialGroupId and tutorialGroupTitle
else API Absent
Service->>DTO: Set tutorialGroup details to defaults
end
sequenceDiagram
participant NR as NotificationResource
participant TGA as TutorialGroupApi
participant User as CurrentUser
NR->>User: Retrieve currentUser info
alt TutorialGroupApi Present
NR->>TGA: findAllForNotifications(currentUser)
TGA-->>NR: Return tutorialGroupIds (set)
else API Absent
NR-->>NR: Initialize empty tutorialGroupIds set
end
NR->>User: Process notifications with retrieved group IDs
Suggested labels
Suggested reviewers
✨ Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
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
🧹 Nitpick comments (10)
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupNotificationApi.java (1)
11-13
: Consider using @service instead of @controller.Since this class is not handling web requests but rather providing a service facade for tutorial group notifications,
@Service
would be more appropriate than@Controller
.@Profile(PROFILE_CORE) -@Controller +@Service public class TutorialGroupNotificationApi extends AbstractTutorialGroupApi {src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupRegistrationApi.java (2)
15-17
: Consider using@Service
instead of@Controller
.This class appears to be a service facade rather than a REST controller as it doesn't handle HTTP requests directly. Using
@Service
would better reflect its role in the architecture.@Profile(PROFILE_CORE) -@Controller +@Service public class TutorialGroupRegistrationApi extends AbstractTutorialGroupApi {
19-23
: Add null check for injected dependency.While Spring handles dependency injection, it's a good practice to add explicit null checks to fail fast and provide clear error messages.
public TutorialGroupRegistrationApi(TutorialGroupRegistrationRepository tutorialGroupRegistrationRepository) { + if (tutorialGroupRegistrationRepository == null) { + throw new IllegalArgumentException("TutorialGroupRegistrationRepository must not be null"); + } this.tutorialGroupRegistrationRepository = tutorialGroupRegistrationRepository; }src/main/java/de/tum/cit/aet/artemis/communication/service/notifications/TutorialGroupNotificationService.java (1)
99-100
: Consider handling invalid registrations.While this maps each registration to its student, consider skipping entries with null or invalid students to avoid potential NPEs or incomplete data.
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupApi.java (1)
30-48
: Add JavaDoc documentation for public methods.Each public method should be documented with JavaDoc to describe its purpose, parameters, return values, and any exceptions it may throw.
Apply this diff to add JavaDoc:
+ /** + * Find all tutorial group IDs associated with notifications for a user. + * @param user The user to find notifications for + * @return Set of tutorial group IDs + */ public Set<Long> findAllForNotifications(User user) { return tutorialGroupService.findAllForNotifications(user); } + /** + * Count tutorial groups associated with a course. + * @param course The course to count tutorial groups for + * @return Number of tutorial groups + */ public Long countByCourse(Course course) { return tutorialGroupRepository.countByCourse(course); } + /** + * Find all tutorial groups for a course. + * @param courseId ID of the course + * @return Set of tutorial groups + */ public Set<TutorialGroup> findAllByCourseId(Long courseId) { return tutorialGroupRepository.findAllByCourseId(courseId); } + /** + * Delete a tutorial group by its ID. + * @param id ID of the tutorial group to delete + */ public void deleteById(Long id) { tutorialGroupRepository.deleteById(id); } + /** + * Find a tutorial group by its channel ID. + * @param channelId ID of the channel + * @return Optional containing the tutorial group if found + */ public Optional<TutorialGroup> findByTutorialGroupChannelId(Long channelId) { return tutorialGroupRepository.findByTutorialGroupChannelId(channelId); }src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupChannelManagementApi.java (1)
30-40
: Add JavaDoc documentation for public methods.Each public method should be documented with JavaDoc to describe its purpose, parameters, and return values.
Apply this diff to add JavaDoc:
+ /** + * Get the tutorial group associated with a channel. + * @param channel The channel to find the tutorial group for + * @return Optional containing the tutorial group if found + */ public Optional<TutorialGroup> getTutorialGroupBelongingToChannel(Channel channel) { return tutorialGroupChannelManagementService.getTutorialGroupBelongingToChannel(channel); } + /** + * Delete the channel associated with a tutorial group. + * @param tutorialGroup The tutorial group whose channel should be deleted + */ public void deleteTutorialGroupChannel(TutorialGroup tutorialGroup) { tutorialGroupChannelManagementService.deleteTutorialGroupChannel(tutorialGroup); } + /** + * Handle timezone updates for a course. + * @param course The course whose timezone has been updated + */ public void onTimeZoneUpdate(Course course) { tutorialGroupsConfigurationService.onTimeZoneUpdate(course); }src/main/java/de/tum/cit/aet/artemis/communication/service/conversation/ConversationDTOService.java (2)
138-144
: Consider extracting tutorial group mapping logic to a private method.The tutorial group mapping logic is duplicated in both
convertChannelToDTO
methods. Consider extracting it to a private method to improve code reusability and maintainability.+private void setTutorialGroupInfo(ChannelDTO channelDTO, Channel channel) { + if (tutorialGroupApi.isPresent()) { + var tutorialGroup = tutorialGroupApi.get().findByTutorialGroupChannelId(channel.getId()); + tutorialGroup.ifPresent(tg -> { + channelDTO.setTutorialGroupId(tg.getId()); + channelDTO.setTutorialGroupTitle(tg.getTitle()); + }); + } +} public ChannelDTO convertChannelToDTO(User requestingUser, Channel channel) { // ... existing code ... - if (tutorialGroupApi.isPresent()) { - var tutorialGroup = tutorialGroupApi.get().findByTutorialGroupChannelId(channel.getId()); - tutorialGroup.ifPresent(tg -> { - channelDTO.setTutorialGroupId(tg.getId()); - channelDTO.setTutorialGroupTitle(tg.getTitle()); - }); - } + setTutorialGroupInfo(channelDTO, channel); return channelDTO; }
168-174
: Duplicate code: Use the extracted method here as well.This is the same tutorial group mapping logic as in the other method. Use the extracted method here.
-if (tutorialGroupApi.isPresent()) { - var tutorialGroup = tutorialGroupApi.get().findByTutorialGroupChannelId(channel.getId()); - tutorialGroup.ifPresent(tg -> { - channelDTO.setTutorialGroupId(tg.getId()); - channelDTO.setTutorialGroupTitle(tg.getTitle()); - }); -} +setTutorialGroupInfo(channelDTO, channel);src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java (1)
288-290
: Consider improving error message clarity.The error message could be more descriptive about why the channel cannot be deleted. Consider mentioning that tutorial group channels must be managed through the tutorial group interface.
-throw new BadRequestAlertException("The channel belongs to tutorial group " + tutorialGroup.getTitle(), CHANNEL_ENTITY_NAME, "channel.tutorialGroup.mismatch"); +throw new BadRequestAlertException("Cannot delete channel: It belongs to tutorial group '" + tutorialGroup.getTitle() + "'. Tutorial group channels must be managed through the tutorial group interface.", CHANNEL_ENTITY_NAME, "channel.tutorialGroup.mismatch");src/main/java/de/tum/cit/aet/artemis/core/web/CourseResource.java (1)
350-352
: Consider extracting time zone update logic to a private method.The time zone update logic could be extracted to a private method to improve readability and maintainability.
+private void handleTimeZoneUpdate(Course course) { + if (tutorialGroupChannelManagementApi.isPresent()) { + tutorialGroupChannelManagementApi.get().onTimeZoneUpdate(course); + } +} -if (timeZoneChanged && tutorialGroupChannelManagementApi.isPresent()) { - tutorialGroupChannelManagementApi.get().onTimeZoneUpdate(result); +if (timeZoneChanged) { + handleTimeZoneUpdate(result); }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
src/main/java/de/tum/cit/aet/artemis/communication/service/conversation/ConversationDTOService.java
(4 hunks)src/main/java/de/tum/cit/aet/artemis/communication/service/notifications/TutorialGroupNotificationService.java
(4 hunks)src/main/java/de/tum/cit/aet/artemis/communication/web/NotificationResource.java
(4 hunks)src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java
(5 hunks)src/main/java/de/tum/cit/aet/artemis/core/exception/ApiNotPresentException.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/web/CourseResource.java
(5 hunks)src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/AbstractTutorialGroupApi.java
(1 hunks)src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupApi.java
(1 hunks)src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupChannelManagementApi.java
(1 hunks)src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupNotificationApi.java
(1 hunks)src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupRegistrationApi.java
(1 hunks)src/test/java/de/tum/cit/aet/artemis/tutorialgroup/architecture/TutorialGroupApiArchitectureTest.java
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/AbstractTutorialGroupApi.java
🧰 Additional context used
📓 Path-based instructions (12)
src/test/java/de/tum/cit/aet/artemis/tutorialgroup/architecture/TutorialGroupApiArchitectureTest.java (1)
Pattern src/test/java/**/*.java
: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupChannelManagementApi.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/exception/ApiNotPresentException.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/tutorialgroup/api/TutorialGroupRegistrationApi.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/communication/service/conversation/ConversationDTOService.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/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
src/main/java/de/tum/cit/aet/artemis/communication/web/NotificationResource.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/tutorialgroup/api/TutorialGroupApi.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/communication/web/conversation/ChannelResource.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/tutorialgroup/api/TutorialGroupNotificationApi.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/communication/service/notifications/TutorialGroupNotificationService.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
📓 Learnings (3)
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupRegistrationApi.java (1)
Learnt from: Strohgelaender
PR: ls1intum/Artemis#8574
File: src/main/java/de/tum/in/www1/artemis/service/tutorialgroups/TutorialGroupService.java:0-0
Timestamp: 2024-11-12T12:51:58.050Z
Learning: The `tryToFindMatchingUsers` method in `TutorialGroupService.java` has been updated to skip registrations without a student, enhancing the method's robustness. This change was implemented in commit `bef30f9751de0913143e8cb28cc0088264052261`.
src/main/java/de/tum/cit/aet/artemis/communication/web/NotificationResource.java (1)
Learnt from: Strohgelaender
PR: ls1intum/Artemis#8574
File: src/main/java/de/tum/in/www1/artemis/service/tutorialgroups/TutorialGroupService.java:0-0
Timestamp: 2024-11-12T12:51:58.050Z
Learning: The `tryToFindMatchingUsers` method in `TutorialGroupService.java` has been updated to skip registrations without a student, enhancing the method's robustness. This change was implemented in commit `bef30f9751de0913143e8cb28cc0088264052261`.
src/main/java/de/tum/cit/aet/artemis/communication/service/notifications/TutorialGroupNotificationService.java (1)
Learnt from: Strohgelaender
PR: ls1intum/Artemis#8574
File: src/main/java/de/tum/in/www1/artemis/service/tutorialgroups/TutorialGroupService.java:0-0
Timestamp: 2024-11-12T12:51:58.050Z
Learning: The `tryToFindMatchingUsers` method in `TutorialGroupService.java` has been updated to skip registrations without a student, enhancing the method's robustness. This change was implemented in commit `bef30f9751de0913143e8cb28cc0088264052261`.
⏰ Context from checks skipped due to timeout of 90000ms (7)
- GitHub Check: Call Build Workflow / Build and Push Docker Image
- GitHub Check: Call Build Workflow / Build .war artifact
- GitHub Check: client-tests
- GitHub Check: client-style
- GitHub Check: server-style
- GitHub Check: server-tests
- GitHub Check: Analyse
🔇 Additional comments (29)
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupNotificationApi.java (2)
1-10
: LGTM! Package structure and imports are well-organized.The package structure follows Java naming conventions, and imports are specific without using wildcard imports.
15-19
: LGTM! Field declaration and constructor follow best practices.The code follows best practices by:
- Using constructor injection
- Making the field private and final
- Following the principle of least access
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupRegistrationApi.java (1)
1-14
: LGTM!Package declaration and imports are well-organized, following Java naming conventions and avoiding star imports.
src/main/java/de/tum/cit/aet/artemis/communication/service/notifications/TutorialGroupNotificationService.java (5)
8-8
: Nice introduction of Optional APIs and custom exception.Using
Optional
to represent potentially unavailable functionality and throwingApiNotPresentException
when absent is a clean approach to modular disablement.Also applies to: 20-22
31-31
: Fields align well with the new API-based design.Declaring Optional fields for
tutorialGroupNotificationApi
andtutorialGroupRegistrationApi
ensures graceful handling of disabled modules without polluting code with null checks.Also applies to: 33-33
41-45
: Injection of Optionals in the constructor is consistent.This constructor neatly enforces the presence of either a valid API or throws an exception when it’s missing. All good here.
72-73
: Safe fallback with orElseThrow.Efficiently terminates the flow if the notification API is unavailable. Ensure upstream callers are prepared to handle
ApiNotPresentException
.
95-95
: Same pattern for the registration API.Consistently applying the same fallback strategy for the registration API provides uniform handling. No issues noted.
src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java (5)
86-86
: Addition of ApiNotPresentException and optional tutorial group APIs.Imports are well-structured and reflect the new API-based approach for tutorial groups. This is consistent with the modular design shift.
Also applies to: 119-121
135-135
: Optional fields align with the disablement mechanism.These field declarations neatly accommodate conditional availability of tutorial group functionalities, maintaining clean boundaries.
Also applies to: 199-199, 211-211
234-234
: Constructor injection of Optionals is coherent and maintainable.You've properly assigned the optional API fields within the constructor. This design fosters clarity regarding module presence.
Also applies to: 236-236, 269-269, 275-275, 276-276
372-377
: Handling absent TutorialGroupApi during course retrieval.Falling back to zero tutorial groups if the API is missing is a simple, user-friendly fallback. This approach cleanly avoids error cascades.
546-546
: Tutorial group deletion flow respects new modular APIs.Fetching the API with
orElseThrow
ensures the module is enabled before proceeding, and conditionally deletes channels and notifications to maintain data consistency.Also applies to: 548-548, 551-552
src/test/java/de/tum/cit/aet/artemis/tutorialgroup/architecture/TutorialGroupApiArchitectureTest.java (2)
1-5
: New architecture test introduced.Extending the
AbstractModuleAccessArchitectureTest
for the tutorial group module is a solid approach to verify module boundaries and usage.
7-10
: Module package resolved for tutorial group.Overriding
getModulePackage
helps ensure the architecture tests specifically target thetutorialgroup
package.src/main/java/de/tum/cit/aet/artemis/core/exception/ApiNotPresentException.java (1)
6-18
: LGTM! Well-structured exception class with clear error messaging.The implementation follows best practices with proper JavaDoc documentation and a clear, informative error message format.
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupApi.java (1)
25-28
: LGTM! Constructor injection is properly implemented.The constructor follows Spring best practices for dependency injection.
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupChannelManagementApi.java (1)
24-28
: LGTM! Constructor injection is properly implemented.The constructor follows Spring best practices for dependency injection.
src/main/java/de/tum/cit/aet/artemis/communication/web/NotificationResource.java (2)
57-65
: LGTM! Optional dependency is properly handled.The constructor injection and field declaration follow Spring best practices.
82-88
: LGTM! Proper handling of optional API presence.The code correctly handles the case when the tutorial group API is not present by falling back to an empty set.
src/main/java/de/tum/cit/aet/artemis/communication/service/conversation/ConversationDTOService.java (3)
34-34
: LGTM!Clean import of the new API interface.
46-46
: LGTM!Field declaration correctly uses Optional wrapper for the API dependency, following the module API pattern.
50-51
: LGTM!Constructor properly handles the Optional API dependency injection.
Also applies to: 55-55
src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java (3)
57-57
: LGTM!Clean import of the new API interface.
80-80
: LGTM!Field declaration correctly uses Optional wrapper for the API dependency, following the module API pattern.
86-89
: LGTM!Constructor properly handles the Optional API dependency injection.
Also applies to: 98-98
src/main/java/de/tum/cit/aet/artemis/core/web/CourseResource.java (3)
125-125
: LGTM!Clean import of the new API interface.
170-170
: LGTM!Field declaration correctly uses Optional wrapper for the API dependency, following the module API pattern.
193-197
: LGTM!Constructor properly handles the Optional API dependency injection.
Also applies to: 214-214
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupNotificationApi.java
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupRegistrationApi.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: 1
🧹 Nitpick comments (2)
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupApi.java (2)
22-29
: Consider adding@Autowired
annotation for clarity.While constructor injection works without
@Autowired
in Spring, adding it makes the dependency injection more explicit. Also, the@Lazy
annotation suggests a circular dependency that might need attention.- public TutorialGroupApi(TutorialGroupRepository tutorialGroupRepository, @Lazy TutorialGroupService tutorialGroupService) { + @Autowired + public TutorialGroupApi(TutorialGroupRepository tutorialGroupRepository, @Lazy TutorialGroupService tutorialGroupService) {
31-49
: Consider adding transaction boundaries.The methods that modify data (e.g.,
deleteById
) should be wrapped in transactions to ensure data consistency.+ @Transactional public void deleteById(Long id) { tutorialGroupRepository.deleteById(id); }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupApi.java
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`src/main/java/**/*.java`: naming:CamelCase; principles:{sin...
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/tutorialgroup/api/TutorialGroupApi.java
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (1)
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupApi.java (1)
1-20
: LGTM! Well-structured class with proper annotations and imports.The class follows Java naming conventions, uses specific imports, and is properly annotated for Spring framework integration.
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: 1
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/main/java/de/tum/cit/aet/artemis/communication/service/conversation/ConversationDTOService.java
(4 hunks)src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupApi.java
(1 hunks)src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupCommunicationApi.java
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupApi.java
- src/main/java/de/tum/cit/aet/artemis/communication/service/conversation/ConversationDTOService.java
🧰 Additional context used
📓 Path-based instructions (1)
`src/main/java/**/*.java`: naming:CamelCase; principles:{sin...
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/tutorialgroup/api/TutorialGroupCommunicationApi.java
⏰ Context from checks skipped due to timeout of 90000ms (9)
- GitHub Check: Codacy Static Code Analysis
- GitHub Check: Call Build Workflow / Build .war artifact
- GitHub Check: Call Build Workflow / Build and Push Docker Image
- GitHub Check: client-tests
- GitHub Check: client-style
- GitHub Check: server-style
- GitHub Check: server-tests
- GitHub Check: Analyse
- GitHub Check: Mend Security Check
🔇 Additional comments (3)
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupCommunicationApi.java (3)
1-14
: LGTM! Well-organized imports and package structure.The imports are specific and well-organized, following Java best practices.
19-23
: LGTM! Clean dependency injection implementation.Good use of constructor injection and final field, following Spring best practices.
15-17
: Consider using@Component
instead of@Controller
.Since this class acts as a facade for repository access rather than handling HTTP requests directly,
@Component
might be more appropriate than@Controller
.Please verify if this class needs to handle web requests. If not, consider changing the annotation:
-@Controller +@Component✅ Verification successful
I'm going to verify if this class is handling web requests by checking for any mapping annotations within it. We'll execute a shell script to search for common Spring HTTP mapping annotations (such as @RequestMapping, @GetMapping, @PostMapping, etc.) in the file.
🏁 Script executed:
#!/bin/bash # Search for Spring web mapping annotations in the file to determine if it's used for handling HTTP requests rg -n "@(RequestMapping|GetMapping|PostMapping|PutMapping|DeleteMapping)" src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupCommunicationApi.javaLength of output: 165
I'll generate a new script to display the first 100 lines of the file. This will let us manually inspect whether any HTTP request mapping annotations (such as @RequestMapping or @GetMapping) are present in any method declarations that might have been overlooked.
🏁 Script executed:
#!/bin/bash head -n 100 src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupCommunicationApi.java
Length of output: 1254
Annotation Choice Verification
The file doesn't contain any HTTP endpoint mapping annotations. Its sole public method doesn’t handle HTTP requests, confirming that the class is acting as a facade for repository access rather than exposing web endpoints. Based on this, replacing @controller with @component (or another appropriate stereotype) is advisable.
src/main/java/de/tum/cit/aet/artemis/tutorialgroup/api/TutorialGroupCommunicationApi.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.
tested on server3 and worked as expected.
9e9b8d5
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: 0
🧹 Nitpick comments (3)
src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java (1)
445-445
: Consider implementing a limit for bulk deregistration.The TODO comment suggests implementing a limit on the number of users that can be deregistered at once. This could help prevent potential performance issues or abuse.
Would you like me to help implement this feature by suggesting a solution that includes:
- A configurable maximum limit
- Batch processing for large deregistrations
- Error handling for requests exceeding the limit
src/main/java/de/tum/cit/aet/artemis/core/web/CourseResource.java (1)
193-200
: Consider using the builder pattern to improve constructor readability.The constructor has many parameters (20+) which makes it hard to maintain and use. Consider refactoring to use the builder pattern or breaking down the class into smaller components to reduce the number of dependencies.
Example builder pattern implementation:
public class CourseResource { private CourseResource(CourseResourceBuilder builder) { this.userRepository = builder.userRepository; this.courseService = builder.courseService; // ... other assignments } public static class CourseResourceBuilder { private UserRepository userRepository; private CourseService courseService; // ... other fields public CourseResourceBuilder userRepository(UserRepository userRepository) { this.userRepository = userRepository; return this; } public CourseResourceBuilder courseService(CourseService courseService) { this.courseService = courseService; return this; } // ... other builder methods public CourseResource build() { return new CourseResource(this); } } }src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java (1)
547-555
: Consider enhancing error handling in deleteTutorialGroupsOfCourse.While the implementation is functionally correct, there are a few improvements that could be made:
- The error handling could be more granular for each API operation
- The operations could benefit from being transactional
Consider this enhanced implementation:
private void deleteTutorialGroupsOfCourse(Course course) { - var api = tutorialGroupApi.orElseThrow(() -> new ApiNotPresentException(TutorialGroupApi.class, PROFILE_CORE)); - var tutorialGroups = api.findAllByCourseId(course.getId()); - // we first need to delete notifications and channels, only then we can delete the tutorial group - tutorialGroups.forEach(tutorialGroup -> { - tutorialGroupNotificationApi.ifPresent(notApi -> notApi.deleteAllByTutorialGroupId(tutorialGroup.getId())); - tutorialGroupChannelManagementApi.ifPresent(manApi -> manApi.deleteTutorialGroupChannel(tutorialGroup)); - api.deleteById(tutorialGroup.getId()); - }); + var api = tutorialGroupApi.orElseThrow(() -> new ApiNotPresentException(TutorialGroupApi.class, PROFILE_CORE)); + var tutorialGroups = api.findAllByCourseId(course.getId()); + // we first need to delete notifications and channels, only then we can delete the tutorial group + tutorialGroups.forEach(tutorialGroup -> { + try { + tutorialGroupNotificationApi.ifPresent(notApi -> { + try { + notApi.deleteAllByTutorialGroupId(tutorialGroup.getId()); + } catch (Exception e) { + log.error("Failed to delete notifications for tutorial group {}: {}", tutorialGroup.getId(), e.getMessage()); + } + }); + tutorialGroupChannelManagementApi.ifPresent(manApi -> { + try { + manApi.deleteTutorialGroupChannel(tutorialGroup); + } catch (Exception e) { + log.error("Failed to delete channel for tutorial group {}: {}", tutorialGroup.getId(), e.getMessage()); + } + }); + api.deleteById(tutorialGroup.getId()); + } catch (Exception e) { + log.error("Failed to delete tutorial group {}: {}", tutorialGroup.getId(), e.getMessage()); + } + }); }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java
(5 hunks)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
(5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`src/main/java/**/*.java`: naming:CamelCase; principles:{sin...
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
src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java
src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: Call Build Workflow / Build and Push Docker Image
- GitHub Check: Call Build Workflow / Build .war artifact
- GitHub Check: Codacy Static Code Analysis
- GitHub Check: client-style
- GitHub Check: client-tests
- GitHub Check: server-style
- GitHub Check: server-tests
- GitHub Check: Analyse
🔇 Additional comments (10)
src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java (2)
81-81
: LGTM! Good use of dependency inversion.The change from direct service dependency to an optional API interface improves modularity and follows the dependency inversion principle.
Also applies to: 90-90, 99-99
289-291
: LGTM! Improved null safety with Optional.The use of
flatMap
provides better null safety and follows functional programming practices. The error message is clear and informative.src/main/java/de/tum/cit/aet/artemis/core/web/CourseResource.java (4)
125-125
: LGTM!The import is correctly placed and follows Java best practices by avoiding wildcard imports.
170-170
: LGTM!The field declaration follows best practices:
- Appropriate use of Optional for optional dependency
- Proper encapsulation with private modifier
- Immutability with final modifier
- Clear and descriptive naming
214-214
: LGTM!The field assignment is correctly placed and follows the established pattern.
350-352
: LGTM!The time zone update handling is well-implemented:
- Proper null safety using Optional
- Efficient conditional execution only when time zone changes
- Clean and readable code structure
src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java (4)
86-86
: LGTM! Clean import organization.The new imports for tutorial group APIs and exception handling are well-organized and follow the package structure.
Also applies to: 119-121
135-135
: LGTM! Proper field declarations.The new Optional API fields are correctly declared as final and follow the established pattern of using Optional for modular APIs.
Also applies to: 199-199, 211-211
234-234
: LGTM! Constructor injection follows best practices.The constructor properly injects the new Optional API dependencies, maintaining the pattern of constructor-based dependency injection.
Also applies to: 236-236, 269-269, 275-276
372-377
: LGTM! Proper null safety with Optional API.The code correctly handles the Optional API presence check for counting tutorial groups, providing a safe fallback to 0 when the API is not present.
Requires #10359 to be merged as currently, one cannot create new tutorial group configurations. |
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: 0
🧹 Nitpick comments (7)
src/main/webapp/app/course/tutorial-groups/tutorial-groups-management/tutorial-groups/crud/tutorial-group-form/schedule-form/schedule-form.component.ts (3)
15-17
: LGTM! Consider optimizing imports organization.The addition of Artemis pipes and their configuration in the component decorator is correct. The pipes are properly imported and configured in both providers and imports arrays.
Consider organizing imports by grouping them into these categories (separated by blank lines):
- Angular core imports
- Angular form imports
- Third-party library imports
- Application-specific imports
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit, inject } from '@angular/core'; import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; + import { faCalendarAlt } from '@fortawesome/free-solid-svg-icons'; import { NgbDateParserFormatter, NgbTimeAdapter, NgbTimepicker } from '@ng-bootstrap/ng-bootstrap'; -import { weekDays } from 'app/course/tutorial-groups/shared/weekdays'; import { Course } from 'app/entities/course.model'; import * as _ from 'lodash-es'; import dayjs from 'dayjs/esm'; + +import { weekDays } from 'app/course/tutorial-groups/shared/weekdays'; import { dayOfWeekZeroSundayToZeroMonday } from 'app/utils/date.utils';Also applies to: 32-34
107-117
: Enhance type safety in form initialization.While the form initialization and validation are correct, the form lacks proper type safety. Consider using strongly typed form controls.
- this.formGroup = this.fb.group( + this.formGroup = this.fb.group<{ + dayOfWeek: FormControl<number>; + startTime: FormControl<string>; + endTime: FormControl<string>; + repetitionFrequency: FormControl<number>; + period: FormControl<Date[]>; + location: FormControl<string>; + }>( { dayOfWeek: [1, Validators.required], startTime: ['13:00:00', [Validators.required]],
78-99
: Improve session creation logic for better maintainability.The
createdSessions
getter handles multiple responsibilities and could benefit from being broken down into smaller, more focused methods. Additionally, consider adding error handling for edge cases.Consider refactoring like this:
- get createdSessions() { + private findFirstDayOfWeek(start: dayjs.Dayjs, targetDayOfWeek: number): dayjs.Dayjs { + while (dayOfWeekZeroSundayToZeroMonday(start.day()) + 1 !== targetDayOfWeek) { + start = start.add(1, 'day'); + } + return start; + } + + private generateSessions(start: dayjs.Dayjs, end: dayjs.Dayjs, repetitionFrequency: number): dayjs.Dayjs[] { + const sessions: dayjs.Dayjs[] = []; + while (start.isBefore(end) || start.isSame(end)) { + sessions.push(start); + start = start.add(repetitionFrequency, 'week'); + } + return sessions; + } + + get createdSessions() { const sessions: dayjs.Dayjs[] = []; if (this.formGroup.valid) { const { dayOfWeek, repetitionFrequency, period } = this.formGroup.value; - let start = dayjs(period[0]); + if (!period?.[0] || !period?.[1]) { + return sessions; + } + + let start = dayjs(period[0]); const end = dayjs(period[1]); - // find the first day of the week - while (dayOfWeekZeroSundayToZeroMonday(start.day()) + 1 !== dayOfWeek) { - start = start.add(1, 'day'); + if (!start.isValid() || !end.isValid()) { + return sessions; } - // add sessions - while (start.isBefore(end) || start.isSame(end)) { - sessions.push(start); - start = start.add(repetitionFrequency, 'week'); - } + start = this.findFirstDayOfWeek(start, dayOfWeek); + return this.generateSessions(start, end, repetitionFrequency); } return sessions; }src/main/java/de/tum/cit/aet/artemis/communication/service/notifications/TutorialGroupNotificationService.java (1)
98-98
: Address the TODO comment about registration type adaptation.The comment indicates future work needed to adapt the registration type handling.
Would you like me to help create an issue to track this enhancement for future implementation?
src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java (2)
135-211
: Consider breaking down the service class to reduce dependencies.The class has a high number of dependencies (30+), which could indicate it's handling too many responsibilities. Consider:
- Splitting into smaller, focused services
- Creating separate services for tutorial group, exam, and exercise management
372-377
: Consider simplifying the tutorial group count logic.The conditional count logic could be more concise using Optional's map and orElse:
-if (tutorialGroupApi.isPresent()) { - course.setNumberOfTutorialGroups(tutorialGroupApi.get().countByCourse(course)); -} -else { - course.setNumberOfTutorialGroups(0L); -} +course.setNumberOfTutorialGroups(tutorialGroupApi.map(api -> api.countByCourse(course)).orElse(0L));src/main/webapp/app/course/tutorial-groups/tutorial-groups-management/tutorial-groups-configuration/crud/tutorial-groups-configuration-form/tutorial-groups-configuration-form.component.ts (1)
21-24
: Consider memory optimization with OnPush strategy.The component uses ChangeDetectionStrategy.OnPush, which is good for performance. To fully leverage this:
- Ensure all inputs are immutable
- Use async pipe for observables
- Use pure pipes for transformations
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/main/java/de/tum/cit/aet/artemis/communication/service/notifications/TutorialGroupNotificationService.java
(4 hunks)src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java
(9 hunks)src/main/webapp/app/course/tutorial-groups/tutorial-groups-management/tutorial-groups-configuration/crud/tutorial-groups-configuration-form/tutorial-groups-configuration-form.component.ts
(2 hunks)src/main/webapp/app/course/tutorial-groups/tutorial-groups-management/tutorial-groups/crud/tutorial-group-form/schedule-form/schedule-form.component.ts
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
`src/main/webapp/**/*.ts`: angular_style:https://angular.io/...
src/main/webapp/app/course/tutorial-groups/tutorial-groups-management/tutorial-groups-configuration/crud/tutorial-groups-configuration-form/tutorial-groups-configuration-form.component.ts
src/main/webapp/app/course/tutorial-groups/tutorial-groups-management/tutorial-groups/crud/tutorial-group-form/schedule-form/schedule-form.component.ts
`src/main/java/**/*.java`: naming:CamelCase; principles:{sin...
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/communication/service/notifications/TutorialGroupNotificationService.java
src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java
⏰ Context from checks skipped due to timeout of 90000ms (9)
- GitHub Check: Call Build Workflow / Build and Push Docker Image
- GitHub Check: Call Build Workflow / Build .war artifact
- GitHub Check: Codacy Static Code Analysis
- GitHub Check: client-tests-selected
- GitHub Check: client-style
- GitHub Check: server-style
- GitHub Check: client-tests
- GitHub Check: server-tests
- GitHub Check: Analyse
🔇 Additional comments (6)
src/main/java/de/tum/cit/aet/artemis/communication/service/notifications/TutorialGroupNotificationService.java (3)
31-49
: Well-structured dependency injection with Optional APIs!The refactoring from direct repository dependencies to Optional APIs is well-implemented:
- Uses constructor injection (recommended practice)
- Supports modular architecture through API interfaces
- Enables conditional functionality through Optional wrapper
71-76
: Clean implementation of API usage in saveAndSend!The method properly handles the API dependency:
- Checks for API presence with orElseThrow
- Maintains clean separation of concerns
- Preserves existing notification functionality
94-105
: Well-implemented user notification logic with API integration!The findUsersToNotify method effectively:
- Handles API absence through orElseThrow
- Maintains existing filtering logic
- Uses streams effectively for user collection
src/main/java/de/tum/cit/aet/artemis/core/service/CourseService.java (2)
546-555
: Well-structured tutorial group deletion with API integration!The method properly:
- Handles API absence through orElseThrow
- Deletes related notifications and channels first
- Maintains proper deletion order
547-547
: Consistent error handling with ApiNotPresentException!The error handling is well-implemented:
- Uses consistent pattern across methods
- Provides clear error messages with API class and profile information
src/main/webapp/app/course/tutorial-groups/tutorial-groups-management/tutorial-groups-configuration/crud/tutorial-groups-configuration-form/tutorial-groups-configuration-form.component.ts (1)
9-9
:❓ Verification inconclusive
Verify the usage of ArtemisDatePipe.
The ArtemisDatePipe is imported and provided but doesn't appear to be used in the component. If it's intended for use in the template, ensure it's being utilized effectively. Otherwise, consider removing it to maintain clean dependencies.
Also applies to: 23-23
🏁 Script executed:
#!/bin/bash # Check if ArtemisDatePipe is used in the template rg "artemisDate" "src/main/webapp/app/course/tutorial-groups/tutorial-groups-management/tutorial-groups-configuration/crud/tutorial-groups-configuration-form/tutorial-groups-configuration-form.component.html"Length of output: 436
Action Required: Confirm Whether ArtemisDatePipe Is Actually Utilized in the Component
- The ArtemisDatePipe is imported (line 9) and added to the providers (line 23) of the component, yet there’s no evidence that it’s being used.
- The initial search in an expected external HTML template returned an error (file not found). This suggests one of two scenarios:
- The component uses an inline template instead of an external file.
- The pipe is not used at all.
- Next Steps:
- Manually verify if the component defines an inline template (check for a
template:
property in the.component.ts
file) and confirm whether the pipe is invoked using Angular’s pipe syntax (e.g.,| artemisDate
) within that template.- If no usage is found, please remove the ArtemisDatePipe from both the imports and providers to keep dependencies clean.
- Also, note that employing the OnPush change detection strategy is a good practice for optimizing performance and memory usage.
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.
Tested on TS3, works 👌🏼
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.
Tutorial groups work correctly on Ts3
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.
code LGTM 👍 also tested on ts3 during testing session
Checklist
General
Server
Motivation and Context
As part of the server modularization, we "facade" the service/repository declaration and method calls to module-external classes via a module API provided by the respective module.
Description
Public
for visiblityOut of scope: Adding a
PROFILE_TUTORIALGROUP
(or similar) to disable the module on server start. This requires a lot of frontend changes and testing.Steps for Testing
Can only be test on TS3
Basically try to test all the functionality of tutorialgroup.
Exam Mode Testing
Review Progress
Performance Review
Code Review
Manual Tests
Summary by CodeRabbit
Summary by CodeRabbit
ArtemisDatePipe
.These updates improve the reliability and flexibility of tutorial group features, ensuring smoother user interactions without altering visible behavior.