feat: harden platform workflows and UI governance

This commit is contained in:
hectorzhao
2026-07-22 14:14:55 +08:00
parent ef957f7daa
commit 0f223f7f91
80 changed files with 4958 additions and 764 deletions
+41
View File
@@ -0,0 +1,41 @@
import { BadRequestException, Body, Controller, Get, Param, Post, Query, Res, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ApiTags } from '@nestjs/swagger';
import { CurrentSessionUserId } from '../auth/current-session-user.decorator';
import { FilesService } from './files.service';
type UploadedMultipartFile = { originalname: string; mimetype: string; size: number; buffer: Buffer };
type DownloadResponse = { setHeader(name: string, value: number | string): void; send(content: Buffer): void };
@ApiTags('client-files')
@Controller('client/files')
export class ClientFilesController {
constructor(private readonly files: FilesService) {}
@Post('upload')
@UseInterceptors(FileInterceptor('file', { limits: { fileSize: 10 * 1024 * 1024, files: 1, fields: 4, parts: 5 } }))
upload(
@CurrentSessionUserId() userId: string | undefined,
@UploadedFile() file: UploadedMultipartFile,
@Body('purpose') purpose: string,
@Body('prefix') prefix?: string,
) {
if (!file) throw new BadRequestException('Upload file is required');
return this.files.uploadForClient(userId, { purpose, prefix }, file);
}
@Get(':id/download')
async download(
@CurrentSessionUserId() userId: string | undefined,
@Param('id') id: string,
@Query('disposition') disposition: string | undefined,
@Res() response: DownloadResponse,
) {
const { fileObject, content } = await this.files.getClientDownload(userId, id);
const mode = disposition === 'inline' ? 'inline' : 'attachment';
response.setHeader('Content-Type', fileObject.contentType || 'application/octet-stream');
response.setHeader('Content-Length', content.length);
response.setHeader('Content-Disposition', `${mode}; filename*=UTF-8''${encodeURIComponent(fileObject.fileName)}`);
response.send(content);
}
}