Files
ihk-projekt/Smartes-Klassenzimmer-Backend/src/files/files.controller.ts
2025-12-10 20:20:39 +01:00

87 lines
3.0 KiB
TypeScript

import { Controller, Get, Post, Param, Delete, UseGuards, UploadedFile, UseInterceptors, Body, ForbiddenException, NotFoundException, Req, Res, ParseIntPipe } from '@nestjs/common';
import { FilesService } from './files.service';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname } from 'path';
import type { Response } from 'express';
import { PrismaService } from '../prisma/prisma.service';
import * as fs from 'fs';
@Controller('files')
@UseGuards(JwtAuthGuard)
export class FilesController {
constructor(
private readonly filesService: FilesService,
private readonly prisma: PrismaService
) {}
@Post('upload')
@UseInterceptors(FileInterceptor('file', {
storage: diskStorage({
destination: './uploads',
filename: (req, file, callback) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
const ext = extname(file.originalname);
callback(null, `${uniqueSuffix}${ext}`);
},
}),
}))
async uploadFile(@UploadedFile() file: Express.Multer.File, @Body('timetableEntryId') timetableEntryId: string, @Req() req: any) {
const user = req.user;
const entryId = timetableEntryId ? parseInt(timetableEntryId) : undefined;
if (!file) {
throw new NotFoundException('No file uploaded');
}
try {
if (entryId) {
// Lesson Upload
const lesson = await this.prisma.timetableEntry.findUnique({ where: { id: entryId } });
if (!lesson) throw new NotFoundException('Lesson not found');
if (user.role !== 'Lehrer') {
// Student uploading to lesson
if (!lesson.allowStudentUploads) {
throw new ForbiddenException('Uploads not allowed for this lesson');
}
}
} else {
// General Upload
if (user.role !== 'Lehrer') {
throw new ForbiddenException('Only teachers can upload general files');
}
}
return await this.filesService.saveFile(file, user.id, entryId);
} catch (error) {
// Cleanup file if error
if (file.path && fs.existsSync(file.path)) {
fs.unlinkSync(file.path);
}
throw error;
}
}
@Get()
async findAllGeneral() {
return this.filesService.findAllGeneral();
}
@Get('lesson/:id')
async findByLesson(@Param('id', ParseIntPipe) id: number, @Req() req: any) {
return this.filesService.findByLesson(id, req.user.id, req.user.role);
}
@Get('download/:id')
async downloadFile(@Param('id', ParseIntPipe) id: number, @Res() res: Response) {
const fileEntity = await this.filesService.getFileEntity(id);
res.download(fileEntity.path, fileEntity.filename);
}
@Delete(':id')
async deleteFile(@Param('id', ParseIntPipe) id: number, @Req() req: any) {
return this.filesService.deleteFile(id, req.user.id, req.user.role);
}
}