Skip to content

Conversation

@tobias-lippert
Copy link
Contributor

@tobias-lippert tobias-lippert commented Oct 5, 2025

Checklist

General

Server

Motivation and Context

ParticipationResource is our class with the most dependencies

Description

Extracted a QuizParticipationService and split the ParticipationResource into ParticipationResource, ParticipationUpdateResource and ParticipationRetrievalResource

Steps for Testing

Code Review

Testserver States

You can manage test servers using Helios. Check environment statuses in the environment list. To deploy to a test server, go to the CI/CD page, find your PR or branch, and trigger the deployment.

Review Progress

Code Review

  • Code Review 1
  • Code Review 2

Test Coverage

unchanged

Summary by CodeRabbit

  • New Features

    • New endpoints to retrieve participations (including latest results, user-specific views, submissions).
    • New endpoint to delete participations with audit logging.
    • New endpoint to clean up build plans for programming participations.
    • New endpoints to update participations and individual due dates, with validation and scheduling updates.
    • Enhanced quiz participation responses based on quiz state.
  • Refactor

    • Streamlined participation APIs by consolidating responsibilities and access checks for a clearer, more focused interface.
  • Chores

    • Minor logging cleanup in participation services.

@github-project-automation github-project-automation bot moved this to Work In Progress in Artemis Development Oct 5, 2025
@github-actions github-actions bot added server Pull requests that update Java code. (Added Automatically!) exercise Pull requests that affect the corresponding module labels Oct 5, 2025
@tobias-lippert tobias-lippert added this to the 8.4.2 milestone Oct 5, 2025
@tobias-lippert tobias-lippert requested a review from a team as a code owner October 5, 2025 17:42
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 5, 2025

Walkthrough

Adds new REST controllers for participation retrieval, deletion, and updates; introduces QuizParticipationService for quiz-specific participation responses; centralizes authorization via ParticipationAuthorizationService; refactors ParticipationResource to a leaner dependency set and scope; removes logger from ParticipationService.

Changes

Cohort / File(s) Summary
Quiz participation service
src/.../exercise/service/QuizParticipationService.java
New service orchestrating quiz participation responses by quiz state; composes MappingJacksonValue-wrapped DTOs; loads participations, submissions, results, and answers; handles batches and filtering.
REST resources — retrieval/deletion/update
src/.../exercise/web/ParticipationRetrievalResource.java, src/.../exercise/web/ParticipationDeletionResource.java, src/.../exercise/web/ParticipationUpdateResource.java
New controllers: retrieval endpoints (list/fetch participations, submissions, quiz-aware current-user fetch), deletion endpoint and programming build-plan cleanup, and update endpoints (participation update, individual due dates). Include access checks and feature toggles.
Authorization service
src/.../exercise/service/ParticipationAuthorizationService.java
New service centralizing instructor/owner access checks and course resolution from participations.
Participation resource refactor
src/.../exercise/web/ParticipationResource.java
Constructor and dependency surface reduced; shifts access checks to ParticipationAuthorizationService; drops multiple endpoints, focusing on start/resume and feedback handling.
Minor service cleanup
src/.../exercise/service/ParticipationService.java
Removes logger and related imports; no API changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant PR as ParticipationRetrievalResource
  participant ER as ExerciseRepository
  participant PS as ParticipationService
  participant QPS as QuizParticipationService

  U->>PR: GET /api/exercise/exercises/{exerciseId}/participation
  PR->>ER: findById(exerciseId)
  alt QuizExercise
    PR->>QPS: participationForQuizExercise(quiz, user)
    QPS->>QPS: Determine state (not started / started / ended)
    alt Not started
      QPS->>QPS: Filter data, attach batches, remaining attempts
      QPS-->>PR: MappingJacksonValue(participation minimal)
    else Started
      QPS->>QPS: Load with questions, filter, attach submissions/results
      QPS-->>PR: MappingJacksonValue(appropriate DTO)
    else Ended
      QPS->>QPS: Load full, enrich with submission/result
      QPS-->>PR: MappingJacksonValue(full participation)
    end
  else Non-quiz
    PR->>PS: findOneByExerciseAndCurrentUser(...)
    PS-->>PR: StudentParticipation
  end
  PR-->>U: 200 OK (MappingJacksonValue or entity)
