Spaces:
Sleeping
Sleeping
File size: 6,630 Bytes
1ae6d1e | 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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
Query,
Req,
UseGuards,
ParseIntPipe,
HttpCode,
HttpStatus,
} from '@nestjs/common';
import {
ApiTags,
ApiOperation,
ApiParam,
ApiBody,
ApiResponse,
ApiBearerAuth,
} from '@nestjs/swagger';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { RolesGuard } from '../../auth/guards/roles.guard';
import { Roles } from '../../auth/roles.decorator';
import { RoleName } from '../../auth/entities/role.entity';
import { ScheduleTemplatesService } from '../services/schedule-templates.service';
import {
CreateScheduleTemplateDto,
UpdateScheduleTemplateDto,
ApplyTemplateToSectionDto,
BulkApplyTemplateDto,
QueryScheduleTemplateDto,
} from '../dto';
@ApiTags('📋 Schedule Templates')
@ApiBearerAuth('JWT-auth')
@Controller('api/schedule-templates')
@UseGuards(JwtAuthGuard, RolesGuard)
export class ScheduleTemplatesController {
constructor(private readonly templatesService: ScheduleTemplatesService) {}
@Get()
@ApiOperation({
summary: 'List schedule templates',
description: `
## List Schedule Templates
Returns paginated list of schedule templates.
### Access Control
- **Authentication Required**: ✅ Yes (Bearer Token)
- **Roles**: ALL
### Visibility Rules
- **Admins/IT_Admins**: See all templates
- **Department Heads**: See university-wide and own department templates
- **Others**: See active university-wide templates only
### Query Parameters
- \`scheduleType\`: Filter by type
- \`departmentId\`: Filter by department
- \`isActive\`: Filter by active status
- \`search\`: Search in name or description
`,
})
@ApiResponse({ status: 200, description: 'Paginated list of templates' })
async findAll(@Query() query: QueryScheduleTemplateDto, @Req() req: any) {
const userId = req.user.userId || req.user.id;
const roles = this.extractRoles(req.user);
return this.templatesService.findAll(query, userId, roles);
}
@Get(':id')
@ApiOperation({
summary: 'Get template by ID',
description: 'Returns detailed information about a specific schedule template including all time slots.',
})
@ApiParam({ name: 'id', description: 'Template ID', type: Number })
@ApiResponse({ status: 200, description: 'Template details' })
@ApiResponse({ status: 404, description: 'Template not found' })
async findById(@Param('id', ParseIntPipe) id: number) {
return this.templatesService.findById(id);
}
@Post()
@Roles(RoleName.ADMIN, RoleName.IT_ADMIN, RoleName.DEPARTMENT_HEAD)
@HttpCode(HttpStatus.CREATED)
@ApiOperation({
summary: 'Create schedule template',
description: `
## Create Schedule Template
Creates a new reusable schedule template.
### Access Control
- **Roles**: ADMIN, IT_ADMIN, DEPARTMENT_HEAD
### Permissions
- **Admins**: Can create university-wide or department templates
- **Department Heads**: Can only create department templates for their department
`,
})
@ApiBody({ type: CreateScheduleTemplateDto })
@ApiResponse({ status: 201, description: 'Template created successfully' })
@ApiResponse({ status: 403, description: 'Forbidden' })
async create(@Body() dto: CreateScheduleTemplateDto, @Req() req: any) {
const userId = req.user.userId || req.user.id;
const roles = this.extractRoles(req.user);
return this.templatesService.create(dto, userId, roles);
}
@Put(':id')
@Roles(RoleName.ADMIN, RoleName.IT_ADMIN, RoleName.DEPARTMENT_HEAD)
@ApiOperation({
summary: 'Update schedule template',
description: 'Updates template metadata (not slots). To modify slots, delete and recreate.',
})
@ApiParam({ name: 'id', description: 'Template ID', type: Number })
@ApiBody({ type: UpdateScheduleTemplateDto })
@ApiResponse({ status: 200, description: 'Template updated' })
async update(
@Param('id', ParseIntPipe) id: number,
@Body() dto: UpdateScheduleTemplateDto,
@Req() req: any,
) {
const userId = req.user.userId || req.user.id;
const roles = this.extractRoles(req.user);
return this.templatesService.update(id, dto, userId, roles);
}
@Delete(':id')
@Roles(RoleName.ADMIN, RoleName.IT_ADMIN, RoleName.DEPARTMENT_HEAD)
@HttpCode(HttpStatus.OK)
@ApiOperation({
summary: 'Delete schedule template',
description: 'Deletes a schedule template. Does not affect existing course schedules created from this template.',
})
@ApiParam({ name: 'id', description: 'Template ID', type: Number })
@ApiResponse({ status: 200, description: 'Template deleted' })
async delete(@Param('id', ParseIntPipe) id: number, @Req() req: any) {
const userId = req.user.userId || req.user.id;
const roles = this.extractRoles(req.user);
return this.templatesService.delete(id, userId, roles);
}
@Post('apply')
@Roles(RoleName.ADMIN, RoleName.IT_ADMIN, RoleName.DEPARTMENT_HEAD)
@HttpCode(HttpStatus.OK)
@ApiOperation({
summary: 'Apply template to section',
description: `
## Apply Template to Course Section
Applies a schedule template to a course section. Replaces existing schedules.
### Process
1. Deletes all existing schedules for the section
2. Creates new schedules based on template slots
3. Optionally overrides building/room from template
`,
})
@ApiBody({ type: ApplyTemplateToSectionDto })
@ApiResponse({ status: 200, description: 'Template applied successfully' })
async applyToSection(@Body() dto: ApplyTemplateToSectionDto, @Req() req: any) {
const userId = req.user.userId || req.user.id;
const roles = this.extractRoles(req.user);
return this.templatesService.applyToSection(dto, userId, roles);
}
@Post('apply/bulk')
@Roles(RoleName.ADMIN, RoleName.IT_ADMIN, RoleName.DEPARTMENT_HEAD)
@HttpCode(HttpStatus.OK)
@ApiOperation({
summary: 'Bulk apply template to multiple sections',
description: `
## Bulk Apply Template
Applies a schedule template to multiple course sections at once.
### Response
Returns detailed results for each section including successes and failures.
`,
})
@ApiBody({ type: BulkApplyTemplateDto })
@ApiResponse({ status: 200, description: 'Bulk application completed' })
async bulkApply(@Body() dto: BulkApplyTemplateDto, @Req() req: any) {
const userId = req.user.userId || req.user.id;
const roles = this.extractRoles(req.user);
return this.templatesService.bulkApply(dto, userId, roles);
}
private extractRoles(user: any): string[] {
if (Array.isArray(user.roles)) {
return user.roles.map((r: any) => (typeof r === 'string' ? r : r.name || r.roleName));
}
return [];
}
}
|