Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions src/assessment/grading/grading.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { RubricsService } from './rubrics.service';
import { GradingService } from './grading.service';
import { FeedbackTemplatesService } from './feedback-templates.service';
import { Rubric } from './entities/rubric.entity';
import { SubmissionGrade } from './entities/submission-grade.entity';
import { FeedbackTemplate } from './entities/feedback-template.entity';
import { CreateRubricDto, UpdateRubricDto } from './dto/rubric.dto';
import {
AutoGradeSubmissionDto,
Expand Down Expand Up @@ -46,7 +49,8 @@ export class GradingController {

@Post('rubrics')
@ApiOperation({ summary: 'Create a new grading rubric' })
@ApiResponse({ status: 201, description: 'Rubric created' })
@ApiResponse({ status: 201, description: 'Rubric created', type: Rubric })
@ApiResponse({ status: 400, description: 'Bad Request - invalid rubric data' })
createRubric(@Body() dto: CreateRubricDto, @Request() req: any) {
return this.rubrics.create(dto, req.user?.id);
}
Expand All @@ -56,6 +60,7 @@ export class GradingController {
@ApiQuery({ name: 'mine', required: false, type: String, description: 'Filter to own rubrics' })
@ApiQuery({ name: 'page', required: false, type: Number, example: 1 })
@ApiQuery({ name: 'limit', required: false, type: Number, example: 10 })
@ApiResponse({ status: 200, description: 'List of rubrics returned' })
listRubrics(
@Query('mine') mine: string | undefined,
@Query('page') page?: number,
Expand All @@ -71,19 +76,26 @@ export class GradingController {

@Get('rubrics/:id')
@ApiOperation({ summary: 'Get a rubric with its criteria and levels' })
@ApiResponse({ status: 200, description: 'Rubric retrieved successfully', type: Rubric })
@ApiResponse({ status: 404, description: 'Rubric not found' })
getRubric(@Param('id') id: string) {
return this.rubrics.findOne(id);
}

@Patch('rubrics/:id')
@ApiOperation({ summary: 'Update rubric metadata' })
@ApiResponse({ status: 200, description: 'Rubric updated successfully', type: Rubric })
@ApiResponse({ status: 400, description: 'Bad Request - invalid update data' })
@ApiResponse({ status: 404, description: 'Rubric not found' })
updateRubric(@Param('id') id: string, @Body() dto: UpdateRubricDto, @Request() req: any) {
return this.rubrics.update(id, dto, req.user?.id);
}

@Delete('rubrics/:id')
@HttpCode(HttpStatus.NO_CONTENT)
@ApiOperation({ summary: 'Soft-delete a rubric' })
@ApiResponse({ status: 204, description: 'Rubric successfully deleted' })
@ApiResponse({ status: 404, description: 'Rubric not found' })
deleteRubric(@Param('id') id: string, @Request() req: any) {
return this.rubrics.remove(id, req.user?.id);
}
Expand All @@ -98,7 +110,9 @@ export class GradingController {
'Provide one criterion score per rubric criterion. Each entry may use ' +
'`levelId` to pick a predefined level, or `points` to award a custom value (capped at criterion maxPoints).',
})
@ApiResponse({ status: 200, description: 'Submission graded' })
@ApiResponse({ status: 200, description: 'Submission graded', type: SubmissionGrade })
@ApiResponse({ status: 400, description: 'Bad Request - invalid grading payload' })
@ApiResponse({ status: 404, description: 'Rubric or Assessment Attempt not found' })
gradeSubmission(@Body() dto: GradeSubmissionDto, @Request() req: any) {
return this.grading.gradeSubmission(dto, req.user?.id);
}
Expand All @@ -110,14 +124,17 @@ export class GradingController {
description:
'Requires the rubric to have `autoGradeEnabled=true` (every criterion has a default level).',
})
@ApiResponse({ status: 200, description: 'Submission auto-graded' })
@ApiResponse({ status: 200, description: 'Submission auto-graded', type: SubmissionGrade })
@ApiResponse({ status: 400, description: 'Rubric is not auto-grade enabled' })
@ApiResponse({ status: 404, description: 'Rubric or Assessment Attempt not found' })
autoGradeSubmission(@Body() dto: AutoGradeSubmissionDto) {
return this.grading.autoGradeSubmission(dto);
}

@Get('submissions/:attemptId/grade')
@ApiOperation({ summary: 'Get the rubric grade for an assessment attempt' })
@ApiResponse({ status: 200, description: 'Grade retrieved successfully', type: SubmissionGrade })
@ApiResponse({ status: 404, description: 'Grade not found for this attempt' })
getGrade(@Param('attemptId') attemptId: string) {
return this.grading.findByAttempt(attemptId);
}
Expand All @@ -126,6 +143,8 @@ export class GradingController {

@Post('feedback-templates')
@ApiOperation({ summary: 'Create a reusable feedback template' })
@ApiResponse({ status: 201, description: 'Feedback template created', type: FeedbackTemplate })
@ApiResponse({ status: 400, description: 'Bad Request - invalid template data' })
createTemplate(@Body() dto: CreateFeedbackTemplateDto, @Request() req: any) {
return this.feedbackTemplates.create(dto, req.user?.id);
}
Expand All @@ -135,6 +154,7 @@ export class GradingController {
@ApiQuery({ name: 'mine', required: false, type: String, description: 'Filter to own templates' })
@ApiQuery({ name: 'page', required: false, type: Number, example: 1 })
@ApiQuery({ name: 'limit', required: false, type: Number, example: 10 })
@ApiResponse({ status: 200, description: 'List of feedback templates returned' })
listTemplates(
@Query('mine') mine: string | undefined,
@Query('page') page?: number,
Expand All @@ -150,12 +170,25 @@ export class GradingController {

@Get('feedback-templates/:id')
@ApiOperation({ summary: 'Get a feedback template' })
@ApiResponse({
status: 200,
description: 'Feedback template retrieved successfully',
type: FeedbackTemplate,
})
@ApiResponse({ status: 404, description: 'Feedback template not found' })
getTemplate(@Param('id') id: string) {
return this.feedbackTemplates.findOne(id);
}

@Patch('feedback-templates/:id')
@ApiOperation({ summary: 'Update a feedback template' })
@ApiResponse({
status: 200,
description: 'Feedback template updated successfully',
type: FeedbackTemplate,
})
@ApiResponse({ status: 400, description: 'Bad Request - invalid update data' })
@ApiResponse({ status: 404, description: 'Feedback template not found' })
updateTemplate(
@Param('id') id: string,
@Body() dto: UpdateFeedbackTemplateDto,
Expand All @@ -167,6 +200,8 @@ export class GradingController {
@Delete('feedback-templates/:id')
@HttpCode(HttpStatus.NO_CONTENT)
@ApiOperation({ summary: 'Soft-delete a feedback template' })
@ApiResponse({ status: 204, description: 'Feedback template successfully deleted' })
@ApiResponse({ status: 404, description: 'Feedback template not found' })
deleteTemplate(@Param('id') id: string, @Request() req: any) {
return this.feedbackTemplates.remove(id, req.user?.id);
}
Expand Down
Loading