Loading
sequenceDiagram
  autonumber
  actor Admin as Instructor/TA
  participant PDR as ParticipationDeletionResource
  participant SPR as StudentParticipationRepository
  participant PAS as ParticipationAuthorizationService
  participant PDS as ParticipationDeletionService
  participant FTS as FeatureToggleService

  Admin->>PDR: DELETE /api/exercise/participations/{id}
  PDR->>SPR: findByIdWithExerciseAndStudent(id)
  PDR->>PAS: checkAccessPermissionAtLeastInstructor(participation, user)
  alt ProgrammingParticipation
    PDR->>FTS: check(ProgrammingExercises)
  end
  PDR->>PDS: delete(participation)
  PDR-->>Admin: 200 OK
Loading
sequenceDiagram
  autonumber
  actor TA as TA/Instructor
  participant PUR as ParticipationUpdateResource
  participant ER as ExerciseRepository
  participant SPR as StudentParticipationRepository
  participant PS as ParticipationService
  participant PES as ProgrammingExerciseParticipationService

  TA->>PUR: PUT /api/exercise/exercises/{exerciseId}/participations/update-individual-due-date
  PUR->>ER: findById(exerciseId)
  PUR->>PS: updateDueDates(participations, newDueDate)
  PS-->>PUR: Updated participations
  opt Programming exercise
    PUR->>PES: updateScheduling(exercise)
  end
  PUR-->>TA: 200 OK (updated participations)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “Development: Split participation resource” clearly reflects the primary refactoring in this pull request, namely the splitting of the monolithic ParticipationResource into dedicated services and controllers. It succinctly captures the main change without extraneous detail. The phrasing is specific enough that team members scanning the history will understand the focus of the update.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/split-participation-resource

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 PMD (7.17.0)
src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationAuthorizationService.java

[ERROR] Error at ruleset.xml:58:5
56|
57|
58|
^^^^^ Unable to find referenced rule BooleanInstantiation; perhaps the rule name is misspelled?

59|
60|
[WARN] Warning at ruleset.xml:66:5
64|
65|
66|
^^^^^ Use Rule name category/java/bestpractices.xml/DefaultLabelNotLastInSwitch instead of the deprecated Rule name category/java/bestpractices.xml/DefaultLabelNotLastInSwitchStmt. PMD 8.0.0 will remove su

... [truncated 11412 characters] ...

prone.xml/InaccurateNumericLiteral instead of the deprecated Rule name category/ecmascript/errorprone.xml/InnaccurateNumericLiteral. PMD 8.0.0 will remove support for this deprecated Rule name usage.

185|
186|
[ERROR] Cannot load ruleset category/vm/bestpractices.xml: Cannot resolve rule/ruleset reference 'category/vm/bestpractices.xml'. Make sure the resource is a valid file or URL and is on the CLASSPATH. Use --debug (or a fine log level) to see the current classpath.
[WARN] Progressbar rendering conflicts with reporting to STDOUT. No progressbar will be shown. Try running with argument -r to output the report to a file instead.

src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java

[ERROR] Error at ruleset.xml:58:5
56|
57|
58|
^^^^^ Unable to find referenced rule BooleanInstantiation; perhaps the rule name is misspelled?

59|
60|
[WARN] Warning at ruleset.xml:66:5
64|
65|
66|
^^^^^ Use Rule name category/java/bestpractices.xml/DefaultLabelNotLastInSwitch instead of the deprecated Rule name category/java/bestpractices.xml/DefaultLabelNotLastInSwitchStmt. PMD 8.0.0 will remove su

... [truncated 11412 characters] ...

prone.xml/InaccurateNumericLiteral instead of the deprecated Rule name category/ecmascript/errorprone.xml/InnaccurateNumericLiteral. PMD 8.0.0 will remove support for this deprecated Rule name usage.

185|
186|
[ERROR] Cannot load ruleset category/vm/bestpractices.xml: Cannot resolve rule/ruleset reference 'category/vm/bestpractices.xml'. Make sure the resource is a valid file or URL and is on the CLASSPATH. Use --debug (or a fine log level) to see the current classpath.
[WARN] Progressbar rendering conflicts with reporting to STDOUT. No progressbar will be shown. Try running with argument -r to output the report to a file instead.

