openapi: 3.1.0 info: title: Artemis Application Server API contact: {name: Stephan Krusche, email: krusche@tum.de} version: 8.7.4 servers: - {url: 'http://localhost:8080', description: Generated server url} paths: /api/tutorialgroup/courses/{courseId}/tutorial-groups/{tutorialGroupId}: get: tags: [tutorial-group] operationId: getOneOfCourse parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} - name: tutorialGroupId in: path required: true schema: {type: integer, format: int64} responses: '200': description: OK content: application/json: schema: {$ref: '#/components/schemas/TutorialGroup'} put: tags: [tutorial-group] operationId: update parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} - name: tutorialGroupId in: path required: true schema: {type: integer, format: int64} requestBody: content: application/json: schema: {$ref: '#/components/schemas/TutorialGroupUpdate'} required: true responses: '200': description: OK content: application/json: schema: {$ref: '#/components/schemas/TutorialGroup'} delete: tags: [tutorial-group] operationId: delete parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} - name: tutorialGroupId in: path required: true schema: {type: integer, format: int64} responses: '200': {description: OK} /api/tutorialgroup/courses/{courseId}/tutorial-groups/{tutorialGroupId}/sessions/{sessionId}: delete: tags: [tutorial-group-session] operationId: deleteSession parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} - name: tutorialGroupId in: path required: true schema: {type: integer, format: int64} - name: sessionId in: path required: true schema: {type: integer, format: int64} responses: '200': {description: OK} ? /api/tutorialgroup/courses/{courseId}/tutorial-groups-configuration/{tutorialGroupsConfigurationId}/tutorial-free-periods/{tutorialGroupFreePeriodId} : delete: tags: [tutorial-group-free-period] operationId: delete_1 parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} - name: tutorialGroupsConfigurationId in: path required: true schema: {type: integer, format: int64} - name: tutorialGroupFreePeriodId in: path required: true schema: {type: integer, format: int64} responses: '200': {description: OK} /api/tutorialgroup/courses/{courseId}/tutorial-groups: get: tags: [tutorial-group] operationId: getAllForCourse parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} responses: '200': description: OK content: application/json: schema: type: array items: {$ref: '#/components/schemas/TutorialGroup'} post: tags: [tutorial-group] operationId: create parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} requestBody: content: application/json: schema: {$ref: '#/components/schemas/TutorialGroup'} required: true responses: '200': description: OK content: application/json: schema: {$ref: '#/components/schemas/TutorialGroup'} /api/tutorialgroup/courses/{courseId}/tutorial-groups/{tutorialGroupId}/register/{studentLogin}: post: tags: [tutorial-group] operationId: registerStudent parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} - name: tutorialGroupId in: path required: true schema: {type: integer, format: int64} - name: studentLogin in: path required: true schema: {type: string} responses: '200': {description: OK} /api/tutorialgroup/courses/{courseId}/tutorial-groups/{tutorialGroupId}/register-multiple: post: tags: [tutorial-group] operationId: registerMultipleStudentsToTutorialGroup parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} - name: tutorialGroupId in: path required: true schema: {type: integer, format: int64} requestBody: content: application/json: schema: type: array items: {$ref: '#/components/schemas/Student'} uniqueItems: true required: true responses: '200': description: OK content: application/json: schema: type: array items: {$ref: '#/components/schemas/Student'} uniqueItems: true /api/tutorialgroup/courses/{courseId}/tutorial-groups/import: post: tags: [tutorial-group] operationId: importRegistrations parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} requestBody: content: application/json: schema: type: array items: {$ref: '#/components/schemas/TutorialGroupRegistrationImport'} uniqueItems: true required: true responses: '200': description: OK content: application/json: schema: type: array items: {$ref: '#/components/schemas/TutorialGroupRegistrationImport'} /api/hyperion/programming-exercises/{programmingExerciseId}/consistency-check: post: tags: [hyperion-problem-statement] operationId: checkExerciseConsistency parameters: - name: programmingExerciseId in: path required: true schema: {type: integer, format: int64} responses: '200': description: OK content: application/json: schema: {$ref: '#/components/schemas/ConsistencyCheckResponse'} /api/hyperion/programming-exercises/{exerciseId}/generate-code: post: tags: [hyperion-code-generation] operationId: generateCode parameters: - name: exerciseId in: path required: true schema: {type: integer, format: int64} requestBody: content: application/json: schema: {$ref: '#/components/schemas/CodeGenerationRequest'} required: true responses: '200': description: OK content: application/json: schema: {$ref: '#/components/schemas/CodeGenerationJobStart'} /api/hyperion/courses/{courseId}/problem-statements/rewrite: post: tags: [hyperion-problem-statement] operationId: rewriteProblemStatement parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} requestBody: content: application/json: schema: {$ref: '#/components/schemas/ProblemStatementRewriteRequest'} required: true responses: '200': description: OK content: application/json: schema: {$ref: '#/components/schemas/ProblemStatementRewriteResponse'} /api/hyperion/courses/{courseId}/problem-statements/generate: post: tags: [hyperion-problem-statement] operationId: generateProblemStatement parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} requestBody: content: application/json: schema: {$ref: '#/components/schemas/ProblemStatementGenerationRequest'} required: true responses: '200': description: OK content: application/json: schema: {$ref: '#/components/schemas/ProblemStatementGenerationResponse'} /api/hyperion/courses/{courseId}/faq/rewrite: post: tags: [hyperion-faq] operationId: rewriteFaq parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} requestBody: content: application/json: schema: {$ref: '#/components/schemas/RewriteFaqRequest'} required: true responses: '200': description: OK content: application/json: schema: {$ref: '#/components/schemas/RewriteFaqResponse'} /api/tutorialgroup/tutorial-groups/{tutorialGroupId}/title: get: tags: [tutorial-group] operationId: getTitle parameters: - name: tutorialGroupId in: path required: true schema: {type: integer, format: int64} responses: '200': description: OK content: application/json: schema: {type: string} /api/tutorialgroup/courses/{courseId}/tutorial-groups/language-values: get: tags: [tutorial-group] operationId: getUniqueLanguageValues parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} responses: '200': description: OK content: application/json: schema: type: array items: {type: string} uniqueItems: true /api/tutorialgroup/courses/{courseId}/tutorial-groups/export/json: get: tags: [tutorial-group] operationId: exportTutorialGroupsToJSON parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} - name: fields in: query required: true schema: type: array items: {type: string} responses: '200': description: OK content: application/json: schema: type: array items: {$ref: '#/components/schemas/TutorialGroupExport'} /api/tutorialgroup/courses/{courseId}/tutorial-groups/export/csv: get: tags: [tutorial-group] operationId: exportTutorialGroupsToCSV parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} - name: fields in: query required: true schema: type: array items: {type: string} responses: '200': description: OK content: text/csv: schema: {type: string, format: binary} /api/tutorialgroup/courses/{courseId}/tutorial-groups/campus-values: get: tags: [tutorial-group] operationId: getUniqueCampusValues parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} responses: '200': description: OK content: application/json: schema: type: array items: {type: string} uniqueItems: true /api/tutorialgroup/courses/{courseId}/tutorial-group-detail/{tutorialGroupId}: get: tags: [tutorial-group] operationId: getTutorialGroupDetailGroupDTO parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} - name: tutorialGroupId in: path required: true schema: {type: integer, format: int64} responses: '200': description: OK content: application/json: schema: {$ref: '#/components/schemas/TutorialGroupDetailGroup'} /api/tutorialgroup/courses/{courseId}/tutorial-groups/{tutorialGroupId}/deregister/{studentLogin}: delete: tags: [tutorial-group] operationId: deregisterStudent parameters: - name: courseId in: path required: true schema: {type: integer, format: int64} - name: tutorialGroupId in: path required: true schema: {type: integer, format: int64} - name: studentLogin in: path required: true schema: {type: string} responses: '200': {description: OK} /api/exercise/exercises/{exerciseId}/review-threads: post: tags: [exercise-review] operationId: createReviewThread parameters: - name: exerciseId in: path required: true schema: {type: integer, format: int64} requestBody: content: application/json: schema: {$ref: '#/components/schemas/CreateCommentThreadDTO'} required: true responses: '201': description: Created content: application/json: schema: {$ref: '#/components/schemas/CommentThreadDTO'} get: tags: [exercise-review] operationId: getReviewThreads parameters: - name: exerciseId in: path required: true schema: {type: integer, format: int64} responses: '200': description: OK content: application/json: schema: type: array items: {$ref: '#/components/schemas/CommentThreadDTO'} /api/exercise/exercises/{exerciseId}/review-thread-groups: post: tags: [exercise-review] operationId: createReviewThreadGroup parameters: - name: exerciseId in: path required: true schema: {type: integer, format: int64} requestBody: content: application/json: schema: {$ref: '#/components/schemas/CreateCommentThreadGroupDTO'} required: true responses: '201': description: Created content: application/json: schema: {$ref: '#/components/schemas/CommentThreadGroupDTO'} /api/exercise/exercises/{exerciseId}/review-thread-groups/{groupId}: delete: tags: [exercise-review] operationId: deleteReviewThreadGroup parameters: - name: exerciseId in: path required: true schema: {type: integer, format: int64} - name: groupId in: path required: true schema: {type: integer, format: int64} responses: '200': {description: OK} /api/exercise/exercises/{exerciseId}/review-threads/{threadId}/comments: post: tags: [exercise-review] operationId: createUserComment parameters: - name: exerciseId in: path required: true schema: {type: integer, format: int64} - name: threadId in: path required: true schema: {type: integer, format: int64} requestBody: content: application/json: schema: {$ref: '#/components/schemas/UserCommentContentDTO'} required: true responses: '201': description: Created content: application/json: schema: {$ref: '#/components/schemas/CommentDTO'} /api/exercise/exercises/{exerciseId}/review-threads/{threadId}/resolved: put: tags: [exercise-review] operationId: updateReviewThreadResolvedState parameters: - name: exerciseId in: path required: true schema: {type: integer, format: int64} - name: threadId in: path required: true schema: {type: integer, format: int64} requestBody: content: application/json: schema: {$ref: '#/components/schemas/UpdateThreadResolvedStateDTO'} required: true responses: '200': description: OK content: application/json: schema: {$ref: '#/components/schemas/CommentThreadDTO'} /api/exercise/exercises/{exerciseId}/review-comments/{commentId}: put: tags: [exercise-review] operationId: updateUserCommentContent parameters: - name: exerciseId in: path required: true schema: {type: integer, format: int64} - name: commentId in: path required: true schema: {type: integer, format: int64} requestBody: content: application/json: schema: {$ref: '#/components/schemas/UserCommentContentDTO'} required: true responses: '200': description: OK content: application/json: schema: {$ref: '#/components/schemas/CommentDTO'} delete: tags: [exercise-review] operationId: deleteReviewComment parameters: - name: exerciseId in: path required: true schema: {type: integer, format: int64} - name: commentId in: path required: true schema: {type: integer, format: int64} responses: '200': {description: OK} components: schemas: TutorialGroup: type: object properties: id: {type: integer, format: int64} title: {type: string, maxLength: 19, minLength: 1} teachingAssistant: {$ref: '#/components/schemas/TeachingAssistant'} additionalInformation: {type: string} capacity: {type: integer, format: int32} isOnline: {type: boolean} language: {type: string} campus: {type: string} TutorialGroupStatus: type: object properties: status_explanation: {type: string} ProblemStatementGenerationResponse: type: object description: Response containing generated problem statement properties: draftProblemStatement: {type: string, description: Draft problem statement text} error: {type: string, description: Error message if generation failed} CodeGenerationRequest: type: object properties: repositoryType: type: string enum: [exercise, solution, tests, auxiliary, user] required: [repositoryType] TutorialGroupDetailSession: type: object properties: start: {type: string, format: date-time} end: {type: string, format: date-time} location: {type: string} isCancelled: {type: boolean} locationChanged: {type: boolean} timeChanged: {type: boolean} dateChanged: {type: boolean} attendanceCount: {type: integer, format: int32} required: [end, location, start] CodeGenerationJobStart: type: object properties: jobId: {type: string} ConsistencyIssue: type: object description: Individual consistency issue details properties: severity: type: string description: Severity of the issue enum: [LOW, MEDIUM, HIGH] example: HIGH category: type: string description: Category of the issue enum: [METHOD_RETURN_TYPE_MISMATCH, METHOD_PARAMETER_MISMATCH, CONSTRUCTOR_PARAMETER_MISMATCH, ATTRIBUTE_TYPE_MISMATCH, VISIBILITY_MISMATCH, IDENTIFIER_NAMING_INCONSISTENCY] example: METHOD_RETURN_TYPE_MISMATCH description: {type: string, description: Detailed description of the issue, example: Problem statement does not match test cases} suggestedFix: {type: string, description: Suggested fix for the issue, example: Update problem statement to clarify expected behavior} relatedLocations: type: array description: Related locations across artifacts items: {$ref: '#/components/schemas/ArtifactLocation'} required: [category, description, relatedLocations, severity, suggestedFix] ProblemStatementRewriteRequest: type: object description: Request to rewrite a problem statement properties: problemStatementText: {type: string, description: Original problem statement text to be improved, minLength: 1} required: [problemStatementText] TutorialGroupDetailGroup: type: object properties: id: {type: integer, format: int64} title: {type: string} language: {type: string} isOnline: {type: boolean} teachingAssistantName: {type: string} teachingAssistantLogin: {type: string} teachingAssistantImageUrl: {type: string} capacity: {type: integer, format: int32} campus: {type: string} groupChannelId: {type: integer, format: int64} tutorChatId: {type: integer, format: int64} sessions: type: array items: {$ref: '#/components/schemas/TutorialGroupDetailSession'} required: [language, sessions, teachingAssistantLogin, teachingAssistantName, title] ProblemStatementGenerationRequest: type: object description: Request to generate a problem statement properties: userPrompt: {type: string, description: User prompt describing the problem statement requirements, maxLength: 1000, minLength: 0} required: [userPrompt] ProblemStatementRewriteResponse: type: object description: Response containing rewritten problem statement properties: rewrittenText: {type: string, description: Improved problem statement text} improved: {type: boolean, description: Whether the text was actually improved, example: true} required: [improved, rewrittenText] Channel: type: object properties: type: {type: string} id: {type: integer, format: int64} creationDate: {type: string, format: date-time} lastMessageDate: {type: string, format: date-time} creator: {$ref: '#/components/schemas/ConversationUser'} lastReadDate: {type: string, format: date-time} unreadMessagesCount: {type: integer, format: int64} isFavorite: {type: boolean} isHidden: {type: boolean} isMuted: {type: boolean} isCreator: {type: boolean} isMember: {type: boolean} numberOfMembers: {type: integer, format: int32} name: {type: string} description: {type: string} topic: {type: string} isPublic: {type: boolean} isAnnouncementChannel: {type: boolean} isArchived: {type: boolean} isCourseWide: {type: boolean} hasChannelModerationRights: {type: boolean} isChannelModerator: {type: boolean} tutorialGroupId: {type: integer, format: int64} tutorialGroupTitle: {type: string} subType: type: string enum: [general, exercise, lecture, exam, feedbackDiscussion] subTypeReferenceId: {type: integer, format: int64} subTypeWithReferenceFromChannel: {$ref: '#/components/schemas/Channel', writeOnly: true} TutorialGroupRegistrationImport: type: object properties: title: {type: string} student: {$ref: '#/components/schemas/Student'} importSuccessful: {type: boolean} error: type: string enum: [NO_TITLE, NO_USER_FOUND, MULTIPLE_REGISTRATIONS] campus: {type: string} capacity: {type: integer, format: int32} language: {type: string} additionalInformation: {type: string} isOnline: {type: boolean} Student: type: object properties: login: {type: string, maxLength: 50, minLength: 0} firstName: {type: string, maxLength: 50, minLength: 0} lastName: {type: string, maxLength: 50, minLength: 0} registrationNumber: {type: string, maxLength: 10, minLength: 0} email: {type: string, format: email, maxLength: 100, minLength: 0} TutorialGroupUpdate: type: object properties: tutorialGroup: {$ref: '#/components/schemas/TutorialGroup'} notificationText: {type: string, maxLength: 1000, minLength: 1} updateTutorialGroupChannelName: {type: boolean} required: [tutorialGroup] ExamSeat: type: object properties: name: {type: string} condition: type: string enum: [USABLE, NO_TABLE, DEFECT, WHEELCHAIR] x: {type: number, format: double} y: {type: number, format: double} required: [condition, name] ConsistencyCheckResponse: type: object description: Response containing consistency check results properties: issues: type: array description: List of consistency issues found items: {$ref: '#/components/schemas/ConsistencyIssue'} required: [issues] TeachingAssistant: type: object properties: login: {type: string} TutorialGroupFreePeriodRequest: type: object properties: startDate: {type: string, format: date-time} endDate: {type: string, format: date-time} reason: {type: string} required: [endDate, startDate] ArtifactLocation: type: object description: Location information for artifacts properties: type: type: string description: Type of artifact enum: [PROBLEM_STATEMENT, TEMPLATE_REPOSITORY, SOLUTION_REPOSITORY, TESTS_REPOSITORY] example: PROBLEM_STATEMENT filePath: {type: string, description: 'Path to file, empty or problem_statement.md for problem statement', example: src/main/java/Main.java} startLine: {type: integer, format: int32, description: Start line number (1-based), minimum: 1} endLine: {type: integer, format: int32, description: End line number (1-based), minimum: 1} required: [endLine, filePath, startLine, type] RewriteFaqResponse: type: object description: Response containing rewritten FAQ properties: rewrittenText: {type: string} inconsistencies: type: array items: {type: string} suggestions: type: array items: {type: string} improvement: {type: string} TutorialGroupExport: type: object properties: id: {type: integer, format: int64} title: {type: string} dayOfWeek: {type: string} startTime: {type: string} endTime: {type: string} location: {type: string} campus: {type: string} language: {type: string} additionalInformation: {type: string} capacity: {type: integer, format: int32} isOnline: {type: boolean} students: type: array items: {$ref: '#/components/schemas/StudentExport'} RewriteFaqRequest: type: object description: Request to rewrite a FAQ properties: faqText: {type: string} required: [faqText] ConversationUser: type: object properties: id: {type: integer, format: int64} login: {type: string} name: {type: string} firstName: {type: string} lastName: {type: string} imageUrl: {type: string} isInstructor: {type: boolean} isEditor: {type: boolean} isTeachingAssistant: {type: boolean} isStudent: {type: boolean} isChannelModerator: {type: boolean} isRequestingUser: {type: boolean} TutorialGroupSessionRequest: type: object properties: date: {type: string, format: date} startTime: {type: string} endTime: {type: string} location: {type: string, maxLength: 2000, minLength: 1} StudentExport: type: object properties: registrationNumber: {type: string} firstName: {type: string} lastName: {type: string} CodeGenerationRequestDTO: type: object description: Request DTO for code generation properties: repositoryType: type: string description: Type of repository to generate code for enum: [TEMPLATE, SOLUTION, TESTS] example: SOLUTION CommentThreadLocationType: type: string description: Location type of a review comment thread enum: [PROBLEM_STATEMENT, TEMPLATE_REPO, SOLUTION_REPO, TEST_REPO, AUXILIARY_REPO] CommentType: type: string description: Type of review comment enum: [USER, CONSISTENCY_CHECK] InlineCodeChangeDTO: type: object description: Inline code change suggestion that can be applied to a specific line range properties: startLine: {type: integer, format: int32, description: First line number (inclusive) of the replacement range} endLine: {type: integer, format: int32, description: Last line number (inclusive) of the replacement range} expectedCode: {type: string, description: Code expected in the replacement range before applying the change} replacementCode: {type: string, description: Code that replaces the expected code within the range} applied: {type: boolean, description: Whether the change has been applied} UserCommentContentDTO: type: object description: Content for a user-provided review comment properties: text: {type: string, description: Comment text supplied by the reviewer} required: [text] ConsistencyIssueCommentContentDTO: type: object description: Content describing a detected consistency issue in a review properties: contentType: type: string enum: [CONSISTENCY_CHECK] severity: type: string description: Severity level assigned to the issue enum: [LOW, MEDIUM, HIGH] category: type: string description: Category of the consistency issue enum: [METHOD_RETURN_TYPE_MISMATCH, METHOD_PARAMETER_MISMATCH, CONSTRUCTOR_PARAMETER_MISMATCH, ATTRIBUTE_TYPE_MISMATCH, VISIBILITY_MISMATCH, IDENTIFIER_NAMING_INCONSISTENCY] text: {type: string, description: Human-readable description of the issue} suggestedFix: allOf: - {$ref: '#/components/schemas/InlineCodeChangeDTO'} nullable: true description: Inline code change suggestion, if applicable required: [category, contentType, severity, text] CommentContentDTO: description: Base type for review comment content. Discriminator is contentType. oneOf: - {$ref: '#/components/schemas/UserCommentContentDTO'} - {$ref: '#/components/schemas/ConsistencyIssueCommentContentDTO'} CreateCommentThreadDTO: type: object description: Request payload to create a new comment thread properties: targetType: {$ref: '#/components/schemas/CommentThreadLocationType'} auxiliaryRepositoryId: {type: integer, format: int64, description: Identifier of the auxiliary repository, if applicable} initialFilePath: {type: string, description: Initial file path captured at thread creation} initialLineNumber: {type: integer, format: int32, description: Initial line number captured at thread creation, minimum: 1} initialComment: {$ref: '#/components/schemas/UserCommentContentDTO'} required: [initialComment, initialLineNumber, targetType] CreateCommentThreadGroupDTO: type: object description: Request payload to create a new comment thread group properties: threadIds: type: array description: Thread ids to associate with the new group items: {type: integer, format: int64} minItems: 2 required: [threadIds] UpdateThreadResolvedStateDTO: type: object description: Request payload to update the resolved state of a thread properties: resolved: {type: boolean, description: Whether the thread is resolved} required: [resolved] CommentDTO: type: object description: DTO representing a review comment properties: id: {type: integer, format: int64, description: Comment identifier} threadId: {type: integer, format: int64, description: Identifier of the owning comment thread} authorName: {type: string, description: Display name of the author, if available} type: {$ref: '#/components/schemas/CommentType'} content: {$ref: '#/components/schemas/CommentContentDTO'} initialVersionId: {type: integer, format: int64, description: Identifier of the initial exercise version, if available} initialCommitSha: {type: string, description: Initial commit SHA for repository-based comments, if available} createdDate: {type: string, format: date-time, description: Creation timestamp} lastModifiedDate: {type: string, format: date-time, description: Last modification timestamp} required: [content, createdDate, id, threadId, type] CommentThreadDTO: type: object description: DTO representing a review comment thread properties: id: {type: integer, format: int64, description: Thread identifier} groupId: {type: integer, format: int64, description: Grouping identifier for related threads} exerciseId: {type: integer, format: int64, description: Identifier of the owning exercise} targetType: {$ref: '#/components/schemas/CommentThreadLocationType'} auxiliaryRepositoryId: {type: integer, format: int64, description: Identifier of the auxiliary repository, if applicable} initialVersionId: {type: integer, format: int64, description: Identifier of the initial exercise version, if available} initialCommitSha: {type: string, description: Initial commit SHA for repository-based threads, if available} filePath: {type: string, description: Current file path for repository-based threads} initialFilePath: {type: string, description: Initial file path captured at thread creation} lineNumber: {type: integer, format: int32, description: Current line number for repository-based threads, minimum: 1} initialLineNumber: {type: integer, format: int32, description: Initial line number captured at thread creation, minimum: 1} outdated: {type: boolean, description: Whether the thread is outdated} resolved: {type: boolean, description: Whether the thread is resolved} comments: type: array description: Comments belonging to the thread items: {$ref: '#/components/schemas/CommentDTO'} required: [comments, exerciseId, id, initialLineNumber, outdated, resolved, targetType] CommentThreadGroupDTO: type: object description: DTO representing a comment thread group properties: id: {type: integer, format: int64, description: Group identifier} exerciseId: {type: integer, format: int64, description: Identifier of the owning exercise} threadIds: type: array description: Thread identifiers associated with the group items: {type: integer, format: int64} required: [exerciseId, id, threadIds]