Skip to content

Conversation

@krusche
Copy link
Member

@krusche krusche commented Nov 22, 2025

Checklist

General

Server

  • Important: I implemented the changes with a very good performance and prevented too many (unnecessary) and too complex database calls.
  • I strictly followed the principle of data economy for all database calls.
  • I strictly followed the server coding and design guidelines.
  • I updated multiple integration tests (Spring) related to the features (with a high test coverage).
  • I added pre-authorization annotations according to the guidelines and checked the course groups for all new REST Calls (security).
  • I documented the Java code using JavaDoc style.

Motivation and Context

We want to use DTOs and we must avoid saving on entities parsed from the client because this is unsafe and leads to issues.

Description

This PR changes the LectureResource to use DTOs, removes unused code, simplifies/improves existing code, in particular client-server interaction and database queries where possible. This should also result in performance improvements

Steps for Testing

Prerequisites:

  • 1 Instructor
  1. Create a lecture with and one lecture without lecture units
  2. Edit a lecture with and without lecture units
  3. Import a lecture with and without lecture units
  4. Delete the lectures

All should work without issues

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

Test Coverage

No changes in test coverage

No changes in the user interface, but the code should generally be more reliable and fix issues noticed in production logs.

Summary by CodeRabbit

  • New Features

    • Lecture endpoints now use DTO-based payloads/responses (simple and detailed); lecture details include units, attachments, competencies, course and channel info.
    • Channel creation now returns the created channel name.
  • API Changes

    • Several assessment/exam endpoints now accept collections of exercise IDs instead of a single exam id.
    • Calendar/lecture APIs simplified (user-student flag removed).
  • Bug Fixes

    • Safer container cleanup to avoid null-access issues.
  • Other

    • Frontend: simplified lecture/competency forms and route handling; switched some storage usage; attachment bulk query API removed; translation pipe import adjustments.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-project-automation github-project-automation bot moved this to Work In Progress in Artemis Development Nov 22, 2025
@github-actions github-actions bot added tests server Pull requests that update Java code. (Added Automatically!) client Pull requests that update TypeScript code. (Added Automatically!) assessment Pull requests that affect the corresponding module buildagent Pull requests that affect the corresponding module communication Pull requests that affect the corresponding module exam Pull requests that affect the corresponding module exercise Pull requests that affect the corresponding module lecture Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module labels Nov 22, 2025
@krusche krusche added this to the 8.5.1 milestone Nov 22, 2025
@krusche krusche marked this pull request as ready for review November 22, 2025 08:14
@krusche krusche requested review from a team as code owners November 22, 2025 08:14
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 22, 2025

Walkthrough

Replaced many exam-id-based repository methods and service calls to operate on collections of exercise IDs; added ExamRepository helpers; introduced lecture DTOs and mapping, removed transient channelName field, adjusted channel/channel-service APIs, refactored frontend lecture/atlas code and tests, and applied minor safety/formatting fixes.

Changes