src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java

[ERROR] Error at ruleset.xml:58:5
56|
57|
58|
^^^^^ Unable to find referenced rule BooleanInstantiation; perhaps the rule name is misspelled?

59|
60|
[WARN] Warning at ruleset.xml:66:5
64|
65|
66|
^^^^^ Use Rule name category/java/bestpractices.xml/DefaultLabelNotLastInSwitch instead of the deprecated Rule name category/java/bestpractices.xml/DefaultLabelNotLastInSwitchStmt. PMD 8.0.0 will remove su

... [truncated 11412 characters] ...

prone.xml/InaccurateNumericLiteral instead of the deprecated Rule name category/ecmascript/errorprone.xml/InnaccurateNumericLiteral. PMD 8.0.0 will remove support for this deprecated Rule name usage.

185|
186|
[ERROR] Cannot load ruleset category/vm/bestpractices.xml: Cannot resolve rule/ruleset reference 'category/vm/bestpractices.xml'. Make sure the resource is a valid file or URL and is on the CLASSPATH. Use --debug (or a fine log level) to see the current classpath.
[WARN] Progressbar rendering conflicts with reporting to STDOUT. No progressbar will be shown. Try running with argument -r to output the report to a file instead.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7be8cdf and 654f085.

⛔ Files ignored due to path filters (1)
  • .github/workflows/quality.yml is excluded by !**/*.yml
📒 Files selected for processing (5)
  • src/main/java/de/tum/cit/aet/artemis/exercise/service/QuizParticipationService.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationRetrievalResource.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationUpdateResource.java (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/main/java/**/*.java

⚙️ CodeRabbit configuration file

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

Files:

  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationRetrievalResource.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/service/QuizParticipationService.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationUpdateResource.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java
🧠 Learnings (3)
📚 Learning: 2025-02-11T12:05:49.151Z
Learnt from: janthoXO
PR: ls1intum/Artemis#9406
File: src/main/java/de/tum/cit/aet/artemis/programming/web/ProgrammingExerciseParticipationResource.java:209-209
Timestamp: 2025-02-11T12:05:49.151Z
Learning: In ProgrammingExerciseParticipationResource, exam-related authorization checks and sensitive information filtering for results and feedbacks are handled by resultService.filterSensitiveInformationIfNecessary().

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationRetrievalResource.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java
📚 Learning: 2025-06-17T12:31:09.178Z
Learnt from: jfr2102
PR: ls1intum/Artemis#10983
File: src/main/java/de/tum/cit/aet/artemis/exercise/repository/StudentParticipationRepository.java:110-126
Timestamp: 2025-06-17T12:31:09.178Z
Learning: The query `findByExamIdWithEagerLatestLegalSubmissionsRatedResultAndIgnoreTestRunParticipation` in StudentParticipationRepository fetches all rated results (not just the latest) because the second correction round feature requires access to multiple assessment results per submission for proper correction round management.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationRetrievalResource.java
📚 Learning: 2025-08-26T13:23:05.331Z
Learnt from: tobias-lippert
PR: ls1intum/Artemis#11318
File: src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java:549-552
Timestamp: 2025-08-26T13:23:05.331Z
Learning: The method findGradeScoresForAllExercisesForCourseAndStudent in StudentParticipationRepository handles both individual and team exercises by combining results from separate queries for individual grades, individual quiz grades, and team grades.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java
🧬 Code graph analysis (4)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationRetrievalResource.java (3)
src/main/java/de/tum/cit/aet/artemis/core/config/Constants.java (1)
  • Constants (8-526)
src/main/java/de/tum/cit/aet/artemis/exercise/service/QuizParticipationService.java (1)
  • Profile (38-169)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (1)
  • Profile (75-439)
src/main/java/de/tum/cit/aet/artemis/exercise/service/QuizParticipationService.java (2)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationRetrievalResource.java (1)
  • Profile (51-243)
src/main/java/de/tum/cit/aet/artemis/core/config/Constants.java (1)
  • Constants (8-526)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationUpdateResource.java (1)
