File size: 3,961 Bytes
56e2348
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a8a7b69
56e2348
 
a8a7b69
56e2348
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343821c
56e2348
89ee94c
56e2348
 
 
 
 
 
343821c
56e2348
89ee94c
56e2348
 
 
 
 
 
 
 
89ee94c
56e2348
 
 
 
 
 
 
 
89ee94c
56e2348
 
 
 
 
 
 
 
 
 
a8a7b69
 
 
 
 
 
 
 
 
56e2348
343821c
56e2348
89ee94c
56e2348
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import {
  Controller,
  Get,
  Put,
  Patch,
  Param,
  Body,
  Query,
  UseGuards,
  Request,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiParam,
  ApiBody,
} from '@nestjs/swagger';
import { GradesService } from '../services';
import { UpdateGradeDto, GradeQueryDto, BulkPublishGradesDto } from '../dto';
import { Roles } from '../../auth/roles.decorator';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { RolesGuard } from '../../auth/guards/roles.guard';
import { RoleName } from '../../auth/entities/role.entity';

@ApiTags('📊 Grades')
@Controller('api/grades')
@UseGuards(JwtAuthGuard, RolesGuard)
@ApiBearerAuth('JWT-auth')
export class GradesController {
  constructor(private readonly gradesService: GradesService) {}

  @Get()
  @Roles(RoleName.INSTRUCTOR, RoleName.TA, RoleName.ADMIN)
  @ApiOperation({ summary: 'List grades with filters and pagination' })
  @ApiResponse({ status: 200, description: 'Paginated list of grades' })
  async findAll(@Query() query: GradeQueryDto) {
    return this.gradesService.findAll(query);
  }

  @Get('my')
  @Roles(RoleName.STUDENT)
  @ApiOperation({ summary: "Get authenticated student's own grades" })
  @ApiResponse({ status: 200, description: "Student's grades" })
  async getMyGrades(@Request() req) {
    const userId = req.user.userId || req.user.id;
    return this.gradesService.findMyGrades(userId);
  }

  @Get('transcript/:studentId')
  @Roles(RoleName.STUDENT, RoleName.TA, RoleName.ADMIN)
  @ApiOperation({ summary: 'Get student transcript' })
  @ApiParam({ name: 'studentId', description: 'Student user ID', type: Number, example: 57 })
  @ApiResponse({ status: 200, description: 'Student transcript' })
  async getTranscript(@Param('studentId') studentId: number) {
    return this.gradesService.getTranscript(studentId);
  }

  @Get('gpa/:studentId')
  @Roles(RoleName.STUDENT, RoleName.TA, RoleName.ADMIN)
  @ApiOperation({ summary: 'Calculate GPA for a student' })
  @ApiParam({ name: 'studentId', description: 'Student user ID', type: Number, example: 57 })
  @ApiResponse({ status: 200, description: 'GPA calculation result' })
  async calculateGPA(@Param('studentId') studentId: number) {
    return this.gradesService.calculateGPA(studentId);
  }

  @Get('distribution/:courseId')
  @Roles(RoleName.INSTRUCTOR, RoleName.TA, RoleName.ADMIN)
  @ApiOperation({ summary: 'Get grade distribution for a course' })
  @ApiParam({ name: 'courseId', description: 'Course ID', type: Number, example: 1 })
  @ApiResponse({ status: 200, description: 'Grade distribution by letter grade' })
  async getDistribution(@Param('courseId') courseId: number) {
    return this.gradesService.getDistribution(courseId);
  }

  @Put(':id')
  @Roles(RoleName.INSTRUCTOR, RoleName.TA)
  @ApiOperation({ summary: 'Update a grade' })
  @ApiParam({ name: 'id', description: 'Grade ID', type: Number, example: 1 })
  @ApiResponse({ status: 200, description: 'Grade updated' })
  async updateGrade(
    @Param('id') id: number,
    @Body() dto: UpdateGradeDto,
    @Request() req,
  ) {
    const graderId = req.user.userId || req.user.id;
    return this.gradesService.updateGrade(id, dto, graderId);
  }

  @Patch('bulk/finalize')
  @Roles(RoleName.INSTRUCTOR, RoleName.TA)
  @ApiOperation({ summary: 'Bulk publish/finalize grades' })
  @ApiBody({ type: BulkPublishGradesDto })
  @ApiResponse({ status: 200, description: 'Grades published in bulk' })
  async finalizeGrades(@Body() dto: BulkPublishGradesDto) {
    return this.gradesService.publishGrades(dto);
  }

  @Patch(':id/finalize')
  @Roles(RoleName.INSTRUCTOR, RoleName.TA)
  @ApiOperation({ summary: 'Publish/finalize a grade' })
  @ApiParam({ name: 'id', description: 'Grade ID', type: Number, example: 1 })
  @ApiResponse({ status: 200, description: 'Grade published' })
  async finalizeGrade(@Param('id') id: number) {
    return this.gradesService.publishGrade(id);
  }
}