-
Notifications
You must be signed in to change notification settings - Fork 294
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
Programming exercises
: Add feedback discussion feature to feedback analysis table
#9810
base: develop
Are you sure you want to change the base?
Programming exercises
: Add feedback discussion feature to feedback analysis table
#9810
Conversation
…g-exercises/add-affected-students-to-analysis-table
…d-students-to-analysis-table
…d-affected-students-to-analysis-table' into feature/programming-exercises/add-affected-students-to-analysis-table
…d-students-to-analysis-table
…d-affected-students-to-analysis-table' into feature/programming-exercises/add-affected-students-to-analysis-table
…g-exercises/add-communication-feature-to-analysis-table # Conflicts: # src/main/java/de/tum/cit/aet/artemis/assessment/web/ResultResource.java # src/main/java/de/tum/cit/aet/artemis/exercise/repository/StudentParticipationRepository.java # src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.html # src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.ts # src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts # src/main/webapp/i18n/de/programmingExercise.json # src/main/webapp/i18n/en/programmingExercise.json
…g-exercises/add-communication-feature-to-analysis-table
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
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.
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.
Added my feedback for the server code.
src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/exercise/repository/StudentParticipationRepository.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/exercise/repository/StudentParticipationRepository.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/exercise/repository/StudentParticipationRepository.java
Outdated
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/exercise/repository/StudentParticipationRepository.java
Outdated
Show resolved
Hide resolved
32cf023
…cation-feature-to-analysis-table
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: 7
🧹 Outside diff range and nitpick comments (10)
src/main/java/de/tum/cit/aet/artemis/communication/dto/FeedbackChannelRequestDTO.java (1)
5-7
: Consider adding documentation and validation.Given that this DTO handles potentially sensitive feedback information:
- Add Javadoc to document the purpose and potential sensitive nature of the fields
- Consider adding validation annotations (e.g.,
@NotNull
,@Size
) for the fields@JsonInclude(JsonInclude.Include.NON_EMPTY) +/** + * DTO for creating feedback discussion channels. + * Note: The feedbackDetailText field may contain sensitive feedback information. + * Instructors should ensure appropriate content when creating channels. + */ +public record FeedbackChannelRequestDTO( + @NotNull ChannelDTO channel, + @NotNull @Size(min = 1, max = 1000) String feedbackDetailText) { -public record FeedbackChannelRequestDTO(ChannelDTO channel, String feedbackDetailText) { }src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts (1)
71-78
: Add JSDoc comments for better documentation.Consider adding JSDoc comments to the new methods to document:
- Parameters and their purpose
- Return value
- Possible error cases
- Example usage
Example improvement:
/** * Creates a feedback channel for discussion between instructors and students. * @param courseId - The ID of the course * @param exerciseId - The ID of the exercise * @param feedbackChannelRequest - The channel creation request containing channel details and feedback text * @returns Promise resolving to the created channel * @throws HttpErrorResponse if channel creation fails */ createChannel(courseId: number, exerciseId: number, feedbackChannelRequest: FeedbackChannelRequestDTO): Promise<ChannelDTO>src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts (1)
Line range hint
11-33
: Improve type safety of mock data.Consider using TypeScript interfaces for the mock data to improve type safety and maintainability.
Add these type definitions at the beginning of the file:
interface FeedbackDetailMock { concatenatedFeedbackIds: number[]; detailText: string; testCaseName: string; count: number; relativeCount: number; taskName: string; errorCategory: string; } interface FeedbackAnalysisResponseMock { feedbackDetails: { resultsOnPage: FeedbackDetailMock[]; numberOfPages: number; }; totalItems: number; taskNames: string[]; testCaseNames: string[]; errorCategories: string[]; } const feedbackDetailsMock: FeedbackDetailMock[] = [...]; const feedbackAnalysisResponseMock: FeedbackAnalysisResponseMock = {...};src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.ts (1)
214-217
: Consider adding warning about sensitive informationBased on the PR discussion about potential exposure of sensitive information, consider adding a warning note in the modal template about avoiding sensitive information in channel names and descriptions.
This could help prevent inadvertent exposure of test case information or other sensitive data through user-provided channel names and descriptions.
src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java (2)
491-494
: Use 'var' for local variables to improve readabilityFor consistency with the codebase's style and to improve readability, use 'var' for local variable declarations.
Apply this diff:
- User requestingUser = userRepository.getUserWithGroupsAndAuthorities(); - Course course = courseRepository.findByIdElseThrow(courseId); + var requestingUser = userRepository.getUserWithGroupsAndAuthorities(); + var course = courseRepository.findByIdElseThrow(courseId); checkCommunicationEnabledElseThrow(course); - Channel createdChannel = channelService.createFeedbackChannel(course, exerciseId, channelDTO, feedbackDetailText, requestingUser); + var createdChannel = channelService.createFeedbackChannel(course, exerciseId, channelDTO, feedbackDetailText, requestingUser);
471-481
: Improve Javadoc concisenessThe Javadoc can be more concise while maintaining clarity.
Apply this diff to improve the documentation:
/** - * POST /api/courses/:courseId/channels/: Creates a new feedback-specific channel in a course. + * POST /api/courses/:courseId/exercises/:exerciseId/feedback-channel: Creates a feedback-specific channel. * - * @param courseId where the channel is being created. - * @param exerciseId for which the feedback channel is being created. - * @param feedbackChannelRequest containing a DTO with the properties of the channel (e.g., name, description, visibility) - * and the feedback detail text used to determine the affected students to be added to the channel. + * @param courseId the course ID + * @param exerciseId the exercise ID + * @param feedbackChannelRequest the channel properties and feedback detail text * @return ResponseEntity with status 201 (Created) and the body containing the details of the created channel. * @throws URISyntaxException if the URI for the created resource cannot be constructed. * @throws BadRequestAlertException if the channel name starts with an invalid prefix (e.g., "$"). */src/main/java/de/tum/cit/aet/artemis/exercise/repository/StudentParticipationRepository.java (4)
1365-1371
: Documentation could be more specific.Consider enhancing the documentation:
- For
findAffectedLoginsByFeedbackDetailText
, specify the format of returned logins and any potential empty list scenarios.- For
countAffectedStudentsByFeedbackDetailText
, mention that only negative feedback entries are considered./** * Retrieves the logins of students affected by a specific feedback detail text in a given exercise. * * @param exerciseId The ID of the exercise for which affected students are requested. * @param detailText The feedback detail text to filter by. - * @return A list of student logins affected by the given feedback detail text in the specified exercise. + * @return A list of student logins (usernames) affected by the given feedback detail text. Returns an empty list if no students are affected. */ /** * Counts the number of distinct students affected by a specific feedback detail text for a given programming exercise. * <p> * This query identifies students whose submissions were impacted by feedback entries matching the provided detail text - * within the specified exercise. Only students with non-test run submissions and negative feedback entries are considered. + * within the specified exercise. Only students with non-test run submissions and negative feedback entries (f.positive = FALSE) are considered. * </p>Also applies to: 1388-1398
1372-1386
: Consider performance optimizations for the query.The current implementation might face performance issues with large datasets:
- The subquery for getting the latest result could be inefficient.
- Missing pagination could lead to memory issues with large result sets.
- Consider adding index hints for join conditions.
Consider these improvements:
- Add pagination support to limit the result set size.
- Use a window function instead of a subquery for better performance:
@Query(""" SELECT DISTINCT p.student.login FROM ProgrammingExerciseStudentParticipation p INNER JOIN p.submissions s - INNER JOIN s.results r ON r.id = ( - SELECT MAX(pr.id) - FROM s.results pr - WHERE pr.participation.id = p.id - ) + INNER JOIN s.results r ON r.id = ( + SELECT r2.id FROM s.results r2 + WHERE r2.participation.id = p.id + ORDER BY r2.id DESC + LIMIT 1 + ) INNER JOIN r.feedbacks f WHERE p.exercise.id = :exerciseId AND f.detailText = :detailText AND p.testRun = FALSE """) + @QueryHints(value = { + @QueryHint(name = "org.hibernate.comment", value = "Index hint: idx_participation_exercise"), + @QueryHint(name = "org.hibernate.fetchSize", value = "50") + })
1399-1413
: Optimize the counting query for better performance.The current implementation could be optimized for counting operations:
- Consider using EXISTS instead of COUNT(DISTINCT) for better performance.
- The subquery pattern for latest results could be inefficient.
Consider this optimization:
@Query(""" - SELECT COUNT(DISTINCT p.student.id) + SELECT COUNT(*) + FROM ( + SELECT 1 FROM ProgrammingExerciseStudentParticipation p INNER JOIN p.submissions s INNER JOIN s.results r ON r.id = ( - SELECT MAX(pr.id) - FROM s.results pr - WHERE pr.participation.id = p.id + SELECT r2.id FROM s.results r2 + WHERE r2.participation.id = p.id + ORDER BY r2.id DESC + LIMIT 1 ) INNER JOIN r.feedbacks f WHERE p.exercise.id = :exerciseId AND f.detailText = :detailText AND p.testRun = FALSE + GROUP BY p.student.id + ) AS distinct_students """) + @QueryHints(@QueryHint(name = "org.hibernate.comment", value = "Index hint: idx_participation_exercise"))
1364-1387
: Enhance parameter validation and null safety.Consider adding parameter validation and null safety annotations:
- List<String> findAffectedLoginsByFeedbackDetailText(@Param("exerciseId") long exerciseId, @Param("detailText") String detailText); + List<String> findAffectedLoginsByFeedbackDetailText( + @Param("exerciseId") @NotNull long exerciseId, + @Param("detailText") @NotNull @NotEmpty String detailText); - long countAffectedStudentsByFeedbackDetailText(@Param("exerciseId") long exerciseId, @Param("detailText") String detailText); + long countAffectedStudentsByFeedbackDetailText( + @Param("exerciseId") @NotNull long exerciseId, + @Param("detailText") @NotNull @NotEmpty String detailText);Also applies to: 1388-1413
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (7)
src/main/java/de/tum/cit/aet/artemis/communication/dto/FeedbackChannelRequestDTO.java
(1 hunks)src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java
(5 hunks)src/main/java/de/tum/cit/aet/artemis/exercise/repository/StudentParticipationRepository.java
(1 hunks)src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.ts
(6 hunks)src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts
(3 hunks)src/test/java/de/tum/cit/aet/artemis/communication/ChannelIntegrationTest.java
(5 hunks)src/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
src/main/java/de/tum/cit/aet/artemis/communication/dto/FeedbackChannelRequestDTO.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/exercise/repository/StudentParticipationRepository.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/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.ts (1)
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts (1)
src/test/java/de/tum/cit/aet/artemis/communication/ChannelIntegrationTest.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/test/javascript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts (1)
Pattern src/test/javascript/spec/**/*.ts
: jest: true; mock: NgMocks; bad_practices: avoid_full_module_import; perf_improvements: mock_irrelevant_deps; service_testing: mock_http_for_logic; no_schema: avoid_NO_ERRORS_SCHEMA; expectation_specificity: true; solutions: {boolean: toBeTrue/False, reference: toBe, existence: toBeNull/NotNull, undefined: toBeUndefined, class_obj: toContainEntries/toEqual, spy_calls: {not_called: not.toHaveBeenCalled, once: toHaveBeenCalledOnce, with_value: toHaveBeenCalledWith|toHaveBeenCalledExactlyOnceWith}}
🔇 Additional comments (9)
src/main/java/de/tum/cit/aet/artemis/communication/dto/FeedbackChannelRequestDTO.java (2)
1-4
: LGTM! Package and imports are well-structured.
The package naming and import statement follow best practices, avoiding star imports as required by the coding guidelines.
5-7
: LGTM! Record implementation follows DTO best practices.
The use of a Java record with minimal fields aligns perfectly with the coding guidelines for DTOs.
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts (2)
6-6
: LGTM! Well-structured interface definition.
The FeedbackChannelRequestDTO
interface is properly defined with appropriate naming conventions and clear property structure.
Also applies to: 32-35
71-73
: Consider adding input validation for channel creation.
Given the concerns raised in PR comments about potentially exposing sensitive test case information, consider adding input validation or sanitization for the channel name and description before sending to the server.
Let's check if there are any existing input validation patterns in the codebase:
src/main/webapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.component.ts (3)
2-2
: LGTM: Import statements are well-organized
The new imports are correctly added and necessary for the feedback discussion feature implementation.
Also applies to: 5-5, 14-16
29-30
: LGTM: Properties are well-defined and follow Angular patterns
The new properties are correctly implemented with:
- Required inputs using Angular's new input() syntax
- Proper type definitions
- Modal state management to prevent multiple instances
Also applies to: 55-55, 70-71
204-238
: 🛠️ Refactor suggestion
Enhance error handling and documentation
While the implementation is generally good, there are a few improvements needed:
- Error handling should be more specific and include the channel name in the error message
- The empty catch block should be better documented
Consider applying these improvements:
- this.alertService.error(error);
+ const name = channelDto.name;
+ this.alertService.error(this.TRANSLATION_BASE + '.channelError', { name });
- } catch {
- // modal dismissed
+ } catch {
+ // Modal dismissed by user - no action needed as this is expected behavior
Note: This addresses similar concerns raised in previous reviews while maintaining the improved navigation approach using Angular Router.
src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java (2)
38-38
: LGTM: Dependencies and imports are well-structured
The new dependencies are properly integrated using constructor injection, following Spring best practices.
Also applies to: 46-46, 55-55, 57-57, 87-88, 92-93, 105-105
482-482
: 🛠️ Refactor suggestion
Update endpoint path to follow REST conventions
The current path /{courseId}/{exerciseId}/feedback-channel
should include 'exercises' for consistency with other endpoints and REST conventions.
Apply this diff:
-@PostMapping("{courseId}/{exerciseId}/feedback-channel")
+@PostMapping("{courseId}/exercises/{exerciseId}/feedback-channel")
Likely invalid or redundant comment.
...bapp/app/exercises/programming/manage/grading/feedback-analysis/feedback-analysis.service.ts
Show resolved
Hide resolved
...ript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts
Show resolved
Hide resolved
...ript/spec/component/programming-exercise/feedback-analysis/feedback-analysis.service.spec.ts
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/communication/web/conversation/ChannelResource.java
Show resolved
Hide resolved
src/test/java/de/tum/cit/aet/artemis/communication/ChannelIntegrationTest.java
Show resolved
Hide resolved
src/test/java/de/tum/cit/aet/artemis/communication/ChannelIntegrationTest.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.
Tested on TS3, works as expected
Checklist
General
Server
Client
authorities
to all new routes and checked the course groups for displaying navigation elements (links, buttons).Motivation and Context
This is a follow-up to the feature I’m working on: #9728. The goal is to provide instructors with clearer insights into the feedback given to students. In this PR, a “Feedback Discussion” modal has been introduced. This feature allows instructors to select specific feedback and open a communication channel for it, provided the course has one. For example, during an exam review, instructors can use this functionality to send messages that clarify certain mistakes, offering students a better understanding and clearer insights.
Description
A new server-side query has been implemented, which takes a feedbackDetailText input and creates a channel based on it, automatically adding all students who encountered the corresponding error. On the client side, instructors can now create these channels via a modal accessible on the far-right side of each feedback entry. This modal provides two options: instructors can either navigate directly to the newly created channel or remain on the feedback analysis page. Additionally, the modal allows instructors to specify the channel type, name, and description.
Steps for Testing
Prerequisites:
Testserver States
Note
These badges show the state of the test servers.
Green = Currently available, Red = Currently locked
Click on the badges to get to the test servers.
Review Progress
Performance Review
Code Review
Manual Tests
Performance Tests
Test Coverage
Screenshots
Before:
After:
Summary by CodeRabbit
Summary by CodeRabbit
Release Notes
New Features
Enhancements
Bug Fixes
Documentation