src/main/java/de/tum/cit/aet/artemis/core/config/Constants.java (1)
  • Constants (8-526)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java (2)
src/main/java/de/tum/cit/aet/artemis/core/config/Constants.java (1)
  • Constants (8-526)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (1)
  • Profile (75-439)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: client-tests
  • GitHub Check: server-tests
  • GitHub Check: Build and Push Docker Image / Build linux/amd64 Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build linux/arm64 Docker Image for ls1intum/artemis
  • GitHub Check: Analyse

@github-project-automation github-project-automation bot moved this from Work In Progress to Ready For Review in Artemis Development Oct 5, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

♻️ Duplicate comments (1)
src/main/java/de/tum/cit/aet/artemis/exercise/service/QuizParticipationService.java (1)

98-120: Race condition: Re-check quiz ended status before filtering.

This is the same issue flagged in the previous review. After reloading the quiz at line 98, you call filterForStudentsDuringQuiz() at line 100 before re-checking whether the quiz has ended. If the quiz transitions from "running" to "ended" between the initial check at line 82 and the reload at line 98, students lose solution data even though the quiz is already finished.

Move the isQuizEnded() check to immediately after the reload and only filter when the quiz is still running.

Apply the fix suggested in the previous review:

 quizExercise = quizExerciseRepository.findByIdWithQuestionsElseThrow(quizExercise.getId());
 quizExercise.setQuizBatches(quizBatch.stream().collect(Collectors.toSet()));
-quizExercise.filterForStudentsDuringQuiz();
+boolean quizEnded = quizExercise.isQuizEnded();
+if (!quizEnded) {
+    quizExercise.filterForStudentsDuringQuiz();
+}
 StudentParticipation participation = participationForQuizWithSubmissionAndResult(quizExercise, user.getLogin(), quizBatch.get());
 
