fix: harden tenant auth and quality gates

This commit is contained in:
hectorzhao
2026-08-28 11:44:16 +08:00
parent c3bf8af3e6
commit 2744690f9f
51 changed files with 1750 additions and 466 deletions
@@ -1,7 +1,9 @@
import { BadRequestException, Body, Controller, Get, Param, Post, Query } from '@nestjs/common';
import { Body, Controller, Get, Param, Post, Query, UsePipes } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { TenantId } from '../common/tenant-id.decorator';
import { ConfirmImportDto, CreateBatchTaskDto, ImportPreviewDto } from './send-chain.contracts';
import { CurrentTenantId } from '../auth/current-tenant-id.decorator';
import { CurrentSessionUserId } from '../auth/current-session-user.decorator';
import { ClientBatchTaskDto, ClientImportConfirmDto, ClientImportPreviewDto } from '../common/client-write.dto';
import { strictValidationPipe } from '../common/strict-validation.pipe';
import { SendChainService } from './send-chain.service';
@ApiTags('client-send-chain')
@@ -10,46 +12,42 @@ export class ClientSendChainController {
constructor(private readonly sendChain: SendChainService) {}
@Post('batch-tasks')
createBatchTask(@Body() body: CreateBatchTaskDto) {
return this.sendChain.createBatchTask(body);
@UsePipes(strictValidationPipe)
createBatchTask(@CurrentTenantId() tenantId: string, @CurrentSessionUserId() createdById: string | undefined, @Body() body: ClientBatchTaskDto) {
return this.sendChain.createBatchTask({ ...body, tenantId, sourceType: 'client', createdById });
}
@Post('imports/preview')
previewImport(@Body() body: ImportPreviewDto) {
return this.sendChain.previewImport(body);
@UsePipes(strictValidationPipe)
previewImport(@CurrentTenantId() tenantId: string, @Body() body: ClientImportPreviewDto) {
return this.sendChain.previewImport({ ...body, tenantId });
}
@Post('imports/confirm')
confirmImport(@Body() body: ConfirmImportDto) {
return this.sendChain.confirmImport(body);
@UsePipes(strictValidationPipe)
confirmImport(@CurrentTenantId() tenantId: string, @CurrentSessionUserId() createdById: string | undefined, @Body() body: ClientImportConfirmDto) {
return this.sendChain.confirmImport({ ...body, tenantId, sourceType: 'client', createdById });
}
@Get('batch-tasks')
listBatchTasks(@TenantId() tenantId?: string, @Query('status') status?: string, @Query('keyword') keyword?: string, @Query('applicationKeyword') applicationKeyword?: string, @Query('createdAtFrom') createdAtFrom?: string, @Query('createdAtTo') createdAtTo?: string, @Query('page') page?: string, @Query('pageSize') pageSize?: string) {
listBatchTasks(@CurrentTenantId() tenantId: string, @Query('status') status?: string, @Query('keyword') keyword?: string, @Query('applicationKeyword') applicationKeyword?: string, @Query('createdAtFrom') createdAtFrom?: string, @Query('createdAtTo') createdAtTo?: string, @Query('page') page?: string, @Query('pageSize') pageSize?: string) {
return page || pageSize
? this.sendChain.listBatchTasksPage({ tenantId: requireTenantId(tenantId), status, sourceType: 'client', keyword, applicationKeyword, createdAtFrom, createdAtTo, page: Number(page), pageSize: Number(pageSize) })
: this.sendChain.listBatchTasks(requireTenantId(tenantId), status, 'client');
? this.sendChain.listBatchTasksPage({ tenantId, status, sourceType: 'client', keyword, applicationKeyword, createdAtFrom, createdAtTo, page: Number(page), pageSize: Number(pageSize) })
: this.sendChain.listBatchTasks(tenantId, status, 'client');
}
@Get('batch-tasks/:id')
getBatchTask(@TenantId() tenantId: string | undefined, @Param('id') taskId: string) {
return this.sendChain.getBatchTask(taskId, requireTenantId(tenantId), 'client');
getBatchTask(@CurrentTenantId() tenantId: string, @Param('id') taskId: string) {
return this.sendChain.getBatchTask(taskId, tenantId, 'client');
}
@Get('batch-tasks/:id/messages')
listTaskMessages(@TenantId() tenantId: string | undefined, @Param('id') taskId: string) {
return this.sendChain.listClientTaskMessages(taskId, requireTenantId(tenantId));
listTaskMessages(@CurrentTenantId() tenantId: string, @Param('id') taskId: string) {
return this.sendChain.listClientTaskMessages(taskId, tenantId);
}
@Post('batch-tasks/:id/cancel')
cancelBatchTask(@TenantId() tenantId: string | undefined, @Param('id') taskId: string) {
return this.sendChain.cancelBatchTask(taskId, requireTenantId(tenantId), 'client');
cancelBatchTask(@CurrentTenantId() tenantId: string, @Param('id') taskId: string) {
return this.sendChain.cancelBatchTask(taskId, tenantId, 'client');
}
}
function requireTenantId(tenantId?: string) {
if (!tenantId) {
throw new BadRequestException('Tenant context is required');
}
return tenantId;
}