Files
dh-inspeccion-v2/api-v3/src/inspection-closing/inspection-closing.controller.ts
T

139 lines
5.0 KiB
TypeScript

import {
Body,
Controller,
Get,
Param,
ParseUUIDPipe,
Post,
Put,
Req,
Res,
UploadedFile,
UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } 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 { CloseInspectionActDto } from './dto/close-inspection-act.dto';
import { CreateCompanyOutcomeDto } from './dto/create-company-outcome.dto';
import { CreateInspectionSignatureDto } from './dto/create-inspection-signature.dto';
import { CreateCompanySignatureDto } from './dto/create-company-signature.dto';
import { UpsertInspectionResponsibleDto } from './dto/upsert-inspection-responsible.dto';
import { InspectionClosingService } from './inspection-closing.service';
import {
MAX_INSPECTION_SIGNATURE_BYTES,
type UploadedInspectionSignatureFile,
} from './inspection-signature-file';
@Controller('inspection-acts/:actId')
export class InspectionClosingController {
constructor(private readonly closing: InspectionClosingService) {}
@Get('closure')
@RequirePermissions('inspection_closure.read')
get(@Param('actId', new ParseUUIDPipe({ version: '4' })) actId: string) {
return this.closing.get(actId);
}
@Put('responsible')
@RequirePermissions('inspection_closure.prepare')
responsible(
@Param('actId', new ParseUUIDPipe({ version: '4' })) actId: string,
@Body() dto: UpsertInspectionResponsibleDto,
@CurrentAuth() principal: AuthPrincipal,
@Req() request: RequestWithContext,
) {
return this.closing.upsertResponsible(actId, dto, principal, request);
}
@Post('lock')
@RequirePermissions('inspection_closure.prepare')
lock(
@Param('actId', new ParseUUIDPipe({ version: '4' })) actId: string,
@CurrentAuth() principal: AuthPrincipal,
@Req() request: RequestWithContext,
) {
return this.closing.prepare(actId, principal, request);
}
@Post('signatures/inspector')
@RequirePermissions('inspection_closure.sign')
@UseInterceptors(FileInterceptor('file', {
limits: { fileSize: MAX_INSPECTION_SIGNATURE_BYTES, files: 1 },
}))
inspectorSignature(
@Param('actId', new ParseUUIDPipe({ version: '4' })) actId: string,
@Body() dto: CreateInspectionSignatureDto,
@UploadedFile() file: UploadedInspectionSignatureFile | undefined,
@CurrentAuth() principal: AuthPrincipal,
@Req() request: RequestWithContext,
) {
return this.closing.signInspector(actId, dto, file, principal, request);
}
@Post('signatures/company')
@RequirePermissions('inspection_closure.sign')
@UseInterceptors(FileInterceptor('file', {
limits: { fileSize: MAX_INSPECTION_SIGNATURE_BYTES, files: 1 },
}))
companySignature(
@Param('actId', new ParseUUIDPipe({ version: '4' })) actId: string,
@Body() dto: CreateCompanySignatureDto,
@UploadedFile() file: UploadedInspectionSignatureFile | undefined,
@CurrentAuth() principal: AuthPrincipal,
@Req() request: RequestWithContext,
) {
return this.closing.signCompany(actId, dto, file, principal, request);
}
@Post('company-outcome')
@RequirePermissions('inspection_closure.sign')
companyOutcome(
@Param('actId', new ParseUUIDPipe({ version: '4' })) actId: string,
@Body() dto: CreateCompanyOutcomeDto,
@CurrentAuth() principal: AuthPrincipal,
@Req() request: RequestWithContext,
) {
return this.closing.recordCompanyOutcome(actId, dto, principal, request);
}
@Post('seal')
@RequirePermissions('inspection_closure.close')
seal(
@Param('actId', new ParseUUIDPipe({ version: '4' })) actId: string,
@Body() dto: CloseInspectionActDto,
@CurrentAuth() principal: AuthPrincipal,
@Req() request: RequestWithContext,
) {
return this.closing.close(actId, dto, principal, request);
}
}
@Controller('inspection-act-signatures')
export class InspectionSignatureContentController {
constructor(private readonly closing: InspectionClosingService) {}
@Get(':signatureId/content')
@RequirePermissions('inspection_closure.read')
async content(
@Param('signatureId', new ParseUUIDPipe({ version: '4' })) signatureId: string,
@Res() response: Response,
): Promise<void> {
const { filePath, signature } = await this.closing.signatureContent(signatureId);
response.setHeader('Content-Type', 'image/png');
response.setHeader('Content-Length', String(signature.sizeBytes));
response.setHeader('Content-Disposition', 'inline; filename="firma.png"');
response.setHeader('Cache-Control', 'private, no-store');
response.setHeader('X-Content-Type-Options', 'nosniff');
response.setHeader('Content-Security-Policy', "sandbox; default-src 'none'");
await new Promise<void>((resolveSend, rejectSend) => {
response.sendFile(filePath, (error) => {
if (error) rejectSend(error);
else resolveSend();
});
});
}
}