-// TODO: Duplicate
 Object responseDTO = null;
 if (participation != null) {
     var submissions = submissionRepository.findAllWithResultsByParticipationIdOrderBySubmissionDateAsc(participation.getId());
     participation.setSubmissions(new HashSet<>(submissions));
-    if (quizExercise.isQuizEnded()) {
+    if (quizEnded) {
🧹 Nitpick comments (2)
src/main/java/de/tum/cit/aet/artemis/exercise/service/QuizParticipationService.java (2)

71-80: Address TODO: Consider replacing MappingJacksonValue with a proper DTO.

The TODO comment on line 79 indicates that MappingJacksonValue should be replaced with a proper DTO or interface. This would improve type safety and API clarity.

Would you like me to help design a proper DTO hierarchy to replace MappingJacksonValue? I can propose a solution that handles the three quiz states (ended, active, not-started) with type-safe DTOs.


103-119: Extract duplicated DTO creation logic into a shared helper method

Duplicate code in

  • src/main/java/de/tum/cit/aet/artemis/exercise/service/QuizParticipationService.java:103–119
  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizParticipationResource.java:116–123

both load submissions and choose the appropriate StudentQuizParticipation*DTO; consolidate into a common method to eliminate this duplication.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 654f085 and c344c33.

📒 Files selected for processing (1)
  • src/main/java/de/tum/cit/aet/artemis/exercise/service/QuizParticipationService.java (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/main/java/**/*.java

⚙️ CodeRabbit configuration file

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

Files:

  • src/main/java/de/tum/cit/aet/artemis/exercise/service/QuizParticipationService.java
🧬 Code graph analysis (1)
src/main/java/de/tum/cit/aet/artemis/exercise/service/QuizParticipationService.java (2)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationRetrievalResource.java (1)
  • Profile (51-243)
src/main/java/de/tum/cit/aet/artemis/core/config/Constants.java (1)
  • Constants (8-526)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: Build and Push Docker Image / Build linux/amd64 Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build linux/arm64 Docker Image for ls1intum/artemis
  • GitHub Check: Build .war artifact
  • GitHub Check: client-tests
  • GitHub Check: server-style
  • GitHub Check: server-tests
  • GitHub Check: client-style
  • GitHub Check: bean-instantiation-check
  • GitHub Check: Analyse
🔇 Additional comments (1)
src/main/java/de/tum/cit/aet/artemis/exercise/service/QuizParticipationService.java (1)

35-69: LGTM: Clean service structure with proper dependency injection.

The service follows Spring and coding guidelines with constructor injection, private final fields, and appropriate annotations.

@github-actions
Copy link

github-actions bot commented Oct 5, 2025

End-to-End (E2E) Test Results Summary

TestsPassed ✅SkippedFailedTime ⏱
End-to-End (E2E) Test Report1 ran1 passed0 skipped0 failed1s 494ms
TestResultTime ⏱
No test annotations available

@github-actions
Copy link

github-actions bot commented Oct 5, 2025

End-to-End (E2E) Test Results Summary

TestsPassed ✅SkippedFailedTime ⏱
End-to-End (E2E) Test Report1 ran1 passed0 skipped0 failed1s 652ms
TestResultTime ⏱
No test annotations available

coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 5, 2025
@github-actions
Copy link

github-actions bot commented Oct 5, 2025

End-to-End (E2E) Test Results Summary

TestsPassed ✅SkippedFailedTime ⏱
End-to-End (E2E) Test Report1 ran1 passed0 skipped0 failed2s 132ms
TestResultTime ⏱
No test annotations available

Copy link
Contributor

@SamuelRoettgermann SamuelRoettgermann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please adapt the JavaDocs as described, otherwise it's just moving code, so nothing really happening here.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (1)

424-437: Extract duplicated helper methods to a shared utility or service.

These helper methods are duplicated in ParticipationDeletionResource.java (lines 135-146). Both resources share identical implementations of checkAccessPermissionOwner (here) / checkAccessPermissionAtLeastInstructor (in DeletionResource) and findCourseFromParticipation.

Since this refactor spans multiple files and addresses code duplication introduced by the resource split, consider extracting these methods to a shared component such as:

  1. A dedicated ParticipationAuthorizationHelper service
  2. The existing ParticipationAuthorizationCheckService if one exists
  3. A package-private utility class if the methods don't require dependency injection beyond what's already available

This would centralize the authorization logic and maintain DRY principles across the newly split resources.

As per coding guidelines (no_duplication principle).

♻️ Duplicate comments (2)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java (2)

42-44: The JavaDoc has already been flagged by a previous reviewer as needing improvement. The current description "REST controller for deleting a participation and cleaning up a build plan for a participation" is more specific than "Managing participation," but could still be more concise and action-oriented.


123-133: The unguarded cast creates a ClassCastException risk.

This issue has already been flagged in a previous review. When studentParticipationRepository.findByIdElseThrow(participationId) returns a non-programming participation, the cast on line 127 will throw ClassCastException, resulting in a 500 error instead of a controlled 400 response.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3cfe450 and efaf40d.

📒 Files selected for processing (2)
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/main/java/**/*.java

⚙️ CodeRabbit configuration file

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

Files:

  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java
🧠 Learnings (1)
📚 Learning: 2025-08-26T13:23:05.331Z
Learnt from: tobias-lippert
PR: ls1intum/Artemis#11318
File: src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java:549-552
Timestamp: 2025-08-26T13:23:05.331Z
Learning: The method findGradeScoresForAllExercisesForCourseAndStudent in StudentParticipationRepository handles both individual and team exercises by combining results from separate queries for individual grades, individual quiz grades, and team grades.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java
🧬 Code graph analysis (1)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java (2)
src/main/java/de/tum/cit/aet/artemis/core/config/Constants.java (1)
  • Constants (8-526)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (1)
  • Profile (75-439)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: Build and Push Docker Image / Build linux/amd64 Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build linux/arm64 Docker Image for ls1intum/artemis
  • GitHub Check: Build .war artifact
  • GitHub Check: client-style
  • GitHub Check: server-style
  • GitHub Check: client-tests
  • GitHub Check: server-tests
  • GitHub Check: Analyse
  • GitHub Check: bean-instantiation-check
🔇 Additional comments (2)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (2)

72-74: LGTM! JavaDoc improvement addresses previous feedback.

The updated JavaDoc "REST controller for starting or resuming participations, as well as requesting feedback for one" is clearer and more specific than the previous version, directly addressing the reviewer's feedback.


95-122: LGTM! Constructor refactoring aligns with resource split.

The constructor changes properly reflect the PR's goal of splitting responsibilities:

  • Removed deletion-related dependencies (participationDeletionService, auditEventRepository)
  • Removed quiz-specific dependencies (quizExerciseRepository, quizSubmissionService, quizBatchService, submittedAnswerRepository)
  • Added feedback-related dependencies (programmingExerciseCodeReviewFeedbackService, textFeedbackApi, modelingExerciseFeedbackService, studentExamApi)
  • All new fields are properly initialized

This aligns with the introduction of ParticipationDeletionResource and QuizParticipationService mentioned in the PR objectives.

@github-actions
Copy link

github-actions bot commented Oct 6, 2025

End-to-End (E2E) Test Results Summary

TestsPassed ✅SkippedFailedTime ⏱
End-to-End (E2E) Test Report1 ran1 passed0 skipped0 failed1s 498ms
TestResultTime ⏱
No test annotations available

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

♻️ Duplicate comments (1)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java (1)

122-132: The unsafe cast issue from the previous review remains unresolved.

Line 126 still contains an unguarded cast from StudentParticipation to ProgrammingExerciseStudentParticipation. If a caller passes the ID of a non-programming participation (e.g., text/modeling), this will throw ClassCastException and return HTTP 500 instead of a controlled 400 error.

Apply the fix suggested in the previous review:

-        ProgrammingExerciseStudentParticipation participation = (ProgrammingExerciseStudentParticipation) studentParticipationRepository.findByIdElseThrow(participationId);
+        StudentParticipation rawParticipation = studentParticipationRepository.findByIdElseThrow(participationId);
+        if (!(rawParticipation instanceof ProgrammingExerciseStudentParticipation participation)) {
+            throw new BadRequestAlertException("Cleanup is only supported for programming participations", "participation", "invalidParticipationType");
+        }
         User user = userRepository.getUserWithGroupsAndAuthorities();
         participationAuthorizationHelper.checkAccessPermissionAtLeastInstructor(participation, user);
🧹 Nitpick comments (1)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java (1)

103-112: Add JavaDoc to the private helper method.

The private deleteParticipation method lacks documentation. While it's internal, documenting its purpose, parameters, and return value improves maintainability.

+    /**
+     * Deletes the participation, including build plan and repository if applicable, and logs the event in the audit database.
+     *
+     * @param participation the participation to be deleted
+     * @param user the currently logged-in user who initiated the delete operation
+     * @return the response to the client with deletion confirmation headers
+     */
     @NotNull
     private ResponseEntity<Void> deleteParticipation(StudentParticipation participation, User user) {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between efaf40d and 512d877.

📒 Files selected for processing (4)
  • src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationAuthorizationHelper.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationService.java (0 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (4 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationService.java
🧰 Additional context used
📓 Path-based instructions (1)
src/main/java/**/*.java

⚙️ CodeRabbit configuration file

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

Files:

  • src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationAuthorizationHelper.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java
🧬 Code graph analysis (2)
src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationAuthorizationHelper.java (3)
src/main/java/de/tum/cit/aet/artemis/core/config/Constants.java (1)
  • Constants (8-526)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java (1)
  • Profile (43-134)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (1)
  • Profile (75-428)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java (2)
src/main/java/de/tum/cit/aet/artemis/core/config/Constants.java (1)
  • Constants (8-526)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (1)
  • Profile (75-428)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Build and Push Docker Image / Build linux/amd64 Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build linux/arm64 Docker Image for ls1intum/artemis
  • GitHub Check: Build .war artifact
  • GitHub Check: client-style
  • GitHub Check: server-style
  • GitHub Check: client-tests
  • GitHub Check: server-tests
  • GitHub Check: bean-instantiation-check
  • GitHub Check: Analyse
  • GitHub Check: Mend Security Check
  • GitHub Check: submit-gradle
🔇 Additional comments (1)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (1)

56-56: LGTM! Authorization refactoring successfully centralizes access control.

The refactoring to use ParticipationAuthorizationHelper successfully centralizes authorization logic:

  • Constructor properly injects the helper (lines 119-125, 141)
  • Authorization checks at lines 255 and 320 now delegate to the helper instead of inline logic
  • This reduces code duplication and makes authorization patterns more consistent across resources

The changes align with the DRY principle and improve maintainability.

Based on coding guidelines (no_duplication, code_reuse principles).

Also applies to: 99-99, 119-125, 141-141, 255-255, 320-320

Copy link
Contributor

@SamuelRoettgermann SamuelRoettgermann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

look at the comment, but generally it lgtm

coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 7, 2025
Copy link
Contributor

@SamuelRoettgermann SamuelRoettgermann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@github-actions
Copy link

github-actions bot commented Oct 7, 2025

End-to-End (E2E) Test Results Summary

TestsPassed ✅SkippedFailedTime ⏱
End-to-End (E2E) Test Report1 ran1 passed0 skipped0 failed1s 593ms
TestResultTime ⏱
No test annotations available

@github-actions
Copy link

github-actions bot commented Oct 7, 2025

End-to-End (E2E) Test Results Summary

TestsPassed ✅SkippedFailedTime ⏱
End-to-End (E2E) Test Report1 ran1 passed0 skipped0 failed1s 602ms
TestResultTime ⏱
No test annotations available

@github-actions
Copy link

github-actions bot commented Oct 7, 2025

End-to-End (E2E) Test Results Summary

TestsPassed ✅SkippedFailedTime ⏱
End-to-End (E2E) Test Report1 ran1 passed0 skipped0 failed1s 752ms
TestResultTime ⏱
No test annotations available

Copy link
Contributor

@florian-glombik florian-glombik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approve the restructuring, thanks for introducing some helper methods

Copy link
Contributor

@florian-glombik florian-glombik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some checks are failing that appear to be related to the changes in this PR

Image

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 (2)
src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationAuthorizationService.java (2)

50-55: Ensure associations are fetched and null-checked.

  • studentParticipationRepository.findByIdElseThrow uses default lazy loading—add an @entitygraph or JOIN FETCH query on the repository method to load exercise and its course in one call.
  • After loading, guard against missing associations: check loaded.getExercise() and loaded.getExercise().getCourseViaExerciseGroupOrCourseMember() and throw a clear exception if null.

63-68: Use the two-arg isOwnerOfParticipation overload for consistency.

ParticipationAuthorizationService.java


- if (!authCheckService.isOwnerOfParticipation(participation)) {
+ if (!authCheckService.isOwnerOfParticipation(participation, user)) {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fa6bb66 and a515fd7.

📒 Files selected for processing (3)
  • src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationAuthorizationService.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java
🧰 Additional context used
📓 Path-based instructions (1)
src/main/java/**/*.java

⚙️ CodeRabbit configuration file

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

Files:

  • src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationAuthorizationService.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java
🧠 Learnings (1)
📚 Learning: 2025-02-11T12:05:49.151Z
Learnt from: janthoXO
PR: ls1intum/Artemis#9406
File: src/main/java/de/tum/cit/aet/artemis/programming/web/ProgrammingExerciseParticipationResource.java:209-209
Timestamp: 2025-02-11T12:05:49.151Z
Learning: In ProgrammingExerciseParticipationResource, exam-related authorization checks and sensitive information filtering for results and feedbacks are handled by resultService.filterSensitiveInformationIfNecessary().

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationAuthorizationService.java
🧬 Code graph analysis (1)
src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationAuthorizationService.java (3)
src/main/java/de/tum/cit/aet/artemis/core/config/Constants.java (1)
  • Constants (8-526)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationDeletionResource.java (1)
  • Profile (43-134)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (1)
  • Profile (75-428)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Build and Push Docker Image / Build linux/arm64 Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build linux/amd64 Docker Image for ls1intum/artemis
  • GitHub Check: Build .war artifact
  • GitHub Check: server-tests
  • GitHub Check: client-style
  • GitHub Check: server-style
  • GitHub Check: client-tests
  • GitHub Check: Analyse
  • GitHub Check: bean-instantiation-check
🔇 Additional comments (13)
src/main/java/de/tum/cit/aet/artemis/exercise/service/ParticipationAuthorizationService.java (4)

19-31: LGTM!

The service correctly uses constructor injection, and all fields are properly declared as final with appropriate Spring annotations (@service, @lazy, @Profile).


50-55: Fix potential null return when course is not loaded.

The condition on line 51 checks if participation.getExercise() is not null, but if getCourseViaExerciseGroupOrCourseMember() returns null, the method returns null at line 52 without attempting the fallback repository fetch. The method should only return early if the course is actually present.

Apply this diff to fix the logic:

 public Course findCourseFromParticipation(StudentParticipation participation) {
-    if (participation.getExercise() != null && participation.getExercise().getCourseViaExerciseGroupOrCourseMember() != null) {
-        return participation.getExercise().getCourseViaExerciseGroupOrCourseMember();
+    if (participation.getExercise() != null) {
+        Course course = participation.getExercise().getCourseViaExerciseGroupOrCourseMember();
+        if (course != null) {
+            return course;
+        }
     }
     return studentParticipationRepository.findByIdElseThrow(participation.getId()).getExercise().getCourseViaExerciseGroupOrCourseMember();
 }
⛔ Skipped due to learnings
Learnt from: tobias-lippert
PR: ls1intum/Artemis#11318
File: src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java:549-552
Timestamp: 2025-08-26T13:23:05.331Z
Learning: The method findGradeScoresForAllExercisesForCourseAndStudent in StudentParticipationRepository handles both individual and team exercises by combining results from separate queries for individual grades, individual quiz grades, and team grades.

39-42: LGTM!

The method correctly delegates course resolution and authorization checks. JavaDoc is clear and complete.


50-55: LGTM!

The defensive pattern correctly handles both fully-loaded and partially-initialized participations by falling back to a repository fetch when needed.

src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (9)

56-56: LGTM!

The import statement and field declarations properly follow the constructor injection pattern with private final fields. The addition of ParticipationAuthorizationService aligns with the PR's goal of centralizing authorization logic.

Also applies to: 93-117


119-143: LGTM!

The constructor properly implements dependency injection following the coding guidelines. All dependencies, including the newly added ParticipationAuthorizationService, are correctly injected and assigned.


255-255: LGTM!

The authorization check correctly delegates to the centralized ParticipationAuthorizationService, following the refactoring pattern of moving authorization logic out of the resource class.


320-320: LGTM!

The authorization check correctly delegates to the centralized ParticipationAuthorizationService, consistent with the refactoring pattern applied throughout the PR.


72-74: LGTM!

The JavaDoc clearly describes the controller's focused responsibilities after the refactoring, addressing the previous review feedback about improving the documentation.


119-143: Constructor properly integrates new authorization service.

The refactoring correctly adds ParticipationAuthorizationService via constructor injection, following the project's dependency injection guidelines. The centralized authorization approach improves maintainability.


56-56: LGTM!

The addition of ParticipationAuthorizationService as a dependency properly supports the centralized authorization pattern introduced by this PR.

Also applies to: 93-117


119-125: LGTM!

Constructor properly injects ParticipationAuthorizationService following the project's constructor injection pattern.

Also applies to: 141-141


255-255: LGTM!

The refactoring successfully centralizes authorization checks in ParticipationAuthorizationService, improving code reuse and maintainability.

Also applies to: 320-320

@github-actions
Copy link

github-actions bot commented Oct 7, 2025

End-to-End (E2E) Test Results Summary

TestsPassed ✅SkippedFailedTime ⏱
End-to-End (E2E) Test Report1 ran1 passed0 skipped0 failed1s 639ms
TestResultTime ⏱
No test annotations available

Copy link
Contributor

@SamuelRoettgermann SamuelRoettgermann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes lgtm

Copy link
Contributor

@florian-glombik florian-glombik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code, the build failure seems unrelated and to be caused by the pipeline

Copy link
Contributor

@ahmetsenturk ahmetsenturk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm 👍

@krusche krusche merged commit f723b4a into develop Oct 9, 2025
32 of 34 checks passed
@github-project-automation github-project-automation bot moved this from Ready For Review to Merged in Artemis Development Oct 9, 2025
@krusche krusche deleted the chore/split-participation-resource branch October 9, 2025 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

exercise Pull requests that affect the corresponding module ready to merge server Pull requests that update Java code. (Added Automatically!)

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

6 participants