129 lines
4.8 KiB
TypeScript
129 lines
4.8 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
Get,
|
|
Param,
|
|
ParseUUIDPipe,
|
|
Patch,
|
|
Post,
|
|
Req,
|
|
Res,
|
|
UploadedFile,
|
|
UploadedFiles,
|
|
UseInterceptors,
|
|
} from '@nestjs/common';
|
|
import { FileInterceptor, FilesInterceptor } from '@nestjs/platform-express';
|
|
import type { Response } from 'express';
|
|
import { CurrentAuth } from '../auth/decorators/current-auth.decorator';
|
|
import { RequirePermissions } from '../authorization/decorators/require-permissions.decorator';
|
|
import type { AuthPrincipal, RequestWithContext } from '../common/http/request-context';
|
|
import { CreateInspectionReportFollowUpDto } from './dto/create-inspection-report-follow-up.dto';
|
|
import { OfficializeInspectionReportGedoDto } from './dto/officialize-inspection-report-gedo.dto';
|
|
import { UpdateInspectionReportContentDto } from './dto/update-inspection-report-content.dto';
|
|
import {
|
|
MAX_REPORT_DOSSIER_PDF_BYTES,
|
|
type UploadedReportDossierFile,
|
|
} from './inspection-report-dossier-file';
|
|
import { InspectionReportDossierService } from './inspection-report-dossier.service';
|
|
|
|
@Controller('inspection-reports/:reportId/dossier')
|
|
export class InspectionReportDossierController {
|
|
constructor(private readonly dossier: InspectionReportDossierService) {}
|
|
|
|
@Get()
|
|
@RequirePermissions('inspection_reports.read')
|
|
get(@Param('reportId', new ParseUUIDPipe({ version: '4' })) reportId: string) {
|
|
return this.dossier.get(reportId);
|
|
}
|
|
|
|
@Patch('content')
|
|
@RequirePermissions('inspection_reports.edit')
|
|
updateContent(
|
|
@Param('reportId', new ParseUUIDPipe({ version: '4' })) reportId: string,
|
|
@Body() dto: UpdateInspectionReportContentDto,
|
|
@CurrentAuth() principal: AuthPrincipal,
|
|
@Req() request: RequestWithContext,
|
|
) {
|
|
return this.dossier.updateContent(reportId, dto, principal, request);
|
|
}
|
|
|
|
@Post('gedo')
|
|
@RequirePermissions('inspection_reports.officialize')
|
|
@UseInterceptors(FileInterceptor('file', {
|
|
limits: { fileSize: MAX_REPORT_DOSSIER_PDF_BYTES, files: 1 },
|
|
}))
|
|
officializeGedo(
|
|
@Param('reportId', new ParseUUIDPipe({ version: '4' })) reportId: string,
|
|
@Body() dto: OfficializeInspectionReportGedoDto,
|
|
@UploadedFile() file: UploadedReportDossierFile | undefined,
|
|
@CurrentAuth() principal: AuthPrincipal,
|
|
@Req() request: RequestWithContext,
|
|
) {
|
|
return this.dossier.officializeGedo(reportId, dto, file, principal, request);
|
|
}
|
|
|
|
@Get('gedo/pdf')
|
|
@RequirePermissions('inspection_reports.read')
|
|
async gedoPdf(
|
|
@Param('reportId', new ParseUUIDPipe({ version: '4' })) reportId: string,
|
|
@Res() response: Response,
|
|
): Promise<void> {
|
|
const content = await this.dossier.gedoPdfContent(reportId);
|
|
response.setHeader('Content-Type', 'application/pdf');
|
|
response.setHeader('Content-Disposition', `attachment; filename="${content.originalName.replaceAll('"', '')}"`);
|
|
response.setHeader('Cache-Control', 'private, no-store');
|
|
response.setHeader('X-Content-Type-Options', 'nosniff');
|
|
await new Promise<void>((resolveSend, rejectSend) => {
|
|
response.sendFile(content.filePath, (error) => {
|
|
if (error) rejectSend(error);
|
|
else resolveSend();
|
|
});
|
|
});
|
|
}
|
|
|
|
@Get('follow-ups')
|
|
@RequirePermissions('inspection_reports.read')
|
|
followUps(@Param('reportId', new ParseUUIDPipe({ version: '4' })) reportId: string) {
|
|
return this.dossier.listFollowUps(reportId);
|
|
}
|
|
|
|
@Post('follow-ups')
|
|
@RequirePermissions('inspection_reports.follow_up')
|
|
@UseInterceptors(FilesInterceptor('files', 10, {
|
|
limits: { fileSize: MAX_REPORT_DOSSIER_PDF_BYTES, files: 10 },
|
|
}))
|
|
createFollowUp(
|
|
@Param('reportId', new ParseUUIDPipe({ version: '4' })) reportId: string,
|
|
@Body() dto: CreateInspectionReportFollowUpDto,
|
|
@UploadedFiles() files: UploadedReportDossierFile[] | undefined,
|
|
@CurrentAuth() principal: AuthPrincipal,
|
|
@Req() request: RequestWithContext,
|
|
) {
|
|
return this.dossier.createFollowUp(reportId, dto, files ?? [], principal, request);
|
|
}
|
|
}
|
|
|
|
@Controller('inspection-report-follow-up-files')
|
|
export class InspectionReportFollowUpFileController {
|
|
constructor(private readonly dossier: InspectionReportDossierService) {}
|
|
|
|
@Get(':fileId/content')
|
|
@RequirePermissions('inspection_reports.read')
|
|
async content(
|
|
@Param('fileId', new ParseUUIDPipe({ version: '4' })) fileId: string,
|
|
@Res() response: Response,
|
|
): Promise<void> {
|
|
const content = await this.dossier.followUpFileContent(fileId);
|
|
response.setHeader('Content-Type', 'application/pdf');
|
|
response.setHeader('Content-Disposition', `attachment; filename="${content.originalName.replaceAll('"', '')}"`);
|
|
response.setHeader('Cache-Control', 'private, no-store');
|
|
response.setHeader('X-Content-Type-Options', 'nosniff');
|
|
await new Promise<void>((resolveSend, rejectSend) => {
|
|
response.sendFile(content.filePath, (error) => {
|
|
if (error) rejectSend(error);
|
|
else resolveSend();
|
|
});
|
|
});
|
|
}
|
|
}
|