import { BadRequestException, Body, Controller, Delete, Get, HttpCode, Param, ParseUUIDPipe, Patch, Post, Query, StreamableFile, UploadedFile, UseInterceptors, } from '@nestjs/common'; import { FileInterceptor } from '@nestjs/platform-express'; import { DOCUMENT_MAX_BYTES, DocumentCorpusUpdateSchema, type DocumentCorpusUpdate, } from '@siop/shared'; import { AuthenticatedUser, CurrentUser, } from '../auth/current-user.decorator'; import { ZodValidationPipe } from '../common/zod-validation.pipe'; import { RequirePermission } from '../permissions/require-permission.decorator'; import { DocumentsService } from './documents.service'; @Controller('documents') export class DocumentsController { constructor(private readonly documents: DocumentsService) {} /** Bibliothèque interne — authentification seule (les cartes « Documents » * des fiches la consomment). */ @Get() list( @Query('assetId') assetId?: string, @Query('workOrderId') workOrderId?: string, @Query('kind') kind?: string, ) { return this.documents.list({ assetId, workOrderId, kind }); } @Post() @UseInterceptors( FileInterceptor('file', { limits: { fileSize: DOCUMENT_MAX_BYTES } }), ) upload( @UploadedFile() file: Express.Multer.File | undefined, @Body() body: { kind?: string; assetId?: string; workOrderId?: string }, @CurrentUser() user: AuthenticatedUser, ) { if (!file) throw new BadRequestException('Aucun fichier reçu (champ « file »)'); return this.documents.upload( { buffer: file.buffer, originalName: file.originalname, contentType: file.mimetype, size: file.size, kind: body.kind ?? 'OTHER', assetId: body.assetId || undefined, workOrderId: body.workOrderId || undefined, }, user, ); } @Get(':id/download') async download(@Param('id', ParseUUIDPipe) id: string): Promise { const { stream, fileName, contentType } = await this.documents.download(id); return new StreamableFile(stream as never, { type: contentType, disposition: `attachment; filename*=UTF-8''${encodeURIComponent(fileName)}`, }); } /** Corpus IA (D3) : réservé aux gestionnaires du référentiel. */ @Patch(':id/corpus') @RequirePermission('ASSETS', 'edit') setCorpus( @Param('id', ParseUUIDPipe) id: string, @Body(new ZodValidationPipe(DocumentCorpusUpdateSchema)) body: DocumentCorpusUpdate, ) { return this.documents.setCorpus(id, body.inCorpus); } @Delete(':id') @HttpCode(204) remove(@Param('id', ParseUUIDPipe) id: string, @CurrentUser() user: AuthenticatedUser) { return this.documents.remove(id, user); } }