Cohort / File(s) Summary
Exam helpers & service
src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java, src/main/java/de/tum/cit/aet/artemis/exam/service/ExamService.java
Added findExerciseIdsByExamId(...) and findNumberOfCorrectionRoundsByExamId(...). ExamService now resolves exerciseIds and uses them for counts, leaderboards, and correction-round logic.
Assessment & leaderboard
src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java, .../ComplaintResponseRepository.java, .../ResultRepository.java, .../TutorLeaderboardService.java
Switched multiple queries from exam.id predicates to e.id IN :exerciseIds, renamed methods to *ByExerciseIds and updated @Param names. ComplaintResponseRepository had only JPQL reformatting.
Submission & programming counts
src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java, src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
Renamed counting methods to accept Collection<Long> exerciseIds, updated JPQL to exercise.id IN :exerciseIds, added Collection imports.
Channel repo & service
src/main/java/de/tum/cit/aet/artemis/communication/repository/conversation/ChannelRepository.java, .../ChannelService.java
Added findChannelNameByLectureId(...). createLectureChannel(...) now returns the created channel name and uses userRepository.getUser() instead of getUserWithGroupsAndAuthorities.
Lecture domain, DTOs & REST
src/main/java/de/tum/cit/aet/artemis/lecture/domain/Lecture.java, .../web/LectureResource.java, .../dto/*, .../dto/LectureDetailsDTO.java
Removed transient channelName field/accessors; added LectureDTO, SimpleLectureDTO, GetLecturesDTO, LectureDetailsDTO and mapping factories. LectureResource endpoints now consume/produce DTOs and include channelName via DTOs.
Lecture repository (prod vs test)
src/main/java/de/tum/cit/aet/artemis/lecture/repository/LectureRepository.java, src/test/java/.../LectureTestRepository.java
Removed production findAllByCourseIdWithAttachments(...) (and its JOIN FETCH); added equivalent test repository method for tests.
Lecture service & unit mapping
src/main/java/de/tum/cit/aet/artemis/lecture/service/LectureService.java, .../LectureUnitService.java, .../AttachmentVideoUnitService.java
getForDetails now returns LectureDetailsDTO built via private mappers; calendar API dropped userIsStudent param. updateCompetencyLinks now resolves competencies via findCompetencyOrPrerequisiteByIdElseThrow. Added placeholder comments near competency-link saves.
Frontend: lecture & atlas changes
src/main/webapp/app/lecture/manage/services/lecture.service.ts, src/main/webapp/app/lecture/shared/transcript-viewer/*, many src/main/webapp/app/atlas/...
TS: updated setAccessRightsLecture to accept `Lecture
Frontend: tests & specs
many src/main/webapp/.../*.spec.ts, src/test/java/.../LectureIntegrationTest.java, src/test/java/.../ParticipationUtilService.java
Tests adapted to DTO-driven APIs; removed or updated tests for removed methods. ParticipationUtilService now loads a managed Submission before adding a Result. LectureIntegrationTest converted to use DTOs and updated assertions.
Misc safety & formatting
src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildAgentDockerService.java, src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintResponseRepository.java
Added guard against null/empty container names before indexing; JPQL JOIN clause indentation reformatted only.
Atlas/competency API & renames
src/main/java/de/tum/cit/aet/artemis/atlas/api/CompetencyRepositoryApi.java, src/main/java/de/tum/cit/aet/artemis/core/service/course/CourseLoadService.java, src/main/java/de/tum/cit/aet/artemis/atlas/domain/competency/CourseCompetency.java
Renamed findAllByCourseIdfindAllCompetenciesByCourseId, CompetencyRepositoryApi constructor now accepts CourseCompetencyRepository, and removed MAX_TITLE_LENGTH constant from CourseCompetency.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client
    participant ExamService
    participant ExamRepo
    participant SubmissionRepo
    participant ResultRepo
    participant TutorLeaderboardService

    Client->>ExamService: getStatsForExamAssessmentDashboard(examId)
    ExamService->>ExamRepo: findExerciseIdsByExamId(examId)
    ExamRepo-->>ExamService: exerciseIds
    ExamService->>ExamRepo: findNumberOfCorrectionRoundsByExamId(examId)
    ExamRepo-->>ExamService: correctionRounds
    note right of ExamService `#D1F2D8`: use exerciseIds for downstream queries
    ExamService->>SubmissionRepo: countByExerciseIds...(exerciseIds)
    SubmissionRepo-->>ExamService: submissionCounts
    ExamService->>ResultRepo: countNumberOfFinishedAssessmentsByExerciseIdsIgnoreTestRuns(exerciseIds)
    ResultRepo-->>ExamService: assessmentCounts
    ExamService->>TutorLeaderboardService: getExamLeaderboard(course, exerciseIds)
    TutorLeaderboardService->>ResultRepo: findTutorLeaderboardAssessmentByExerciseIds(exerciseIds)
    ResultRepo-->>TutorLeaderboardService: leaderboardAssessments
    TutorLeaderboardService-->>ExamService: leaderboardDTOs
    ExamService-->>Client: aggregated dashboard DTO
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Areas to focus:
    • ExamService: correctness of exerciseIds resolution and propagation of correction rounds.
    • Repository JPQL changes: IN-clause parameter names, semantics, and potential performance with large ID collections.
    • Lecture DTOs & LectureService: mapping correctness, Jackson polymorphism, and API compatibility.
    • Global callsites: ensure all backend and frontend callers updated to new signatures.
    • Frontend: many spec updates and service signature changes.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 43.96% 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 clearly identifies the main change: converting lecture resources to use DTOs instead of entities, which aligns with the substantial refactoring across multiple lecture-related files.
✨ 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/lectures/use-dto

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: 3

Caution

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

⚠️ Outside diff range comments (4)
src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildAgentDockerService.java (1)

168-168: Apply the same null/length guards to prevent runtime exception.

Line 168 accesses container.getNames()[0] without the null and length checks that were added to line 142. This inconsistency means the first cleanup is protected from NPE and ArrayIndexOutOfBoundsException, but subsequent scheduled cleanups are not.

Apply this diff to add the same guards:

             try {
                 danglingBuildContainers = dockerClient.listContainersCmd().withShowAll(true).exec().stream()
-                        .filter(container -> container.getNames()[0].startsWith("/" + buildContainerPrefix)).filter(container -> (now - container.getCreated()) > ageThreshold)
+                        .filter(container -> container.getNames() != null && container.getNames().length > 0 && container.getNames()[0].startsWith("/" + buildContainerPrefix))
+                        .filter(container -> (now - container.getCreated()) > ageThreshold)
                         .toList();
             }
src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java (1)

261-275: Fix Javadoc to reflect exerciseIds parameter instead of examId

The method countByExerciseIdsSubmittedSubmissionsIgnoreTestRuns(Collection<Long> exerciseIds) still has Javadoc that mentions @param examId and “exam id”. This can be misleading now that the API is exercise‑IDs‑based.

Recommend updating the Javadoc to refer to exerciseIds (and to an exam’s exercise IDs if that’s the intended use).

src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java (1)

481-489: Update Javadoc to reference exerciseIds parameter instead of examId

The refactored method signature now uses @Param("exerciseIds") Collection<Long> exerciseIds and filters by p.exercise.id IN :exerciseIds, but the Javadoc at lines 474–480 still references @param examId and describes submissions "belonging to the exam id". Update the Javadoc to reflect the new parameter name and scope so callers understand they should pass exercise IDs (or clarify if these are expected to be an exam's exercise IDs).

src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java (1)

305-329: Update Javadoc in two exam leaderboard methods to reflect exerciseIds parameter

Both findTutorLeaderboardComplaintsByExerciseIds() (lines 305–329) and findTutorLeaderboardComplaintResponsesByExerciseIds() (lines 383–407) have Javadoc that still references @param examId and describe the parameter as "id of the exam" or "id of the exercise". Update both to document the actual exerciseIds parameter (e.g., "@param exerciseIds - exercise IDs of the exam") and align method descriptions accordingly.

🧹 Nitpick comments (4)
src/main/webapp/app/lecture/manage/services/lecture.service.ts (1)

43-43: Consider using nullish coalescing for more explicit intent.

The || undefined pattern correctly converts null to undefined, but the nullish coalescing operator (??) would be more semantically precise and modern.

Apply this diff:

-                this.setAccessRightsLecture(res.body || undefined);
+                this.setAccessRightsLecture(res.body ?? undefined);

The ?? operator only converts null and undefined (not other falsy values like 0 or ""), making the intent clearer. While both work equivalently given the HttpResponse<Lecture> typing, ?? is more idiomatic for null/undefined handling.

Also applies to: 60-60, 141-141

src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java (1)

74-88: Exam leaderboard correctly switched to exercise‑ID–based repositories

getExamLeaderboard now takes Collection<Long> exerciseIds and delegates to the new ...ByExerciseIds repository methods while still marking isExam = true for aggregation. This cleanly aligns the service with the exercise‑centric data layer refactor. You might optionally clarify in the Javadoc that exerciseIds should be the IDs of the exam’s exercises.

src/main/java/de/tum/cit/aet/artemis/exam/service/ExamService.java (1)

1374-1399: Exercise‑ID–based dashboard stats refactor looks good; consider guarding empty exercise sets

The switch to exerciseIds for submissions, finished assessments, locks, and leaderboard is consistent with the rest of the refactor and avoids loading full exam graphs, which is nice from a query/perf perspective. One edge case to consider: if examRepository.findExerciseIdsByExamId(examId) can return an empty set (e.g. early in exam setup), downstream queries that use an IN :exerciseIds condition may generate invalid SQL on some DBs for empty collections, and findNumberOfCorrectionRoundsByExamId must not return null when unboxed to int.

You could defensively short‑circuit for an empty set and return zeroed stats, which also saves a few DB calls:

     public StatsForDashboardDTO getStatsForExamAssessmentDashboard(Course course, Long examId) {
         StatsForDashboardDTO stats = new StatsForDashboardDTO();
-        Set<Long> exerciseIds = examRepository.findExerciseIdsByExamId(examId);
+        Set<Long> exerciseIds = examRepository.findExerciseIdsByExamId(examId);
+        if (exerciseIds.isEmpty()) {
+            stats.setNumberOfSubmissions(new DueDateStat(0L, 0));
+            stats.setNumberOfAssessmentsOfCorrectionRounds(new DueDateStat[0]);
+            stats.setNumberOfComplaints(0L);
+            stats.setNumberOfOpenComplaints(0L);
+            stats.setNumberOfAssessmentLocks(0L);
+            stats.setTotalNumberOfAssessmentLocks(0L);
+            stats.setTutorLeaderboardEntries(List.of());
+            return stats;
+        }

Also worth double‑checking that the new repository methods explicitly handle empty collections and that findNumberOfCorrectionRoundsByExamId always returns a non‑null value (e.g. via COALESCE) to avoid unboxing surprises. As per coding guidelines.

src/main/java/de/tum/cit/aet/artemis/lecture/web/LectureResource.java (1)

151-162: Consider adding JavaDoc to DTO records.

The DTOs lack JavaDoc comments explaining their purpose and usage. While not strictly required for internal DTOs, documentation would improve maintainability, especially for the nested CourseDTO and its from() factory method.

Example JavaDoc:

+    /**
+     * Data transfer object for Lecture entity.
+     * Used to transfer lecture data between client and server without exposing entity internals.
+     *
+     * @param id          the lecture ID
+     * @param title       the lecture title
+     * @param description the lecture description
+     * @param startDate   the lecture start date
+     * @param endDate     the lecture end date
+     * @param channelName the associated channel name
+     * @param course      the course this lecture belongs to
+     */
     @JsonIgnoreProperties(ignoreUnknown = true)
     @JsonInclude(JsonInclude.Include.NON_EMPTY)
     public record LectureDTO(Long id, String title, String description, ZonedDateTime startDate, ZonedDateTime endDate, String channelName, CourseDTO course) {
📜 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 358ad69 and 0102d9b.

📒 Files selected for processing (17)
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintResponseRepository.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java (5 hunks)
  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildAgentDockerService.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/communication/repository/conversation/ChannelRepository.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/communication/service/conversation/ChannelService.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exam/service/ExamService.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java (5 hunks)
  • src/main/java/de/tum/cit/aet/artemis/lecture/domain/Lecture.java (0 hunks)
  • src/main/java/de/tum/cit/aet/artemis/lecture/web/LectureResource.java (10 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java (2 hunks)
  • src/main/webapp/app/lecture/manage/services/lecture.service.ts (4 hunks)
  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/exercise/participation/util/ParticipationUtilService.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java (5 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/de/tum/cit/aet/artemis/lecture/domain/Lecture.java
🧰 Additional context used
📓 Path-based instructions (3)
src/main/webapp/**/*.ts

⚙️ CodeRabbit configuration file

angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

Files:

  • src/main/webapp/app/lecture/manage/services/lecture.service.ts
  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
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/assessment/service/TutorLeaderboardService.java
  • src/main/java/de/tum/cit/aet/artemis/communication/repository/conversation/ChannelRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintResponseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exam/service/ExamService.java
  • src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildAgentDockerService.java
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/lecture/web/LectureResource.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
  • src/main/java/de/tum/cit/aet/artemis/communication/service/conversation/ChannelService.java
src/test/java/**/*.java

⚙️ CodeRabbit configuration file

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

Files:

  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java
  • src/test/java/de/tum/cit/aet/artemis/exercise/participation/util/ParticipationUtilService.java
🧠 Learnings (48)
📓 Common learnings
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11419
File: src/main/java/de/tum/cit/aet/artemis/exam/domain/ExamUser.java:16-17
Timestamp: 2025-09-25T20:28:36.905Z
Learning: In the Artemis codebase, ExamUser entity uses ExamSeatDTO as a transient field for performance reasons. SamuelRoettgermann tested domain value objects but they caused 60x slower performance. This architectural exception is approved by maintainers due to significant performance benefits and Artemis naming convention requirements.
Learnt from: Elfari1028
Repo: ls1intum/Artemis PR: 11351
File: src/main/java/de/tum/cit/aet/artemis/versioning/dto/QuizExerciseSnapshotDTO.java:52-53
Timestamp: 2025-09-25T11:25:54.261Z
Learning: In the Artemis versioning system, quiz questions processed by QuizExerciseSnapshotDTO should always have valid IDs (non-null getId()) since versioning works with persisted entities, making null filtering unnecessary according to Elfari1028.
Learnt from: jfr2102
Repo: ls1intum/Artemis PR: 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.
Learnt from: eceeeren
Repo: ls1intum/Artemis PR: 10533
File: src/main/java/de/tum/cit/aet/artemis/core/web/CourseResource.java:839-857
Timestamp: 2025-04-04T09:39:24.832Z
Learning: In the Artemis application, filtering of unreleased exercises is handled at the database level through SQL queries in the repository methods rather than in the application code. The method findByCourseIdWithFutureDueDatesAndCategories in ExerciseRepository applies this filtering, making additional application-level filtering unnecessary.
Learnt from: Elfari1028
Repo: ls1intum/Artemis PR: 11491
File: src/main/java/de/tum/cit/aet/artemis/exercise/web/ExerciseResource.java:376-378
Timestamp: 2025-10-22T21:31:54.240Z
Learning: In Artemis, ExerciseVersionService.createExerciseVersion(...) (src/main/java/de/tum/cit/aet/artemis/exercise/service/ExerciseVersionService.java) eagerly re-fetches the target exercise (via type-specific findForVersioningById) before building the ExerciseSnapshotDTO. Controllers (e.g., ExerciseResource.toggleSecondCorrectionEnabled) do not need to reload the exercise before invoking createExerciseVersion.
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 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.
📚 Learning: 2025-10-10T17:12:35.471Z
Learnt from: marlonnienaber
Repo: ls1intum/Artemis PR: 11436
File: src/main/webapp/app/lecture/manage/lecture-series-create/lecture-series-create.component.ts:356-361
Timestamp: 2025-10-10T17:12:35.471Z
Learning: In the LectureSeriesCreateComponent (src/main/webapp/app/lecture/manage/lecture-series-create/lecture-series-create.component.ts), the rawExistingLectures input contains only persisted Lecture entities from the database, so their id field is guaranteed to be non-null despite the Lecture type having id?: number. The cast to ExistingLecture at line 359 is therefore safe.

Applied to files:

  • src/main/webapp/app/lecture/manage/services/lecture.service.ts
  • src/main/java/de/tum/cit/aet/artemis/lecture/web/LectureResource.java
📚 Learning: 2025-10-10T13:22:16.754Z
Learnt from: marlonnienaber
Repo: ls1intum/Artemis PR: 11436
File: src/main/java/de/tum/cit/aet/artemis/iris/web/IrisLectureChatSessionResource.java:79-81
Timestamp: 2025-10-10T13:22:16.754Z
Learning: The `visibleDate` property of the `Lecture` entity in the Artemis codebase is deprecated and no longer supported. Visibility checks based on `lecture.isVisibleToStudents()` or `lecture.getVisibleDate()` should not be flagged as missing security controls, as this functionality has been intentionally removed across the codebase (tracked in issue #11479).

Applied to files:

  • src/main/webapp/app/lecture/manage/services/lecture.service.ts
  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/lecture/web/LectureResource.java
📚 Learning: 2025-10-22T21:31:54.240Z
Learnt from: Elfari1028
Repo: ls1intum/Artemis PR: 11491
File: src/main/java/de/tum/cit/aet/artemis/exercise/web/ExerciseResource.java:376-378
Timestamp: 2025-10-22T21:31:54.240Z
Learning: In Artemis, ExerciseVersionService.createExerciseVersion(...) (src/main/java/de/tum/cit/aet/artemis/exercise/service/ExerciseVersionService.java) eagerly re-fetches the target exercise (via type-specific findForVersioningById) before building the ExerciseSnapshotDTO. Controllers (e.g., ExerciseResource.toggleSecondCorrectionEnabled) do not need to reload the exercise before invoking createExerciseVersion.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java
  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exam/service/ExamService.java
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
📚 Learning: 2025-09-15T11:18:26.439Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11378
File: src/main/java/de/tum/cit/aet/artemis/exam/service/ExamRoomDistributionService.java:13-16
Timestamp: 2025-09-15T11:18:26.439Z
Learning: In ExamRoomDistributionService.distributeRegisteredStudents method in src/main/java/de/tum/cit/aet/artemis/exam/service/ExamRoomDistributionService.java, the team has decided not to use Transactional annotation despite multiple repository operations, based on human reviewer consultation.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java
  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java
  • src/test/java/de/tum/cit/aet/artemis/exercise/participation/util/ParticipationUtilService.java
  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exam/service/ExamService.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
📚 Learning: 2024-10-08T15:35:42.972Z
Learnt from: Strohgelaender
Repo: ls1intum/Artemis PR: 8574
File: src/main/java/de/tum/in/www1/artemis/service/tutorialgroups/TutorialGroupService.java:0-0
Timestamp: 2024-10-08T15:35:42.972Z
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`.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java
  • src/test/java/de/tum/cit/aet/artemis/exercise/participation/util/ParticipationUtilService.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
📚 Learning: 2025-09-25T11:25:54.261Z
Learnt from: Elfari1028
Repo: ls1intum/Artemis PR: 11351
File: src/main/java/de/tum/cit/aet/artemis/versioning/dto/QuizExerciseSnapshotDTO.java:52-53
Timestamp: 2025-09-25T11:25:54.261Z
Learning: In the Artemis versioning system, quiz questions processed by QuizExerciseSnapshotDTO should always have valid IDs (non-null getId()) since versioning works with persisted entities, making null filtering unnecessary according to Elfari1028.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java
  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exam/service/ExamService.java
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
📚 Learning: 2025-08-30T12:34:27.995Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11345
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizTrainingLeaderboardService.java:235-248
Timestamp: 2025-08-30T12:34:27.995Z
Learning: In QuizTrainingLeaderboardService.initializeLeaderboard(), existing leaderboard entries are intentionally not updated during rebuilds. The method only initializes new entries for users who don't have leaderboard records yet, preserving historical data for existing users.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java
📚 Learning: 2025-09-25T20:43:41.712Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11419
File: src/main/java/de/tum/cit/aet/artemis/exam/web/ExamRoomDistributionResource.java:62-78
Timestamp: 2025-09-25T20:43:41.712Z
Learning: In the ExamRoomDistributionService.distributeRegisteredStudents method in src/main/java/de/tum/cit/aet/artemis/exam/service/ExamRoomDistributionService.java, ExamRoom entities are shared resources that are dynamically assigned to exams through the ExamRoomExamAssignment join table. Rooms don't "belong" to exams until the distribution process creates these assignments. The method first clears existing assignments for the exam, then creates new ones for the provided room IDs.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java
  • src/main/java/de/tum/cit/aet/artemis/exam/service/ExamService.java
📚 Learning: 2024-06-10T19:44:09.116Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 8703
File: src/main/java/de/tum/in/www1/artemis/web/rest/QuizParticipationResource.java:39-39
Timestamp: 2024-06-10T19:44:09.116Z
Learning: The `Profile(PROFILE_CORE)` annotation in `QuizParticipationResource.java` is used to ensure that all nodes, not just those with the scheduling profile, can handle quiz participations.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java
📚 Learning: 2025-09-25T20:28:36.905Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11419
File: src/main/java/de/tum/cit/aet/artemis/exam/domain/ExamUser.java:16-17
Timestamp: 2025-09-25T20:28:36.905Z
Learning: In the Artemis codebase, ExamUser entity uses ExamSeatDTO as a transient field for performance reasons. SamuelRoettgermann tested domain value objects but they caused 60x slower performance. This architectural exception is approved by maintainers due to significant performance benefits and Artemis naming convention requirements.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java
  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/lecture/web/LectureResource.java
📚 Learning: 2025-09-05T15:13:32.171Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11345
File: src/main/java/de/tum/cit/aet/artemis/quiz/repository/QuizTrainingLeaderboardRepository.java:22-23
Timestamp: 2025-09-05T15:13:32.171Z
Learning: The derived query method name `findByLeagueAndCourseIdOrderByScoreDescUserAscId` in QuizTrainingLeaderboardRepository correctly references the `user` entity field directly in the OrderBy clause, not requiring `userId`. Spring Data JPA supports sorting by entity references directly in derived query method names.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java
  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
📚 Learning: 2025-09-05T15:11:31.588Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11345
File: src/main/java/de/tum/cit/aet/artemis/quiz/domain/QuizTrainingLeaderboard.java:10-11
Timestamp: 2025-09-05T15:11:31.588Z
Learning: In the QuizTrainingLeaderboard domain class, validation is handled by the service class logic rather than using bean validation annotations at the entity level.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java
📚 Learning: 2025-06-17T12:31:09.178Z
Learnt from: jfr2102
Repo: ls1intum/Artemis PR: 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/assessment/service/TutorLeaderboardService.java
  • src/test/java/de/tum/cit/aet/artemis/exercise/participation/util/ParticipationUtilService.java
  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exam/service/ExamService.java
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
📚 Learning: 2025-09-25T20:48:13.391Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11419
File: src/test/java/de/tum/cit/aet/artemis/exam/test_repository/ExamRoomTestRepository.java:18-34
Timestamp: 2025-09-25T20:48:13.391Z
Learning: In ExamRoomTestRepository JPQL queries in src/test/java/de/tum/cit/aet/artemis/exam/test_repository/ExamRoomTestRepository.java, CTE (Common Table Expression) syntax with bare attribute names like `roomNumber`, `name`, `createdDate` inside the WITH clause works correctly without requiring entity aliases, confirmed working by SamuelRoettgermann in their Artemis/Hibernate setup.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java
  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintResponseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
📚 Learning: 2025-09-18T22:22:54.269Z
Learnt from: marlonnienaber
Repo: ls1intum/Artemis PR: 11350
File: src/main/java/de/tum/cit/aet/artemis/tutorialgroup/service/TutorialGroupService.java:0-0
Timestamp: 2025-09-18T22:22:54.269Z
Learning: In the tutorial group domain, TutorialGroup entities are guaranteed to have a non-null teachingAssistant due to database constraints. This means teachingAssistantLogin() will always return a non-null value, and null checks are not necessary when using this field in repository calls or other operations.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java
📚 Learning: 2025-09-21T11:51:17.945Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11345
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizTrainingLeaderboardService.java:128-141
Timestamp: 2025-09-21T11:51:17.945Z
Learning: In QuizTrainingLeaderboardService, prefilling leaderboardName with user.getFirstName() during leaderboard entry creation is a deliberate design choice. Privacy protection is handled at the display level rather than initialization level.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/service/TutorLeaderboardService.java
📚 Learning: 2025-08-26T13:23:05.331Z
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 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/assessment/service/TutorLeaderboardService.java
  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exam/service/ExamService.java
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
📚 Learning: 2025-09-20T16:43:32.823Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11382
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizQuestionProgressService.java:130-137
Timestamp: 2025-09-20T16:43:32.823Z
Learning: The findAllDueQuestions method exists in QuizQuestionRepository and accepts Set<Long> ids, Long courseId, and Pageable parameters, returning Page<QuizQuestion>. The method has a Query annotation that filters by courseId, isOpenForPractice = TRUE, and excludes questions with IDs in the provided set using NOT IN.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/communication/repository/conversation/ChannelRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
📚 Learning: 2025-08-11T13:22:05.140Z
Learnt from: Wallenstein61
Repo: ls1intum/Artemis PR: 10989
File: src/test/java/de/tum/cit/aet/artemis/programming/service/sharing/ExerciseSharingResourceImportTest.java:128-131
Timestamp: 2025-08-11T13:22:05.140Z
Learning: In the ExerciseSharingResourceImportTest class in Artemis, mockServer.verify() is not needed in the tearDown method as the test design doesn't require strict verification of all mocked HTTP expectations. The mockServer field is managed differently in this test class.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java
📚 Learning: 2024-10-15T11:33:17.915Z
Learnt from: alexjoham
Repo: ls1intum/Artemis PR: 9455
File: src/test/java/de/tum/cit/aet/artemis/iris/IrisTextExerciseChatMessageIntegrationTest.java:401-401
Timestamp: 2024-10-15T11:33:17.915Z
Learning: In the Artemis project, when new fields are added to classes like `PyrisChatStatusUpdateDTO`, corresponding tests may be implemented in separate integration test classes such as `IrisChatTokenTrackingIntegrationTest`.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java
📚 Learning: 2025-10-10T13:22:13.454Z
Learnt from: marlonnienaber
Repo: ls1intum/Artemis PR: 11436
File: src/main/java/de/tum/cit/aet/artemis/iris/web/IrisLectureChatSessionResource.java:138-140
Timestamp: 2025-10-10T13:22:13.454Z
Learning: In the IrisLectureChatSessionResource.java file, the checkWhetherLectureIsVisibleToStudentsElseThrow visibility checks are intentionally commented out as part of deprecating the Lecture.visibleDate property. This deprecation is temporary to monitor user feedback before full removal (tracked in issue #11479).

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/lecture/web/LectureResource.java
📚 Learning: 2024-11-26T20:43:17.588Z
Learnt from: magaupp
Repo: ls1intum/Artemis PR: 9751
File: src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseFactory.java:143-148
Timestamp: 2024-11-26T20:43:17.588Z
Learning: In `src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseFactory.java`, the test package name assigned in `populateUnreleasedProgrammingExercise` does not need to adhere to naming conventions.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
📚 Learning: 2024-06-10T19:44:09.116Z
Learnt from: julian-christl
Repo: ls1intum/Artemis PR: 8052
File: src/test/java/de/tum/in/www1/artemis/lecture/CompetencyIntegrationTest.java:310-310
Timestamp: 2024-06-10T19:44:09.116Z
Learning: Modifications to parameters in `competencyProgressUtilService.createCompetencyProgress` for debugging purposes are considered irrelevant to the test outcomes but helpful for clarity during debugging.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java
  • src/test/java/de/tum/cit/aet/artemis/exercise/participation/util/ParticipationUtilService.java
📚 Learning: 2025-08-10T18:33:22.476Z
Learnt from: Wallenstein61
Repo: ls1intum/Artemis PR: 10989
File: src/test/java/de/tum/cit/aet/artemis/programming/AbstractProgrammingIntegrationLocalCILocalVCTest.java:3-9
Timestamp: 2025-08-10T18:33:22.476Z
Learning: In the Artemis test framework, `MockitoBean` from `org.springframework.test.context.bean.override.mockito` is the standard annotation used for mocking beans in test classes, not `MockBean`. This is used consistently across test base classes like `AbstractProgrammingIntegrationLocalCILocalVCTest`, `AbstractSpringIntegrationIndependentTest`, and `AbstractSpringIntegrationLocalVCSamlTest`. The project also uses `MockitoSpyBean` from the same package.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java
📚 Learning: 2024-06-10T19:44:09.116Z
Learnt from: valentin-boehm
Repo: ls1intum/Artemis PR: 7384
File: src/test/java/de/tum/in/www1/artemis/exam/StudentExamIntegrationTest.java:988-993
Timestamp: 2024-06-10T19:44:09.116Z
Learning: The `testSubmitStudentExam_differentUser` method does not require additional checks to verify the state of `studentExam1` after receiving a `HttpStatus.FORBIDDEN` because the control flow in the `StudentExamResource` is straightforward and ensures no state change occurs.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java
📚 Learning: 2024-10-08T15:35:42.972Z
Learnt from: julian-christl
Repo: ls1intum/Artemis PR: 7829
File: src/main/java/de/tum/in/www1/artemis/web/rest/ComplaintResponseResource.java:0-0
Timestamp: 2024-10-08T15:35:42.972Z
Learning: The user has fixed the issue regarding the redundant wildcard import in `ComplaintResponseResource.java` by removing it in commit 7e392e0.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintResponseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
📚 Learning: 2025-05-24T16:06:41.454Z
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 10812
File: src/main/java/de/tum/cit/aet/artemis/atlas/repository/CompetencyRepository.java:70-88
Timestamp: 2025-05-24T16:06:41.454Z
Learning: In CompetencyRepository JPQL queries that join from LearningPath to course competencies, DISTINCT is not necessary because a learning path belongs to exactly one course, preventing duplicate competencies in the result set.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintResponseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
📚 Learning: 2025-08-08T08:50:28.791Z
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 11248
File: src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseParticipationService.java:401-402
Timestamp: 2025-08-08T08:50:28.791Z
Learning: In src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseParticipationService.java, method findStudentParticipationWithLatestSubmissionResultAndFeedbacksElseThrow(long), using List.of() for latestSubmission.setResults(...) is acceptable because the results list is not mutated afterward and is only returned to the client; no follow-up code appends to it.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/exercise/participation/util/ParticipationUtilService.java
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
📚 Learning: 2025-02-11T12:05:49.151Z
Learnt from: janthoXO
Repo: ls1intum/Artemis PR: 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/test/java/de/tum/cit/aet/artemis/exercise/participation/util/ParticipationUtilService.java
  • src/main/java/de/tum/cit/aet/artemis/exam/service/ExamService.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
📚 Learning: 2025-07-11T15:43:56.099Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11055
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizQuestionProgressService.java:47-61
Timestamp: 2025-07-11T15:43:56.099Z
Learning: In QuizQuestionProgressService.retrieveProgressFromResultAndSubmission method, input validation is not necessary because getSubmittedAnswers() always returns a non-null set and the method receives non-null objects by contract when called from QuizSubmissionService.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/exercise/participation/util/ParticipationUtilService.java
📚 Learning: 2024-10-20T18:37:45.365Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 9303
File: src/main/java/de/tum/in/www1/artemis/service/exam/StudentExamService.java:296-300
Timestamp: 2024-10-20T18:37:45.365Z
Learning: When reviewing code changes in `StudentExamService.saveSubmission`, if the PR aims to improve readability without changing logic, avoid suggesting changes that alter logic, such as adding exceptions in the default case of switch statements.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/exercise/participation/util/ParticipationUtilService.java
📚 Learning: 2025-09-13T15:47:08.214Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11378
File: src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRoomExamAssignmentRepository.java:21-23
Timestamp: 2025-09-13T15:47:08.214Z
Learning: Spring Data JPA can resolve nested properties in derived query method names. For example, if an entity has a field `Exam exam`, a method named `deleteAllByExamId(long examId)` will correctly resolve to `exam.id` even without a direct `examId` field. Spring Data first looks for direct field matches, then tries nested property paths when direct matches aren't found. This is standard Spring Data JPA behavior and should not be flagged as incorrect.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
📚 Learning: 2025-09-13T15:47:08.214Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11378
File: src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRoomExamAssignmentRepository.java:21-23
Timestamp: 2025-09-13T15:47:08.214Z
Learning: Spring Data JPA can resolve nested properties in derived query method names. For example, if an entity has a field `Exam exam`, a method named `deleteAllByExamId(long examId)` will correctly resolve to `exam.id` even without a direct `examId` field. Spring Data first looks for direct field matches, then tries nested property paths when direct matches aren't found.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
📚 Learning: 2025-04-04T09:39:24.832Z
Learnt from: eceeeren
Repo: ls1intum/Artemis PR: 10533
File: src/main/java/de/tum/cit/aet/artemis/core/web/CourseResource.java:839-857
Timestamp: 2025-04-04T09:39:24.832Z
Learning: In the Artemis application, filtering of unreleased exercises is handled at the database level through SQL queries in the repository methods rather than in the application code. The method findByCourseIdWithFutureDueDatesAndCategories in ExerciseRepository applies this filtering, making additional application-level filtering unnecessary.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintRepository.java
  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
📚 Learning: 2025-09-20T16:43:32.823Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11382
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizQuestionProgressService.java:130-137
Timestamp: 2025-09-20T16:43:32.823Z
Learning: The findAllDueQuestions method exists in QuizQuestionRepository and accepts Set<Long> ids, Long courseId, and Pageable parameters, returning Page<QuizQuestion>. This method is properly implemented and available for use in QuizQuestionProgressService.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java
📚 Learning: 2025-08-21T17:30:20.530Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/drag-and-drop-question/drag-and-drop-question.component.spec.ts:34-34
Timestamp: 2025-08-21T17:30:20.530Z
Learning: FitTextDirective in src/main/webapp/app/quiz/shared/fit-text/fit-text.directive.ts is a standalone directive marked with standalone: true, so it should be imported in TestBed imports array, not declarations array.

Applied to files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
📚 Learning: 2025-04-22T10:19:41.546Z
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 10714
File: src/main/webapp/app/quiz/manage/create-buttons/quiz-exercise-create-buttons.component.ts:11-15
Timestamp: 2025-04-22T10:19:41.546Z
Learning: In Angular 19, standalone components are the default, so components with an `imports` array don't need to explicitly declare `standalone: true` property in the component decorator.

Applied to files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
📚 Learning: 2024-10-28T11:34:03.750Z
Learnt from: isabellagessl
Repo: ls1intum/Artemis PR: 9615
File: src/main/webapp/app/overview/exercise-details/course-exercise-details.module.ts:75-75
Timestamp: 2024-10-28T11:34:03.750Z
Learning: In Angular, when a non-standalone component declared in an NgModule needs to use a standalone component, the standalone component should be imported into the NgModule's `imports` array. This allows the non-standalone component to utilize the standalone component in its template.

Applied to files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
📚 Learning: 2024-10-21T22:49:01.865Z
Learnt from: BBesrour
Repo: ls1intum/Artemis PR: 9529
File: src/main/java/de/tum/cit/aet/artemis/buildagent/service/SharedQueueProcessingService.java:29-29
Timestamp: 2024-10-21T22:49:01.865Z
Learning: In `SharedQueueProcessingService.java`, `buildAgentDisplayName` can be null, so using `StringUtils.isBlank(buildAgentDisplayName)` is necessary to handle null values.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildAgentDockerService.java
📚 Learning: 2024-10-28T19:47:50.979Z
Learnt from: magaupp
Repo: ls1intum/Artemis PR: 9609
File: src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildJobExecutionService.java:421-421
Timestamp: 2024-10-28T19:47:50.979Z
Learning: In `src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildJobExecutionService.java`, the developer does not expect the list of file extensions in `isValidTestResultFile` to grow and prefers to keep the current implementation without refactoring.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildAgentDockerService.java
📚 Learning: 2025-01-09T06:36:04.666Z
Learnt from: chrisknedl
Repo: ls1intum/Artemis PR: 10118
File: src/main/resources/templates/aeolus/java/plain_maven_blackbox.sh:33-41
Timestamp: 2025-01-09T06:36:04.666Z
Learning: In the Artemis build agent's Aeolus templates for Java/Maven blackbox tests, the existence of tool directories and config files is manually verified before script execution, making runtime existence checks redundant.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildAgentDockerService.java
📚 Learning: 2025-08-26T14:21:27.867Z
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 11318
File: src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java:548-549
Timestamp: 2025-08-26T14:21:27.867Z
Learning: The countPresentationScoresForParticipant method in StudentParticipationRepository handles both individual student IDs and team IDs correctly in a single query. When a team ID is passed as the participant ID, the query uses JOIN logic to count presentation scores for team members, so no special branching logic is needed in the calling code.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
📚 Learning: 2025-08-26T14:21:27.867Z
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 11318
File: src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java:548-549
Timestamp: 2025-08-26T14:21:27.867Z
Learning: The countPresentationScoresForParticipant method in StudentParticipationRepository uses a LEFT JOIN with team.students and an OR condition (p.student.id = :participantId OR ts.id = :participantId) to correctly handle both individual and team participations in a single query. The method properly counts presentation scores for both participation types without requiring additional branching logic in the calling code.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseRepository.java
  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
📚 Learning: 2024-06-10T19:44:09.116Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8597
File: src/main/webapp/app/exercises/programming/manage/repositories-checkout-directories-dto.ts:8-8
Timestamp: 2024-06-10T19:44:09.116Z
Learning: DTOs are typically defined in the `src/main/webapp/app/entities` folder on the client side in the Artemis project.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/lecture/web/LectureResource.java
📚 Learning: 2024-10-08T15:35:42.972Z
Learnt from: JohannesStoehr
Repo: ls1intum/Artemis PR: 8679
File: src/main/java/de/tum/in/www1/artemis/web/rest/tutorialgroups/TutorialGroupSessionResource.java:37-37
Timestamp: 2024-10-08T15:35:42.972Z
Learning: The DTOs `CompetencyProgressForLearningPathDTO`, `ProgrammingExerciseResetOptionsDTO`, and `CourseWithIdDTO` do not contain nullable values or `Optional` types, making the `JsonInclude` annotation unnecessary for them.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/lecture/web/LectureResource.java
📚 Learning: 2025-10-07T21:56:51.081Z
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 11459
File: src/main/java/de/tum/cit/aet/artemis/assessment/service/ComplaintService.java:177-183
Timestamp: 2025-10-07T21:56:51.081Z
Learning: In the Artemis project using Hibernate 6.2+, the in_clause_parameter_padding configuration is set to true, which means empty sets passed to repository methods with IN clauses (e.g., `IN :exerciseIds`) do not cause Hibernate exceptions. Therefore, empty-set guards are not required in service methods that delegate to such repository queries.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java
📚 Learning: 2025-09-01T21:08:54.006Z
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 11318
File: src/main/java/de/tum/cit/aet/artemis/exam/service/ExamService.java:764-799
Timestamp: 2025-09-01T21:08:54.006Z
Learning: In two-round exam correction systems, first correction points are only calculated when both manual results exist (submission.getManualResults().size() > 1), not when only the first round is complete. This prevents premature point calculations before the second correction round is finished.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java
🧬 Code graph analysis (2)
src/main/webapp/app/lecture/manage/services/lecture.service.ts (1)
src/main/webapp/app/lecture/shared/entities/lecture.model.ts (1)
  • Lecture (9-26)
src/main/java/de/tum/cit/aet/artemis/lecture/web/LectureResource.java (2)
src/test/playwright/support/requests/CourseManagementAPIRequests.ts (1)
  • createLecture (178-189)
src/main/webapp/app/lecture/manage/lecture-update/lecture-update.component.ts (1)
  • save (252-261)
⏰ 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/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: Codacy Static Code Analysis
  • GitHub Check: client-style
  • GitHub Check: server-style
  • GitHub Check: client-tests-selected
  • GitHub Check: client-tests
  • GitHub Check: server-tests
  • GitHub Check: Analyse
  • GitHub Check: bean-instantiation-check
🔇 Additional comments (18)
src/main/java/de/tum/cit/aet/artemis/buildagent/service/BuildAgentDockerService.java (1)

141-143: Good defensive guard against NPE and array access errors.

The added null and length checks prevent potential NullPointerException or ArrayIndexOutOfBoundsException when container.getNames() returns null or an empty array.

src/main/webapp/app/lecture/manage/services/lecture.service.ts (1)

205-205: LGTM: Type signature refined from null to undefined.

The change from Lecture | null to Lecture | undefined aligns with TypeScript best practices where undefined is the preferred absence indicator. The implementation correctly handles the undefined case with a truthy check.

src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts (2)

114-133: Excellent XSS prevention implementation.

The highlightText method properly prevents XSS attacks by:

  1. Escaping the segment text first (line 116)
  2. Escaping the search query (line 124)
  3. Only injecting safe <mark> tags after escaping user content

This ensures that any malicious content in either the transcript or search query is neutralized before being rendered via [innerHTML].


6-6: Translation refactoring verified as complete and correct.

The removal of TranslateDirective from the component imports is correct. The template exclusively uses pipe-based translation (| translate), confirming the refactoring is fully implemented and consistent across the component.

src/main/java/de/tum/cit/aet/artemis/assessment/repository/ComplaintResponseRepository.java (1)

41-46: JOIN reformatting only – semantics unchanged

The updated indentation for the JOIN clauses keeps the JPQL identical in behavior; no action needed.

src/main/java/de/tum/cit/aet/artemis/assessment/repository/ResultRepository.java (2)

344-363: Exam assessment counting correctly shifted to exercise IDs

The new countNumberOfFinishedAssessmentsByExerciseIdsIgnoreTestRuns and the updated default method now operate on Collection<Long> exerciseIds, mirroring the existing single‑exercise query conditions (ignoring test runs, only submitted, rated, completed, with assessor). This is a clean generalization; just ensure all exam‑related callers have been updated to pass the exam’s exercise IDs rather than the exam ID.

Also applies to: 522-531


637-656: New tutor leaderboard query by exercise IDs looks consistent

findTutorLeaderboardAssessmentByExerciseIds(Collection<Long> exerciseIds) reuses the existing aggregation (counts, points, average score/rating) and only switches the filter to e.id IN :exerciseIds, which aligns with the new exercise‑centric API. Please double‑check that all exam leaderboard paths now use this method with the correct exercise ID set.

src/main/java/de/tum/cit/aet/artemis/exercise/repository/SubmissionRepository.java (1)

147-160: Locked submission counters correctly generalized to exercise ID collections

Both countLockedSubmissionsByUserIdAndExerciseIds and countLockedSubmissionsByExerciseIds now filter via s.participation.exercise.id IN :exerciseIds while counting COUNT(DISTINCT s). This preserves the previous semantics and cleanly supports multi‑exercise exam scenarios; no further changes needed here.

Also applies to: 165-177

src/test/java/de/tum/cit/aet/artemis/exercise/participation/util/ParticipationUtilService.java (1)

421-429: Using the managed Submission instance is a solid improvement

Re‑loading the Submission via findByIdWithResultsElseThrow and attaching the new Result to that managed instance before saving avoids persisting changes on potentially detached test entities. This aligns well with the DTO/managed‑entity separation you’re pushing elsewhere in the PR.

src/main/java/de/tum/cit/aet/artemis/exam/repository/ExamRepository.java (1)

530-537: New exam helpers for exercise IDs and correction rounds look correct

Both JPQL queries are straightforward and efficient:

  • findExerciseIdsByExamId traverses exam → exerciseGroups → exercises and returns the distinct exercise IDs.
  • findNumberOfCorrectionRoundsByExamId exposes numberOfCorrectionRoundsInExam directly.

Just make sure all callers only use these once the exam’s existence has been validated, as the second method will fail with a missing exam.

Also applies to: 539-544

src/main/java/de/tum/cit/aet/artemis/communication/repository/conversation/ChannelRepository.java (1)

38-43: LGTM!

The query correctly retrieves the channel name for a lecture. The nullable return type is appropriate since not all lectures may have associated channels.

src/test/java/de/tum/cit/aet/artemis/lecture/LectureIntegrationTest.java (2)

487-511: LGTM!

The import test correctly uses DTOs for both request and response, with appropriate accessor method usage throughout.


235-256: Response type inconsistency with endpoint.

The test expects LectureDTO.class as the response (line 246), but updateLecture in LectureResource (line 224) returns ResponseEntity<Lecture>, not ResponseEntity<LectureDTO>. This creates an inconsistency between the test expectation and the actual endpoint behavior.

The endpoint should be made consistent with other endpoints (create, get, import) which all return DTOs. See the related comment in LectureResource.java for the recommended fix.

⛔ Skipped due to learnings
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11111
File: src/test/java/de/tum/cit/aet/artemis/exam/ExamRoomIntegrationTest.java:0-0
Timestamp: 2025-08-30T20:20:17.236Z
Learning: In ExamRoomIntegrationTest.validateAdminOverview(), the first assertion should use subset containment (contains) rather than exact equality because the admin overview shows all newest unique exam rooms in the system including those from previous uploads, not just rooms from the current upload being tested. The test only needs to verify that the expected rooms from the current upload are present in the response.
src/main/java/de/tum/cit/aet/artemis/communication/service/conversation/ChannelService.java (1)

307-314: Same user retrieval pattern as lecture channel.

This method also switched to getUser() (line 313), consistent with the lecture channel change. The same verification applies here.

src/main/java/de/tum/cit/aet/artemis/lecture/web/LectureResource.java (4)

129-149: LGTM!

The endpoint correctly uses DTOs to prevent entity injection from the client. Manual entity construction from DTO fields (lines 137-142) aligns with server coding guidelines and the PR objectives.


270-302: LGTM!

The endpoint correctly returns DTOs and properly converts entities using the GetLecturesDTO.from() factory method.


351-361: LGTM with minor performance note.

The endpoint correctly returns a DTO and includes the channel name via a separate query (line 357). This additional query is acceptable for this use case, though it could be optimized in the future by fetching the channel name with the lecture in a single query.


376-394: LGTM!

The endpoint correctly returns a DTO. The null channel name (line 392) is intentionally set with a comment explaining that it's not needed by the client, which is an acceptable design decision.

@github-project-automation github-project-automation bot moved this from Work In Progress to Ready For Review in Artemis Development Nov 22, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 22, 2025
@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ✅Skipped ⚠️FailedTime ⏱
End-to-End (E2E) Test Report215 ran212 passed3 skipped0 failed1h 5m 16s 269ms
TestResultTime ⏱
No test annotations available

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

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

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report215 ran211 passed3 skipped1 failed1h 16m 10s 152ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exam/test-exam/TestExamParticipation.spec.ts
ts.Test exam participation › Early Hand-in › Using exercise overview to navigate within exam❌ failure3m 43s 346ms

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

📜 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 6fe4434 and 382882b.

📒 Files selected for processing (1)
  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/main/webapp/**/*.ts

⚙️ CodeRabbit configuration file

angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

Files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
🧠 Learnings (10)
📓 Common learnings
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11419
File: src/main/java/de/tum/cit/aet/artemis/exam/domain/ExamUser.java:16-17
Timestamp: 2025-09-25T20:28:36.905Z
Learning: In the Artemis codebase, ExamUser entity uses ExamSeatDTO as a transient field for performance reasons. SamuelRoettgermann tested domain value objects but they caused 60x slower performance. This architectural exception is approved by maintainers due to significant performance benefits and Artemis naming convention requirements.
Learnt from: Elfari1028
Repo: ls1intum/Artemis PR: 11351
File: src/main/java/de/tum/cit/aet/artemis/versioning/dto/QuizExerciseSnapshotDTO.java:52-53
Timestamp: 2025-09-25T11:25:54.261Z
Learning: In the Artemis versioning system, quiz questions processed by QuizExerciseSnapshotDTO should always have valid IDs (non-null getId()) since versioning works with persisted entities, making null filtering unnecessary according to Elfari1028.
Learnt from: Elfari1028
Repo: ls1intum/Artemis PR: 11491
File: src/main/java/de/tum/cit/aet/artemis/exercise/web/ExerciseResource.java:376-378
Timestamp: 2025-10-22T21:31:54.240Z
Learning: In Artemis, ExerciseVersionService.createExerciseVersion(...) (src/main/java/de/tum/cit/aet/artemis/exercise/service/ExerciseVersionService.java) eagerly re-fetches the target exercise (via type-specific findForVersioningById) before building the ExerciseSnapshotDTO. Controllers (e.g., ExerciseResource.toggleSecondCorrectionEnabled) do not need to reload the exercise before invoking createExerciseVersion.
📚 Learning: 2025-08-21T17:30:20.530Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/drag-and-drop-question/drag-and-drop-question.component.spec.ts:34-34
Timestamp: 2025-08-21T17:30:20.530Z
Learning: FitTextDirective in src/main/webapp/app/quiz/shared/fit-text/fit-text.directive.ts is a standalone directive marked with standalone: true, so it should be imported in TestBed imports array, not declarations array.

Applied to files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
📚 Learning: 2025-04-22T10:19:41.546Z
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 10714
File: src/main/webapp/app/quiz/manage/create-buttons/quiz-exercise-create-buttons.component.ts:11-15
Timestamp: 2025-04-22T10:19:41.546Z
Learning: In Angular 19, standalone components are the default, so components with an `imports` array don't need to explicitly declare `standalone: true` property in the component decorator.

Applied to files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
📚 Learning: 2024-06-10T19:44:09.116Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8451
File: src/main/webapp/app/exercises/programming/shared/lifecycle/programming-exercise-lifecycle.component.html:187-187
Timestamp: 2024-06-10T19:44:09.116Z
Learning: Use `artemisTranslate` for handling translations in Angular templates within the Artemis platform, as per the project-specific requirements.

Applied to files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
📚 Learning: 2025-05-27T15:52:32.983Z
Learnt from: eylulnc
Repo: ls1intum/Artemis PR: 10910
File: src/main/webapp/app/core/user/settings/global-notifications-settings/global-notifications-settings.component.html:0-0
Timestamp: 2025-05-27T15:52:32.983Z
Learning: In Artemis codebase, the jhiTranslate directive requires interpolation syntax `jhiTranslate="{{ expression }}"` rather than property binding `[jhiTranslate]="expression"` when using dynamic translation keys. Property binding will not display the translation correctly.

Applied to files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
📚 Learning: 2024-07-09T19:11:26.867Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8858
File: src/main/webapp/app/shared/exercise-filter/exercise-filter-modal.component.html:79-93
Timestamp: 2024-07-09T19:11:26.867Z
Learning: In the context of PR ls1intum/Artemis#8858, avoid suggesting replacing `if` and `for` with `*ngIf` and `*ngFor`.

Applied to files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
📚 Learning: 2024-10-08T15:35:52.595Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8858
File: src/main/webapp/app/shared/range-slider/range-slider.component.ts:16-16
Timestamp: 2024-10-08T15:35:52.595Z
Learning: For the PR ls1intum/Artemis#8858, avoid suggesting the removal of trivially inferred type annotations for the `step` property in `range-slider.component.ts`.

Applied to files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
📚 Learning: 2024-07-10T08:46:22.532Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8858
File: src/main/webapp/app/shared/range-slider/range-slider.component.ts:35-52
Timestamp: 2024-07-10T08:46:22.532Z
Learning: For the PR ls1intum/Artemis#8858, avoid suggesting changes related to the `querySelectorAll` method in the `ngOnInit` method of the `RangeSliderComponent`.

Applied to files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
📚 Learning: 2024-07-09T19:07:38.801Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8858
File: src/main/webapp/app/shared/exercise-filter/exercise-filter-modal.component.ts:185-188
Timestamp: 2024-07-09T19:07:38.801Z
Learning: For the PR ls1intum/Artemis#8858, avoid suggesting moving assignments out of expressions within the `resetFilter` method in `exercise-filter-modal.component.ts`.

Applied to files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
📚 Learning: 2024-10-28T11:34:03.750Z
Learnt from: isabellagessl
Repo: ls1intum/Artemis PR: 9615
File: src/main/webapp/app/overview/exercise-details/course-exercise-details.module.ts:75-75
Timestamp: 2024-10-28T11:34:03.750Z
Learning: In Angular, when a non-standalone component declared in an NgModule needs to use a standalone component, the standalone component should be imported into the NgModule's `imports` array. This allows the non-standalone component to utilize the standalone component in its template.

Applied to files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
⏰ 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: Codacy Static Code Analysis
  • GitHub Check: client-style
  • GitHub Check: client-tests-selected
  • GitHub Check: client-tests
  • GitHub Check: server-style
  • 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: Build .war artifact
  • GitHub Check: Analyse
  • GitHub Check: bean-instantiation-check

LeZhen1105
LeZhen1105 previously approved these changes Nov 22, 2025
Copy link
Contributor

@LeZhen1105 LeZhen1105 left a comment

Choose a reason for hiding this comment

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

tested on TS4 worked as expected

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

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

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 22, 2025
@florian-glombik florian-glombik temporarily deployed to artemis-test1.artemis.cit.tum.de November 22, 2025 20:41 — with GitHub Actions Inactive
@krusche krusche dismissed stale reviews from coderabbitai[bot] and LeZhen1105 via f8e1d36 November 22, 2025 21:03
@krusche krusche requested a review from a team as a code owner November 22, 2025 21:03
@github-actions github-actions bot added the lti Pull requests that affect the corresponding module label Nov 22, 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: 0

Caution

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

⚠️ Outside diff range comments (1)
src/main/webapp/app/shared/organization-selector/organization-selector.component.ts (1)

19-28: Prevent memory leak by unsubscribing from the observable.

The subscription on line 20 is not cleaned up when the component is destroyed. For modal components that are frequently created and destroyed, this causes memory leaks.

As per coding guidelines

Apply this diff to fix the memory leak:

+import { Component, OnInit, OnDestroy, inject } from '@angular/core';
 import { OrganizationManagementService } from 'app/core/admin/organization-management/organization-management.service';
 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { Organization } from 'app/core/shared/entities/organization.model';
 import { TranslateDirective } from 'app/shared/language/translate.directive';
+import { Subject } from 'rxjs';
+import { takeUntil } from 'rxjs/operators';

 @Component({
     selector: 'jhi-organization-selector',
     templateUrl: './organization-selector.component.html',
     imports: [TranslateDirective],
 })
-export class OrganizationSelectorComponent implements OnInit {
+export class OrganizationSelectorComponent implements OnInit, OnDestroy {
     private activeModal = inject(NgbActiveModal);
     private organizationService = inject(OrganizationManagementService);
+    private destroy$ = new Subject<void>();

     organizations: Organization[];
     availableOrganizations: Organization[];

     ngOnInit(): void {
-        this.organizationService.getOrganizations().subscribe((data) => {
+        this.organizationService.getOrganizations().pipe(takeUntil(this.destroy$)).subscribe((data) => {
             this.availableOrganizations = data;
             if (this.organizations !== undefined) {
                 this.availableOrganizations = this.availableOrganizations.filter((organization) => {
                     return !this.organizations.some((currentOrganization) => currentOrganization.id === organization.id);
                 });
             }
         });
     }
+
+    ngOnDestroy(): void {
+        this.destroy$.next();
+        this.destroy$.complete();
+    }

     closeModal(organization: Organization | undefined) {
         this.activeModal.close(organization);
     }
 }
🧹 Nitpick comments (3)
src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.html (1)

3-3: Consider completing the translation migration for consistency.

Lines 3 and 66 still use the jhiTranslate directive while the rest of the file now uses the artemisTranslate pipe (lines 12, 17, 30, 37, 45). Since this file is undergoing translation updates, updating these two lines would ensure consistency throughout the component and align fully with the artemisTranslate approach established in this PR.

If you'd like to complete the migration, apply this diff:

-        <div class="transcript-title" jhiTranslate="artemisApp.attachmentVideoUnit.videoPlayer.transcript">Transcript</div>
+        <div class="transcript-title">{{ 'artemisApp.attachmentVideoUnit.videoPlayer.transcript' | artemisTranslate }}</div>
-            <div class="no-results" jhiTranslate="artemisApp.attachmentVideoUnit.videoPlayer.noMatchingTranscript">No matching transcript found</div>
+            <div class="no-results">{{ 'artemisApp.attachmentVideoUnit.videoPlayer.noMatchingTranscript' | artemisTranslate }}</div>

Also applies to: 66-66

src/main/webapp/app/lti/manage/lti13-select-course/lti13-select-course.component.ts (2)

21-23: Remove unnecessary async keyword.

The async keyword on ngOnInit serves no purpose since the method doesn't use await. This can be misleading to other developers.

Apply this diff:

-    async ngOnInit() {
+    ngOnInit() {
         this.loadAndFilterCourses();
     }

25-41: Consider adding subscription cleanup to prevent potential memory leaks.

The subscription in loadAndFilterCourses() is not being unsubscribed. While HTTP observables typically complete automatically, explicit cleanup is a best practice to prevent memory leaks if the component is destroyed before the request completes.

As per coding guidelines (memory_leak_prevention:true), consider one of these approaches:

  1. Store the subscription and unsubscribe in ngOnDestroy
  2. Use the takeUntilDestroyed() operator (modern Angular approach)

Approach 1: Manual cleanup

import { Component, OnInit, OnDestroy, inject } from '@angular/core';
import { Subscription } from 'rxjs';

export class LtiCoursesComponent implements OnInit, OnDestroy {
    private subscription?: Subscription;
    
    loadAndFilterCourses() {
        const clientId = this.sessionStorageService.retrieve<string>('clientRegistrationId');
        if (clientId) {
            this.subscription = this.courseService.findAllOnlineCoursesWithRegistrationId(clientId).subscribe({
                // ... handlers
            });
        }
    }
    
    ngOnDestroy() {
        this.subscription?.unsubscribe();
    }
}

Approach 2: Using takeUntilDestroyed (preferred for modern Angular)

import { Component, OnInit, inject, DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';

export class LtiCoursesComponent implements OnInit {
    private destroyRef = inject(DestroyRef);
    
    loadAndFilterCourses() {
        const clientId = this.sessionStorageService.retrieve<string>('clientRegistrationId');
        if (clientId) {
            this.courseService.findAllOnlineCoursesWithRegistrationId(clientId)
                .pipe(takeUntilDestroyed(this.destroyRef))
                .subscribe({
                    // ... handlers
                });
        }
    }
}
📜 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 382882b and f8e1d36.

📒 Files selected for processing (32)
  • src/main/webapp/app/atlas/overview/competency-card/competency-card.component.spec.ts (1 hunks)
  • src/main/webapp/app/core/course/manage/overview/course-management-card.component.spec.ts (1 hunks)
  • src/main/webapp/app/core/feature-overview/feature-overview.component.ts (1 hunks)
  • src/main/webapp/app/exam/overview/exercises/file-upload/file-upload-exam-submission.component.spec.ts (1 hunks)
  • src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.spec.ts (1 hunks)
  • src/main/webapp/app/exercise/additional-feedback/additional-feedback.component.ts (1 hunks)
  • src/main/webapp/app/lecture/manage/lecture-import/lecture-import.component.ts (1 hunks)
  • src/main/webapp/app/lecture/manage/lecture-units/services/attachment-video-unit.service.ts (1 hunks)
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.ts (1 hunks)
  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.html (2 hunks)
  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts (1 hunks)
  • src/main/webapp/app/lti/manage/lti13-select-course/lti13-select-course.component.ts (1 hunks)
  • src/main/webapp/app/lti/overview/lti13-dynamic-registration/lti13-dynamic-registration.component.ts (1 hunks)
  • src/main/webapp/app/lti/overview/lti13-select-content/lti13-select-content.component.ts (1 hunks)
  • src/main/webapp/app/shared/components/confirm-autofocus-modal/confirm-autofocus-modal.component.ts (1 hunks)
  • src/main/webapp/app/shared/components/not-released-tag/not-released-tag.component.ts (1 hunks)
  • src/main/webapp/app/shared/confirm-entity-name/confirm-entity-name.component.ts (1 hunks)
  • src/main/webapp/app/shared/connection-status/connection-status.component.ts (1 hunks)
  • src/main/webapp/app/shared/connection-warning/connection-warning.component.ts (1 hunks)
  • src/main/webapp/app/shared/data-table/data-table.component.ts (1 hunks)
  • src/main/webapp/app/shared/date-time-picker/date-time-picker.component.ts (1 hunks)
  • src/main/webapp/app/shared/delete-dialog/component/delete-dialog.component.ts (1 hunks)
  • src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts (1 hunks)
  • src/main/webapp/app/shared/export/modal/export-modal.component.ts (1 hunks)
  • src/main/webapp/app/shared/organization-selector/organization-selector.component.ts (1 hunks)
  • src/main/webapp/app/shared/pagination/item-count.component.ts (1 hunks)
  • src/main/webapp/app/shared/score-display/score-display.component.ts (1 hunks)
  • src/main/webapp/app/shared/sidebar/sidebar.component.ts (1 hunks)
  • src/main/webapp/app/shared/statistics-graph/average-score-graph/statistics-average-score-graph.component.ts (1 hunks)
  • src/main/webapp/app/shared/statistics-graph/score-distribution-graph/statistics-score-distribution-graph.component.ts (1 hunks)
  • src/main/webapp/app/shared/table/editable-field/table-editable-field.component.ts (1 hunks)
  • src/main/webapp/app/shared/user-import/dialog/users-import-dialog.component.ts (1 hunks)
✅ Files skipped from review due to trivial changes (4)
  • src/main/webapp/app/exercise/additional-feedback/additional-feedback.component.ts
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.ts
  • src/main/webapp/app/lti/overview/lti13-dynamic-registration/lti13-dynamic-registration.component.ts
  • src/main/webapp/app/shared/export/modal/export-modal.component.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts
🧰 Additional context used
📓 Path-based instructions (2)
src/main/webapp/**/*.ts

⚙️ CodeRabbit configuration file

angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

Files:

  • src/main/webapp/app/lti/manage/lti13-select-course/lti13-select-course.component.ts
  • src/main/webapp/app/shared/date-time-picker/date-time-picker.component.ts
  • src/main/webapp/app/exam/overview/exercises/file-upload/file-upload-exam-submission.component.spec.ts
  • src/main/webapp/app/shared/pagination/item-count.component.ts
  • src/main/webapp/app/lecture/manage/lecture-import/lecture-import.component.ts
  • src/main/webapp/app/shared/components/confirm-autofocus-modal/confirm-autofocus-modal.component.ts
  • src/main/webapp/app/shared/sidebar/sidebar.component.ts
  • src/main/webapp/app/shared/connection-status/connection-status.component.ts
  • src/main/webapp/app/lti/overview/lti13-select-content/lti13-select-content.component.ts
  • src/main/webapp/app/core/course/manage/overview/course-management-card.component.spec.ts
  • src/main/webapp/app/shared/statistics-graph/average-score-graph/statistics-average-score-graph.component.ts
  • src/main/webapp/app/atlas/overview/competency-card/competency-card.component.spec.ts
  • src/main/webapp/app/core/feature-overview/feature-overview.component.ts
  • src/main/webapp/app/shared/table/editable-field/table-editable-field.component.ts
  • src/main/webapp/app/shared/statistics-graph/score-distribution-graph/statistics-score-distribution-graph.component.ts
  • src/main/webapp/app/shared/organization-selector/organization-selector.component.ts
  • src/main/webapp/app/shared/data-table/data-table.component.ts
  • src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.spec.ts
  • src/main/webapp/app/shared/delete-dialog/component/delete-dialog.component.ts
  • src/main/webapp/app/shared/connection-warning/connection-warning.component.ts
  • src/main/webapp/app/shared/components/not-released-tag/not-released-tag.component.ts
  • src/main/webapp/app/shared/confirm-entity-name/confirm-entity-name.component.ts
  • src/main/webapp/app/shared/user-import/dialog/users-import-dialog.component.ts
  • src/main/webapp/app/shared/score-display/score-display.component.ts
  • src/main/webapp/app/lecture/manage/lecture-units/services/attachment-video-unit.service.ts
  • src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts
src/main/webapp/**/*.html

⚙️ CodeRabbit configuration file

@if and @for are new and valid Angular syntax replacing *ngIf and *ngFor. They should always be used over the old style.

Files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.html
🧠 Learnings (32)
📓 Common learnings
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11419
File: src/main/java/de/tum/cit/aet/artemis/exam/domain/ExamUser.java:16-17
Timestamp: 2025-09-25T20:28:36.905Z
Learning: In the Artemis codebase, ExamUser entity uses ExamSeatDTO as a transient field for performance reasons. SamuelRoettgermann tested domain value objects but they caused 60x slower performance. This architectural exception is approved by maintainers due to significant performance benefits and Artemis naming convention requirements.
Learnt from: Elfari1028
Repo: ls1intum/Artemis PR: 11491
File: src/main/java/de/tum/cit/aet/artemis/exercise/web/ExerciseResource.java:376-378
Timestamp: 2025-10-22T21:31:54.240Z
Learning: In Artemis, ExerciseVersionService.createExerciseVersion(...) (src/main/java/de/tum/cit/aet/artemis/exercise/service/ExerciseVersionService.java) eagerly re-fetches the target exercise (via type-specific findForVersioningById) before building the ExerciseSnapshotDTO. Controllers (e.g., ExerciseResource.toggleSecondCorrectionEnabled) do not need to reload the exercise before invoking createExerciseVersion.
Learnt from: eceeeren
Repo: ls1intum/Artemis PR: 10533
File: src/main/java/de/tum/cit/aet/artemis/core/web/CourseResource.java:839-857
Timestamp: 2025-04-04T09:39:24.832Z
Learning: In the Artemis application, filtering of unreleased exercises is handled at the database level through SQL queries in the repository methods rather than in the application code. The method findByCourseIdWithFutureDueDatesAndCategories in ExerciseRepository applies this filtering, making additional application-level filtering unnecessary.
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11378
File: src/main/java/de/tum/cit/aet/artemis/exam/service/ExamRoomDistributionService.java:13-16
Timestamp: 2025-09-15T11:18:26.439Z
Learning: In ExamRoomDistributionService.distributeRegisteredStudents method in src/main/java/de/tum/cit/aet/artemis/exam/service/ExamRoomDistributionService.java, the team has decided not to use Transactional annotation despite multiple repository operations, based on human reviewer consultation.
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11419
File: src/main/java/de/tum/cit/aet/artemis/exam/web/ExamRoomDistributionResource.java:62-78
Timestamp: 2025-09-25T20:43:41.712Z
Learning: In the ExamRoomDistributionService.distributeRegisteredStudents method in src/main/java/de/tum/cit/aet/artemis/exam/service/ExamRoomDistributionService.java, ExamRoom entities are shared resources that are dynamically assigned to exams through the ExamRoomExamAssignment join table. Rooms don't "belong" to exams until the distribution process creates these assignments. The method first clears existing assignments for the exam, then creates new ones for the provided room IDs.
📚 Learning: 2024-11-07T00:36:51.500Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 9694
File: src/main/webapp/app/shared/date-time-picker/date-time-picker.component.ts:29-29
Timestamp: 2024-11-07T00:36:51.500Z
Learning: In the Angular `FormDateTimePickerComponent` in `src/main/webapp/app/shared/date-time-picker/date-time-picker.component.ts`, the `value` model property may sometimes be a `string` because the component is used in multiple places where a `string` is passed. Therefore, changing its type from `any` to a more specific type could cause issues.

Applied to files:

  • src/main/webapp/app/shared/date-time-picker/date-time-picker.component.ts
📚 Learning: 2025-08-21T17:30:20.530Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/drag-and-drop-question/drag-and-drop-question.component.spec.ts:34-34
Timestamp: 2025-08-21T17:30:20.530Z
Learning: FitTextDirective in src/main/webapp/app/quiz/shared/fit-text/fit-text.directive.ts is a standalone directive marked with standalone: true, so it should be imported in TestBed imports array, not declarations array.

Applied to files:

  • src/main/webapp/app/shared/date-time-picker/date-time-picker.component.ts
  • src/main/webapp/app/exam/overview/exercises/file-upload/file-upload-exam-submission.component.spec.ts
  • src/main/webapp/app/shared/pagination/item-count.component.ts
  • src/main/webapp/app/lecture/manage/lecture-import/lecture-import.component.ts
  • src/main/webapp/app/shared/components/confirm-autofocus-modal/confirm-autofocus-modal.component.ts
  • src/main/webapp/app/shared/sidebar/sidebar.component.ts
  • src/main/webapp/app/shared/connection-status/connection-status.component.ts
  • src/main/webapp/app/lti/overview/lti13-select-content/lti13-select-content.component.ts
  • src/main/webapp/app/core/course/manage/overview/course-management-card.component.spec.ts
  • src/main/webapp/app/shared/statistics-graph/average-score-graph/statistics-average-score-graph.component.ts
  • src/main/webapp/app/atlas/overview/competency-card/competency-card.component.spec.ts
  • src/main/webapp/app/core/feature-overview/feature-overview.component.ts
  • src/main/webapp/app/shared/table/editable-field/table-editable-field.component.ts
  • src/main/webapp/app/shared/statistics-graph/score-distribution-graph/statistics-score-distribution-graph.component.ts
  • src/main/webapp/app/shared/organization-selector/organization-selector.component.ts
  • src/main/webapp/app/shared/data-table/data-table.component.ts
  • src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.spec.ts
  • src/main/webapp/app/shared/delete-dialog/component/delete-dialog.component.ts
  • src/main/webapp/app/shared/connection-warning/connection-warning.component.ts
  • src/main/webapp/app/shared/components/not-released-tag/not-released-tag.component.ts
  • src/main/webapp/app/shared/confirm-entity-name/confirm-entity-name.component.ts
  • src/main/webapp/app/shared/user-import/dialog/users-import-dialog.component.ts
  • src/main/webapp/app/shared/score-display/score-display.component.ts
  • src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts
📚 Learning: 2024-09-13T11:36:07.446Z
Learnt from: undernagruzez
Repo: ls1intum/Artemis PR: 9296
File: src/main/webapp/app/admin/cleanup-service/cleanup-service.component.ts:19-44
Timestamp: 2024-09-13T11:36:07.446Z
Learning: In `cleanup-service.component.ts`, the date range for cleanup operations is configurable through user input via the date time picker.

Applied to files:

  • src/main/webapp/app/shared/date-time-picker/date-time-picker.component.ts
📚 Learning: 2025-09-03T11:25:50.530Z
Learnt from: marlonnienaber
Repo: ls1intum/Artemis PR: 11308
File: src/main/webapp/app/core/calendar/shared/util/calendar-util.ts:4-4
Timestamp: 2025-09-03T11:25:50.530Z
Learning: The Artemis project uses a centralized dayjs configuration approach. All dayjs plugins, including isoWeek, are configured globally in `src/main/webapp/app/core/config/dayjs.ts`, so local plugin imports and dayjs.extend() calls in individual files are redundant and should be removed.

Applied to files:

  • src/main/webapp/app/shared/date-time-picker/date-time-picker.component.ts
📚 Learning: 2025-04-22T10:19:41.546Z
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 10714
File: src/main/webapp/app/quiz/manage/create-buttons/quiz-exercise-create-buttons.component.ts:11-15
Timestamp: 2025-04-22T10:19:41.546Z
Learning: In Angular 19, standalone components are the default, so components with an `imports` array don't need to explicitly declare `standalone: true` property in the component decorator.

Applied to files:

  • src/main/webapp/app/shared/date-time-picker/date-time-picker.component.ts
  • src/main/webapp/app/lecture/manage/lecture-import/lecture-import.component.ts
  • src/main/webapp/app/shared/components/confirm-autofocus-modal/confirm-autofocus-modal.component.ts
  • src/main/webapp/app/shared/sidebar/sidebar.component.ts
  • src/main/webapp/app/shared/connection-status/connection-status.component.ts
  • src/main/webapp/app/shared/organization-selector/organization-selector.component.ts
  • src/main/webapp/app/shared/data-table/data-table.component.ts
  • src/main/webapp/app/shared/components/not-released-tag/not-released-tag.component.ts
  • src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts
📚 Learning: 2024-06-10T19:44:09.116Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8451
File: src/main/webapp/app/exercises/programming/shared/lifecycle/programming-exercise-lifecycle.component.html:187-187
Timestamp: 2024-06-10T19:44:09.116Z
Learning: Use `artemisTranslate` for handling translations in Angular templates within the Artemis platform, as per the project-specific requirements.

Applied to files:

  • src/main/webapp/app/shared/date-time-picker/date-time-picker.component.ts
  • src/main/webapp/app/shared/pagination/item-count.component.ts
  • src/main/webapp/app/shared/components/confirm-autofocus-modal/confirm-autofocus-modal.component.ts
  • src/main/webapp/app/lti/overview/lti13-select-content/lti13-select-content.component.ts
  • src/main/webapp/app/core/course/manage/overview/course-management-card.component.spec.ts
  • src/main/webapp/app/shared/statistics-graph/average-score-graph/statistics-average-score-graph.component.ts
  • src/main/webapp/app/core/feature-overview/feature-overview.component.ts
  • src/main/webapp/app/shared/statistics-graph/score-distribution-graph/statistics-score-distribution-graph.component.ts
  • src/main/webapp/app/shared/data-table/data-table.component.ts
  • src/main/webapp/app/shared/components/not-released-tag/not-released-tag.component.ts
  • src/main/webapp/app/shared/confirm-entity-name/confirm-entity-name.component.ts
  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.html
  • src/main/webapp/app/shared/score-display/score-display.component.ts
📚 Learning: 2025-09-01T10:20:40.706Z
Learnt from: Michael-Breu-UIbk
Repo: ls1intum/Artemis PR: 10989
File: src/main/webapp/app/programming/manage/detail/programming-exercise-detail.component.with-sharing.spec.ts:132-149
Timestamp: 2025-09-01T10:20:40.706Z
Learning: In the Artemis codebase, Angular component test files for ProgrammingExerciseDetailComponent follow a pattern where the component is imported but not explicitly declared in TestBed.configureTestingModule(), yet TestBed.createComponent() still works successfully. This pattern is consistently used across test files like programming-exercise-detail.component.spec.ts and programming-exercise-detail.component.with-sharing.spec.ts.

Applied to files:

  • src/main/webapp/app/exam/overview/exercises/file-upload/file-upload-exam-submission.component.spec.ts
  • src/main/webapp/app/core/course/manage/overview/course-management-card.component.spec.ts
  • src/main/webapp/app/shared/statistics-graph/average-score-graph/statistics-average-score-graph.component.ts
  • src/main/webapp/app/atlas/overview/competency-card/competency-card.component.spec.ts
  • src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.spec.ts
  • src/main/webapp/app/shared/components/not-released-tag/not-released-tag.component.ts
  • src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts
📚 Learning: 2024-11-02T22:57:57.717Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 9656
File: src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/attachment-unit-form/attachment-unit-form.component.ts:69-71
Timestamp: 2024-11-02T22:57:57.717Z
Learning: In the `src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/attachment-unit-form/attachment-unit-form.component.ts`, the `isFormValid` computed property intentionally uses a logical OR between `this.statusChanges() === 'VALID'` and `this.fileName()` to mirror the original `isSubmitPossible` getter, ensuring consistent form validation behavior.

Applied to files:

  • src/main/webapp/app/exam/overview/exercises/file-upload/file-upload-exam-submission.component.spec.ts
  • src/main/webapp/app/lecture/manage/lecture-import/lecture-import.component.ts
  • src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.spec.ts
  • src/main/webapp/app/lecture/manage/lecture-units/services/attachment-video-unit.service.ts
📚 Learning: 2025-08-13T13:35:23.605Z
Learnt from: maximiliansoelch
Repo: ls1intum/Artemis PR: 11288
File: src/main/webapp/i18n/de/exam.json:301-304
Timestamp: 2025-08-13T13:35:23.605Z
Learning: The exam navigation buttons in exam-navigation-bar.component.html use translation keys with the path artemisApp.examParticipation.navigation.nextButton and artemisApp.examParticipation.navigation.previousButton (without the "exam" prefix in the middle).

Applied to files:

  • src/main/webapp/app/exam/overview/exercises/file-upload/file-upload-exam-submission.component.spec.ts
  • src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.spec.ts
  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.html
  • src/main/webapp/app/shared/score-display/score-display.component.ts
  • src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts
📚 Learning: 2024-10-08T15:35:42.972Z
Learnt from: JohannesStoehr
Repo: ls1intum/Artemis PR: 8976
File: src/main/webapp/app/entities/quiz/quiz-exercise.model.ts:0-0
Timestamp: 2024-10-08T15:35:42.972Z
Learning: When defining the `resetQuizForImport` function in `src/main/webapp/app/entities/quiz/quiz-exercise.model.ts`, ensure to directly refer to the `exercise` parameter instead of using `this`.

Applied to files:

  • src/main/webapp/app/exam/overview/exercises/file-upload/file-upload-exam-submission.component.spec.ts
  • src/main/webapp/app/lecture/manage/lecture-import/lecture-import.component.ts
  • src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.spec.ts
📚 Learning: 2024-10-10T11:42:23.069Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 9443
File: src/test/javascript/spec/component/hestia/git-diff-report/git-diff-modal.component.spec.ts:55-60
Timestamp: 2024-10-10T11:42:23.069Z
Learning: In `git-diff-report-modal.component.spec.ts`, using `fakeAsync` and `tick` does not work for handling asynchronous operations in the tests; alternative methods are needed.

Applied to files:

  • src/main/webapp/app/exam/overview/exercises/file-upload/file-upload-exam-submission.component.spec.ts
  • src/main/webapp/app/atlas/overview/competency-card/competency-card.component.spec.ts
📚 Learning: 2025-08-30T20:04:51.435Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11111
File: src/main/webapp/app/core/admin/exam-rooms/exam-rooms.component.ts:127-136
Timestamp: 2025-08-30T20:04:51.435Z
Learning: In the Artemis Angular components (such as `exam-rooms.component.ts`), when using translation methods like `showErrorNotification`, the base translation path is automatically prepended to the provided key. For example, if the base path is `artemisApp.examRooms.adminOverview` and you provide `examRoomOverview.loadError`, the full translation key resolves to `artemisApp.examRooms.adminOverview.examRoomOverview.loadError`.

Applied to files:

  • src/main/webapp/app/exam/overview/exercises/file-upload/file-upload-exam-submission.component.spec.ts
  • src/main/webapp/app/core/course/manage/overview/course-management-card.component.spec.ts
  • src/main/webapp/app/core/feature-overview/feature-overview.component.ts
  • src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.spec.ts
  • src/main/webapp/app/shared/connection-warning/connection-warning.component.ts
  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.html
  • src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts
📚 Learning: 2024-10-29T12:28:57.305Z
Learnt from: SimonEntholzer
Repo: ls1intum/Artemis PR: 9478
File: src/main/webapp/app/shared/user-settings/ssh-settings/details/ssh-user-settings-key-details.component.ts:104-111
Timestamp: 2024-10-29T12:28:57.305Z
Learning: In `ssh-user-settings-key-details.component.ts`, changing the error handling code by adding optional chaining (`?.`) and replacing `.indexOf()` with `.includes()` may alter semantics and should be avoided.

Applied to files:

  • src/main/webapp/app/shared/pagination/item-count.component.ts
  • src/main/webapp/app/shared/connection-status/connection-status.component.ts
  • src/main/webapp/app/shared/organization-selector/organization-selector.component.ts
  • src/main/webapp/app/shared/connection-warning/connection-warning.component.ts
  • src/main/webapp/app/shared/user-import/dialog/users-import-dialog.component.ts
📚 Learning: 2025-01-18T08:49:30.693Z
Learnt from: SimonEntholzer
Repo: ls1intum/Artemis PR: 10147
File: src/main/webapp/app/shared/components/code-button/code-button.component.ts:1-1
Timestamp: 2025-01-18T08:49:30.693Z
Learning: In Angular 19+ projects, component inputs should use the new input() function from angular/core instead of the Input() decorator, as it's part of the new signals architecture that improves performance and type safety.

Applied to files:

  • src/main/webapp/app/shared/pagination/item-count.component.ts
  • src/main/webapp/app/shared/table/editable-field/table-editable-field.component.ts
  • src/main/webapp/app/shared/components/not-released-tag/not-released-tag.component.ts
📚 Learning: 2025-10-10T17:12:35.471Z
Learnt from: marlonnienaber
Repo: ls1intum/Artemis PR: 11436
File: src/main/webapp/app/lecture/manage/lecture-series-create/lecture-series-create.component.ts:356-361
Timestamp: 2025-10-10T17:12:35.471Z
Learning: In the LectureSeriesCreateComponent (src/main/webapp/app/lecture/manage/lecture-series-create/lecture-series-create.component.ts), the rawExistingLectures input contains only persisted Lecture entities from the database, so their id field is guaranteed to be non-null despite the Lecture type having id?: number. The cast to ExistingLecture at line 359 is therefore safe.

Applied to files:

  • src/main/webapp/app/lecture/manage/lecture-import/lecture-import.component.ts
  • src/main/webapp/app/lecture/manage/lecture-units/services/attachment-video-unit.service.ts
📚 Learning: 2024-10-28T11:34:03.750Z
Learnt from: isabellagessl
Repo: ls1intum/Artemis PR: 9615
File: src/main/webapp/app/overview/exercise-details/course-exercise-details.module.ts:75-75
Timestamp: 2024-10-28T11:34:03.750Z
Learning: In Angular, when a non-standalone component declared in an NgModule needs to use a standalone component, the standalone component should be imported into the NgModule's `imports` array. This allows the non-standalone component to utilize the standalone component in its template.

Applied to files:

  • src/main/webapp/app/lecture/manage/lecture-import/lecture-import.component.ts
  • src/main/webapp/app/shared/components/confirm-autofocus-modal/confirm-autofocus-modal.component.ts
  • src/main/webapp/app/shared/sidebar/sidebar.component.ts
  • src/main/webapp/app/lti/overview/lti13-select-content/lti13-select-content.component.ts
  • src/main/webapp/app/shared/data-table/data-table.component.ts
  • src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts
📚 Learning: 2024-06-10T19:44:09.116Z
Learnt from: undernagruzez
Repo: ls1intum/Artemis PR: 8498
File: src/main/webapp/app/exercises/shared/self-learning-feedback-request/self-learning-feedback-request.component.ts:0-0
Timestamp: 2024-06-10T19:44:09.116Z
Learning: Type-only imports are not suitable for scenarios where the imported entities are used as values, such as with Angular components and icons.

Applied to files:

  • src/main/webapp/app/lecture/manage/lecture-import/lecture-import.component.ts
  • src/main/webapp/app/shared/data-table/data-table.component.ts
  • src/main/webapp/app/shared/delete-dialog/component/delete-dialog.component.ts
📚 Learning: 2024-10-10T11:36:20.177Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 9443
File: src/main/webapp/app/exam/manage/student-exams/student-exam-timeline/programming-exam-diff/programming-exercise-exam-diff.component.ts:126-129
Timestamp: 2024-10-10T11:36:20.177Z
Learning: In Angular applications using `NgbModal`, wrapping data with `signal()` when passing inputs to modal components (e.g., `GitDiffReportModalComponent`) is necessary until `NgbModal` supports signal inputs.

Applied to files:

  • src/main/webapp/app/shared/components/confirm-autofocus-modal/confirm-autofocus-modal.component.ts
📚 Learning: 2025-05-27T15:39:30.592Z
Learnt from: eylulnc
Repo: ls1intum/Artemis PR: 10910
File: src/main/webapp/app/core/user/settings/global-notifications-settings/global-notifications-settings.component.ts:101-101
Timestamp: 2025-05-27T15:39:30.592Z
Learning: In Angular components, constants defined at module level (even if exported) are not accessible in templates. To use constants in templates for conditional rendering or comparisons, they must be assigned to a protected or public property of the component class, like `protected readonly CONSTANT_NAME = CONSTANT_NAME;`.

Applied to files:

  • src/main/webapp/app/shared/components/confirm-autofocus-modal/confirm-autofocus-modal.component.ts
  • src/main/webapp/app/lti/overview/lti13-select-content/lti13-select-content.component.ts
  • src/main/webapp/app/shared/data-table/data-table.component.ts
  • src/main/webapp/app/shared/delete-dialog/component/delete-dialog.component.ts
  • src/main/webapp/app/shared/confirm-entity-name/confirm-entity-name.component.ts
  • src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts
📚 Learning: 2024-10-08T15:35:42.972Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 9431
File: angular.json:116-116
Timestamp: 2024-10-08T15:35:42.972Z
Learning: In `angular.json`, the path `./node_modules/monaco-editor/min/vs` is used to provide CSS styles to the client and can remain unchanged when updating `monaco-editor`.

Applied to files:

  • src/main/webapp/app/shared/sidebar/sidebar.component.ts
  • src/main/webapp/app/shared/confirm-entity-name/confirm-entity-name.component.ts
  • src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts
📚 Learning: 2025-07-23T16:24:48.303Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 11204
File: src/main/webapp/app/quiz/manage/manage-buttons/quiz-exercise-manage-buttons.component.html:16-20
Timestamp: 2025-07-23T16:24:48.303Z
Learning: In Angular i18n within the Artemis project, translation keys like `artemisApp.quizExercise.statistics` are resolved by finding the `statistics` key within the `src/main/webapp/i18n/{locale}/quizExercise.json` file, not by searching for the full path string in the JSON files.

Applied to files:

  • src/main/webapp/app/core/course/manage/overview/course-management-card.component.spec.ts
  • src/main/webapp/app/shared/statistics-graph/average-score-graph/statistics-average-score-graph.component.ts
  • src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.spec.ts
📚 Learning: 2025-07-03T14:51:57.407Z
Learnt from: ekayandan
Repo: ls1intum/Artemis PR: 10885
File: src/main/webapp/app/programming/shared/git-diff-report/git-diff-report/git-diff-report.component.ts:63-74
Timestamp: 2025-07-03T14:51:57.407Z
Learning: In the `GitDiffReportComponent` (`src/main/webapp/app/programming/shared/git-diff-report/git-diff-report/git-diff-report.component.ts`), directly mutating the `diffInformation` array from `repositoryDiffInformation().diffInformations` to update the `diffReady` property works correctly with Angular's OnPush change detection strategy in this codebase.

Applied to files:

  • src/main/webapp/app/shared/statistics-graph/average-score-graph/statistics-average-score-graph.component.ts
📚 Learning: 2024-10-20T21:59:11.630Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 9505
File: src/main/webapp/app/exercises/programming/shared/code-editor/monaco/code-editor-monaco.component.html:9-9
Timestamp: 2024-10-20T21:59:11.630Z
Learning: In Angular templates within the Artemis project (e.g., `src/main/webapp/app/exercises/programming/shared/code-editor/monaco/code-editor-monaco.component.html`), properties like `selectedFile()`, `readOnlyManualFeedback()`, `highlightDifferences()`, and `course()` are signals. It is appropriate to call these signals directly in the template.

Applied to files:

  • src/main/webapp/app/shared/statistics-graph/average-score-graph/statistics-average-score-graph.component.ts
  • src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.spec.ts
  • src/main/webapp/app/shared/components/not-released-tag/not-released-tag.component.ts
  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.html
  • src/main/webapp/app/shared/score-display/score-display.component.ts
  • src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts
📚 Learning: 2024-10-08T15:35:48.768Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8858
File: src/main/webapp/app/shared/exercise-filter/exercise-filter-modal.component.ts:107-121
Timestamp: 2024-10-08T15:35:48.768Z
Learning: In the `exercise-filter-modal.component.ts` file, the non-null assertion for `categoryFilter.category.category` is safe to use as the value is always guaranteed to be defined.

Applied to files:

  • src/main/webapp/app/shared/statistics-graph/average-score-graph/statistics-average-score-graph.component.ts
📚 Learning: 2024-07-09T19:07:38.801Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8858
File: src/main/webapp/app/shared/exercise-filter/exercise-filter-modal.component.ts:185-188
Timestamp: 2024-07-09T19:07:38.801Z
Learning: For the PR ls1intum/Artemis#8858, avoid suggesting moving assignments out of expressions within the `resetFilter` method in `exercise-filter-modal.component.ts`.

Applied to files:

  • src/main/webapp/app/shared/statistics-graph/average-score-graph/statistics-average-score-graph.component.ts
  • src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.spec.ts
  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.html
  • src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts
📚 Learning: 2024-08-20T19:00:23.461Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 9230
File: src/main/webapp/app/admin/standardized-competencies/standardized-competency-management.component.ts:90-90
Timestamp: 2024-08-20T19:00:23.461Z
Learning: In the `StandardizedCompetencyManagementComponent`, the `ChangeDetectorRef` is named `changeDetectorRef` for clarity, as per the user's preference.

Applied to files:

  • src/main/webapp/app/atlas/overview/competency-card/competency-card.component.spec.ts
📚 Learning: 2025-03-26T12:29:47.826Z
Learnt from: coolchock
Repo: ls1intum/Artemis PR: 10456
File: src/main/webapp/app/exam/overview/summary/exercises/quiz-exam-summary/quiz-exam-summary.component.ts:68-75
Timestamp: 2025-03-26T12:29:47.826Z
Learning: Components with inputs defined using `input.required<T>()` in Angular don't need optional chaining when accessing the properties of the input value, as these inputs are guaranteed to have a value when the component is properly used.

Applied to files:

  • src/main/webapp/app/shared/table/editable-field/table-editable-field.component.ts
📚 Learning: 2024-10-08T15:35:42.972Z
Learnt from: iyannsch
Repo: ls1intum/Artemis PR: 9379
File: src/main/webapp/app/shared/components/code-button/code-button.component.ts:143-170
Timestamp: 2024-10-08T15:35:42.972Z
Learning: In `code-button.component.ts`, `this.exercise.id` is checked before use, so it's acceptable to use the non-null assertion operator `!` on `this.exercise.id!`.

Applied to files:

  • src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.spec.ts
  • src/main/webapp/app/shared/components/not-released-tag/not-released-tag.component.ts
  • src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts
📚 Learning: 2025-08-15T02:30:19.063Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11111
File: src/main/webapp/app/core/admin/exam-rooms/exam-rooms.component.ts:148-152
Timestamp: 2025-08-15T02:30:19.063Z
Learning: In Artemis Angular components, the DeleteDialogService uses an EventEmitter-based pattern rather than direct Observable subscription. The correct usage is: 1) Create an EventEmitter<{ [key: string]: boolean }>, 2) Subscribe to the emitter to perform the actual delete operation, 3) Call deleteDialogService.openDeleteDialog() with a configuration object containing the emitter, deleteQuestion translation key, buttonType, actionType, dialogError observable, and other options. The service handles the dialog lifecycle and emits through the provided emitter when the user confirms the deletion.

Applied to files:

  • src/main/webapp/app/shared/delete-dialog/component/delete-dialog.component.ts
📚 Learning: 2025-05-27T15:52:32.983Z
Learnt from: eylulnc
Repo: ls1intum/Artemis PR: 10910
File: src/main/webapp/app/core/user/settings/global-notifications-settings/global-notifications-settings.component.html:0-0
Timestamp: 2025-05-27T15:52:32.983Z
Learning: In Artemis codebase, the jhiTranslate directive requires interpolation syntax `jhiTranslate="{{ expression }}"` rather than property binding `[jhiTranslate]="expression"` when using dynamic translation keys. Property binding will not display the translation correctly.

Applied to files:

  • src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.html
📚 Learning: 2025-10-28T13:23:39.105Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11507
File: src/main/webapp/app/exam/manage/students/room-distribution/students-room-distribution-dialog.component.html:15-15
Timestamp: 2025-10-28T13:23:39.105Z
Learning: In the students room distribution dialog component (src/main/webapp/app/exam/manage/students/room-distribution/students-room-distribution-dialog.component.html and .ts), the reserve factor input intentionally uses type="text" instead of type="number" to support specific UX requirements: integer-only input with range 0-100, allowing temporary empty state during editing (which resets to 0), showing 0 only on blur when empty, and selecting all text on focus. This precise control is implemented through custom validation handlers (handleReserveFactorInput, resetReserveFactorText, selectAllTextAndOpenDropdown) which is not achievable with native number input constraints.

Applied to files:

  • src/main/webapp/app/shared/score-display/score-display.component.ts
⏰ 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: Codacy Static Code Analysis
  • GitHub Check: Analyse
  • 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: client-tests-selected
  • GitHub Check: client-style
  • GitHub Check: client-tests
  • GitHub Check: server-style
  • GitHub Check: server-tests
  • GitHub Check: bean-instantiation-check
🔇 Additional comments (27)
src/main/webapp/app/atlas/overview/competency-card/competency-card.component.spec.ts (1)

12-13: Import path migration to app/... looks correct

Using absolute app/shared/... paths for ArtemisTimeAgoPipe and TranslateDirective is consistent with the rest of the file and the repository-wide pattern; mocks in declarations still work as before and no behavioral changes are introduced.

src/main/webapp/app/shared/connection-warning/connection-warning.component.ts (1)

8-8: Import path change to app-root alias looks good

Switching TranslateDirective to the app/shared/language/translate.directive alias is consistent with app-root import usage and does not affect behavior; the component’s imports array remains correct.

src/main/webapp/app/shared/pagination/item-count.component.ts (1)

2-2: Import path refactor is fine

Switching TranslateDirective to the app/shared/language/translate.directive alias is consistent with alias-based imports and should not change runtime behavior, assuming the existing app/* path mapping is in place.

src/main/webapp/app/shared/statistics-graph/average-score-graph/statistics-average-score-graph.component.ts (1)

12-12: Import alias update for TranslateDirective looks good

Switching to the absolute alias app/shared/language/translate.directive aligns with the shared import style and reduces the risk of fragile relative paths without changing behavior.

src/main/webapp/app/shared/components/not-released-tag/not-released-tag.component.ts (1)

4-4: LGTM! Import path normalized to absolute path.

The change from a relative import path to an absolute app path improves maintainability and aligns with the project-wide refactoring mentioned in the PR objectives.

src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.html (1)

12-12: Updated translation bindings align with coding guidelines.

The changes correctly migrate translation bindings from an older approach to the artemisTranslate pipe, which is the preferred approach per project conventions. All six affected translation keys (searchPlaceholder, clearSearch, noResults, previousResult, nextResult) use consistent syntax and proper pipe binding.

Also applies to: 17-17, 30-30, 37-37, 45-45

src/main/webapp/app/shared/data-table/data-table.component.ts (1)

25-25: LGTM! Good refactor to absolute import path.

Converting the relative import to an absolute path improves maintainability and aligns with the broader standardization effort across the codebase.

src/main/webapp/app/shared/date-time-picker/date-time-picker.component.ts (1)

9-9: LGTM! Import path modernization improves maintainability.

The refactor from relative to absolute import path using the app/ alias is a good practice that makes the codebase more maintainable and consistent.

src/main/webapp/app/shared/sidebar/sidebar.component.ts (1)

19-19: LGTM! Import path consistency improved.

The change from a relative to an absolute import path aligns with all other imports in this file and improves maintainability.

src/main/webapp/app/shared/detail-overview-list/detail-overview-list.component.ts (1)

16-16: LGTM! Import path standardization.

The change from a relative import path to an absolute alias path improves code maintainability and aligns with the broader standardization effort across the codebase.

src/main/webapp/app/shared/user-import/dialog/users-import-dialog.component.ts (1)

18-18: LGTM: Import path refactoring improves maintainability.

The change from a relative import path to an alias-based path (app/shared/language/translate.directive) is a positive improvement that enhances code maintainability and consistency across the codebase.

src/main/webapp/app/core/course/manage/overview/course-management-card.component.spec.ts (1)

18-18: LGTM! Import path normalized to absolute alias.

This change improves maintainability by using an absolute import path instead of a relative one, making the code more resilient to file relocations and consistent with other imports in this file.

src/main/webapp/app/shared/delete-dialog/component/delete-dialog.component.ts (1)

10-10: LGTM! Import path standardization improves maintainability.

The change from a relative import path to an absolute alias-based path (app/shared/language/translate.directive) is a beneficial refactoring that improves code consistency and makes the import source more explicit.

src/main/webapp/app/lecture/manage/lecture-import/lecture-import.component.ts (1)

5-7: LGTM! Import path consistency improved.

The change from relative to absolute import paths improves maintainability and aligns with the rest of the file's import style. This is a clean refactoring with no functionality impact.

src/main/webapp/app/shared/confirm-entity-name/confirm-entity-name.component.ts (1)

16-16: LGTM! Import path modernization improves consistency.

The change from a relative to an absolute import path for TranslateDirective is a beneficial refactoring that improves maintainability and aligns with the broader module resolution consistency effort across the codebase.

src/main/webapp/app/shared/statistics-graph/score-distribution-graph/statistics-score-distribution-graph.component.ts (1)

8-8: Import alias change is correct and improves maintainability

Switching TranslateDirective to the app/shared/language/translate.directive alias keeps it consistent with other app-level imports and avoids brittle relative paths. No functional impact; looks good.

src/main/webapp/app/exam/overview/exercises/file-upload/file-upload-exam-submission.component.spec.ts (1)

21-21: LGTM! Import path normalization improves consistency.

The change from a relative to an absolute import path for TranslateDirective aligns with the project-wide refactoring effort to standardize import paths, enhancing maintainability without affecting functionality.

src/main/webapp/app/exam/overview/exercises/modeling/modeling-exam-submission.component.spec.ts (1)

16-16: LGTM: Import path standardization.

The update to use an absolute import path (app/shared/language/translate.directive) improves consistency and maintainability across the codebase.

src/main/webapp/app/lti/overview/lti13-select-content/lti13-select-content.component.ts (1)

1-7: Import path normalization for TranslateDirective looks good

Switching to the app/... alias for TranslateDirective aligns with the common absolute-import pattern in this codebase and should not affect runtime behavior, assuming tsconfig path aliases are configured as elsewhere in Artemis.

src/main/webapp/app/shared/connection-status/connection-status.component.ts (1)

7-7: LGTM: Import path modernization.

The update from relative to absolute import path improves maintainability and aligns with the project-wide standardization effort described in the PR.

src/main/webapp/app/core/feature-overview/feature-overview.component.ts (1)

38-40: LGTM: Consistent import path updates.

Both TranslateDirective and ArtemisTranslatePipe now use absolute paths, improving code maintainability and consistency with the broader refactor.

src/main/webapp/app/shared/components/confirm-autofocus-modal/confirm-autofocus-modal.component.ts (1)

4-4: LGTM: Import path standardization.

The absolute import path for TranslateDirective enhances maintainability and aligns with the project-wide refactor.

src/main/webapp/app/shared/score-display/score-display.component.ts (1)

5-5: LGTM: Import path updated to absolute alias.

The change to an absolute path improves code maintainability and is consistent with the broader refactoring effort across the codebase.

src/main/webapp/app/shared/organization-selector/organization-selector.component.ts (1)

5-5: LGTM! Import path update aligns with repository-wide refactor.

The change from relative to absolute import path improves maintainability and is consistent with the broader refactoring effort mentioned in the PR summary.

src/main/webapp/app/shared/table/editable-field/table-editable-field.component.ts (1)

3-3: LGTM! Import path standardization aligns with codebase conventions.

The directive exists at the expected location, and the absolute import path is consistent with 20+ other files throughout the codebase using the same pattern.

src/main/webapp/app/lti/manage/lti13-select-course/lti13-select-course.component.ts (1)

3-3: LGTM! Import path modernization is correct.

The refactoring of import paths from relative to absolute (using the app/ alias) is consistent with the broader modernization pattern in this PR. No behavioral changes expected.

Also applies to: 7-7

src/main/webapp/app/lecture/manage/lecture-units/services/attachment-video-unit.service.ts (1)

128-132: Change from null to undefined is verified and safe.

All callers of getPlaylistUrl use truthy checks (if (playlist)) that work identically for both values. The change aligns with TypeScript conventions and introduces no breaking changes. The JSDoc, method signature, and implementation are consistent.

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

End-to-End (E2E) Test Results Summary

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

LeZhen1105
LeZhen1105 previously approved these changes Nov 22, 2025
Copy link
Contributor

@LeZhen1105 LeZhen1105 left a comment

Choose a reason for hiding this comment

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

reapprove

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.

Tested the lecture feature on ts1, I did not notice issues as instructor that are related to this PR (created an issue for something unrelated #11686)

Looks good if the failing tests are flaky and unrelated 👍
https://bamboo.ase.in.tum.de/browse/ARTEMIS-TESTS8857-JAVATEST-12

HawKhiem
HawKhiem previously approved these changes Nov 22, 2025
Copy link
Contributor

@HawKhiem HawKhiem left a comment

Choose a reason for hiding this comment

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

Tested on TS1, everything works well. Code also looks good to me 👍

@krusche krusche merged commit cbccbad into develop Nov 22, 2025
20 of 24 checks passed
@krusche krusche deleted the chore/lectures/use-dto branch November 22, 2025 21:32
@github-project-automation github-project-automation bot moved this from Ready For Review to Merged in Artemis Development Nov 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

assessment Pull requests that affect the corresponding module atlas Pull requests that affect the corresponding module buildagent Pull requests that affect the corresponding module client Pull requests that update TypeScript code. (Added Automatically!) communication Pull requests that affect the corresponding module core Pull requests that affect the corresponding module exam Pull requests that affect the corresponding module exercise Pull requests that affect the corresponding module lecture Pull requests that affect the corresponding module lti Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module ready for review server Pull requests that update Java code. (Added Automatically!) tests

Projects

Status: Merged

Development

Successfully merging this pull request may close these issues.

5 participants