refactor: strengthen client boundaries and quality gates

This commit is contained in:
hectorzhao
2026-08-28 14:26:58 +08:00
parent 3af145abe5
commit ad27acad7e
51 changed files with 7703 additions and 697 deletions
@@ -3,7 +3,19 @@ import { ApiTags } from '@nestjs/swagger';
import { CurrentTenantId } from '../auth/current-tenant-id.decorator';
import { RequireRecentAuthentication } from '../auth/require-recent-authentication.decorator';
import { CurrentSessionUserId } from '../auth/current-session-user.decorator';
import { ClientDrainageInfoDto, ClientDrainageInfoUpdateDto, ClientSignatureMaterialDto, ClientSmsApplicationDto, ClientSmsSignatureDto, ClientSmsSignatureUpdateDto, ClientSmsTemplateDto, ClientSmsTemplateUpdateDto, ClientStatusChangeDto } from '../common/client-write.dto';
import {
ClientApplicationStatusDto,
ClientDeleteResourceDto,
ClientDrainageInfoDto,
ClientDrainageInfoUpdateDto,
ClientSecretResetDto,
ClientSignatureMaterialDto,
ClientSmsApplicationDto,
ClientSmsSignatureDto,
ClientSmsSignatureUpdateDto,
ClientSmsTemplateDto,
ClientSmsTemplateUpdateDto,
} from '../common/client-write.dto';
import { strictValidationPipe } from '../common/strict-validation.pipe';
import { DeletionGovernanceService } from '../deletion-governance/deletion-governance.service';
import { SmsConfigService } from './sms-config.service';
@@ -11,10 +23,17 @@ import { SmsConfigService } from './sms-config.service';
@ApiTags('client-sms-config')
@Controller('client')
export class ClientSmsConfigController {
constructor(private readonly smsConfig: SmsConfigService, private readonly deletions: DeletionGovernanceService) {}
constructor(
private readonly smsConfig: SmsConfigService,
private readonly deletions: DeletionGovernanceService,
) {}
@Get('applications')
listApplications(@CurrentTenantId() tenantId: string, @Query('page') page?: string, @Query('pageSize') pageSize?: string) {
listApplications(
@CurrentTenantId() tenantId: string,
@Query('page') page?: string,
@Query('pageSize') pageSize?: string,
) {
return page || pageSize
? this.smsConfig.listApplicationsPage({ tenantId, page: Number(page), pageSize: Number(pageSize) })
: this.smsConfig.listApplications(tenantId);
@@ -37,8 +56,14 @@ export class ClientSmsConfigController {
}
@Get('applications/:id/report-fields')
getApplicationReportFields(@Param('id') applicationId: string, @Query('reportType') reportType: 'signature' | 'drainage' = 'drainage', @CurrentTenantId() tenantId: string) {
return this.smsConfig.getApplication(applicationId, tenantId).then(() => this.smsConfig.getClientApplicationReportFields(applicationId, reportType));
getApplicationReportFields(
@Param('id') applicationId: string,
@Query('reportType') reportType: 'signature' | 'drainage' = 'drainage',
@CurrentTenantId() tenantId: string,
) {
return this.smsConfig
.getApplication(applicationId, tenantId)
.then(() => this.smsConfig.getClientApplicationReportFields(applicationId, reportType));
}
@Get('report-fields/common')
@@ -49,14 +74,24 @@ export class ClientSmsConfigController {
@Post('applications/:id/secret/reset')
@RequireRecentAuthentication()
@UsePipes(strictValidationPipe)
resetApplicationSecret(@Param('id') applicationId: string, @Body() body: ClientStatusChangeDto, @CurrentTenantId() tenantId: string, @CurrentSessionUserId() operatorId?: string) {
resetApplicationSecret(
@Param('id') applicationId: string,
@Body() body: ClientSecretResetDto,
@CurrentTenantId() tenantId: string,
@CurrentSessionUserId() operatorId?: string,
) {
return this.smsConfig.resetClientApplicationSecret(applicationId, { ...body, operatorId }, tenantId);
}
@Post('applications/:id/status')
@RequireRecentAuthentication()
@UsePipes(strictValidationPipe)
changeApplicationStatus(@Param('id') applicationId: string, @Body() body: ClientStatusChangeDto, @CurrentTenantId() tenantId: string, @CurrentSessionUserId() operatorId?: string) {
changeApplicationStatus(
@Param('id') applicationId: string,
@Body() body: ClientApplicationStatusDto,
@CurrentTenantId() tenantId: string,
@CurrentSessionUserId() operatorId?: string,
) {
return this.smsConfig.changeClientApplicationStatus(applicationId, { ...body, operatorId }, tenantId);
}
@@ -71,8 +106,21 @@ export class ClientSmsConfigController {
}
@Get('signatures-workspace')
getSignatureWorkspace(@CurrentTenantId() tenantId: string, @Query('keyword') keyword?: string, @Query('applicationId') applicationId?: string, @Query('status') status?: string, @Query('page') page?: string, @Query('pageSize') pageSize?: string) {
return this.smsConfig.getClientSignatureWorkspace(tenantId, { keyword, applicationId, status, page: Number(page), pageSize: Number(pageSize) });
getSignatureWorkspace(
@CurrentTenantId() tenantId: string,
@Query('keyword') keyword?: string,
@Query('applicationId') applicationId?: string,
@Query('status') status?: string,
@Query('page') page?: string,
@Query('pageSize') pageSize?: string,
) {
return this.smsConfig.getClientSignatureWorkspace(tenantId, {
keyword,
applicationId,
status,
page: Number(page),
pageSize: Number(pageSize),
});
}
@Post('signatures')
@@ -84,14 +132,22 @@ export class ClientSmsConfigController {
@Put('signatures/:id')
@UsePipes(strictValidationPipe)
async updateSignature(@Param('id') signatureId: string, @Body() body: ClientSmsSignatureUpdateDto, @CurrentTenantId() tenantId: string) {
async updateSignature(
@Param('id') signatureId: string,
@Body() body: ClientSmsSignatureUpdateDto,
@CurrentTenantId() tenantId: string,
) {
await this.smsConfig.updateClientSignature(signatureId, body, tenantId);
return this.smsConfig.getClientSignatureView(signatureId, tenantId);
}
@Post('signatures/:id/materials')
@UsePipes(strictValidationPipe)
createSignatureMaterial(@Param('id') signatureId: string, @Body() body: ClientSignatureMaterialDto, @CurrentTenantId() tenantId: string) {
createSignatureMaterial(
@Param('id') signatureId: string,
@Body() body: ClientSignatureMaterialDto,
@CurrentTenantId() tenantId: string,
) {
return this.smsConfig.createClientSignatureMaterial({ ...body, signatureId }, tenantId);
}
@@ -102,21 +158,34 @@ export class ClientSmsConfigController {
@Post('signatures/:id/drainage-infos')
@UsePipes(strictValidationPipe)
async createDrainageInfo(@Param('id') signatureId: string, @Body() body: ClientDrainageInfoDto, @CurrentTenantId() tenantId: string) {
async createDrainageInfo(
@Param('id') signatureId: string,
@Body() body: ClientDrainageInfoDto,
@CurrentTenantId() tenantId: string,
) {
const item = await this.smsConfig.createDrainageInfo(signatureId, body, {}, tenantId);
return this.smsConfig.getClientDrainageInfoView(item.id, tenantId);
}
@Put('drainage-infos/:id')
@UsePipes(strictValidationPipe)
async updateDrainageInfo(@Param('id') itemId: string, @Body() body: ClientDrainageInfoUpdateDto, @CurrentTenantId() tenantId: string) {
async updateDrainageInfo(
@Param('id') itemId: string,
@Body() body: ClientDrainageInfoUpdateDto,
@CurrentTenantId() tenantId: string,
) {
await this.smsConfig.updateDrainageInfo(itemId, body, {}, tenantId);
return this.smsConfig.getClientDrainageInfoView(itemId, tenantId);
}
@Post('drainage-infos/:id/status')
@UsePipes(strictValidationPipe)
async changeDrainageInfoStatus(@Param('id') itemId: string, @Body() body: ClientStatusChangeDto, @CurrentTenantId() tenantId: string, @CurrentSessionUserId() operatorId?: string) {
async changeDrainageInfoStatus(
@Param('id') itemId: string,
@Body() body: ClientDeleteResourceDto,
@CurrentTenantId() tenantId: string,
@CurrentSessionUserId() operatorId?: string,
) {
await this.smsConfig.changeDrainageInfoStatus(itemId, { ...body, operatorId }, tenantId);
if (body.status === 'deleted') return { id: itemId, status: 'deleted' };
return this.smsConfig.getClientDrainageInfoView(itemId, tenantId);
@@ -130,16 +199,34 @@ export class ClientSmsConfigController {
@Post('signatures/:id/status')
@UsePipes(strictValidationPipe)
async changeSignatureStatus(@Param('id') signatureId: string, @Body() body: ClientStatusChangeDto, @CurrentTenantId() tenantId: string, @CurrentSessionUserId() operatorId?: string) {
if (body.status === 'deleted') return this.deletions.delete('signature', signatureId, { ...body, operatorId }, tenantId);
async changeSignatureStatus(
@Param('id') signatureId: string,
@Body() body: ClientDeleteResourceDto,
@CurrentTenantId() tenantId: string,
@CurrentSessionUserId() operatorId?: string,
) {
if (body.status === 'deleted')
return this.deletions.delete('signature', signatureId, { ...body, operatorId }, tenantId);
await this.smsConfig.changeSignatureStatus(signatureId, { ...body, operatorId }, tenantId);
return this.smsConfig.getClientSignatureView(signatureId, tenantId);
}
@Get('templates')
listTemplates(@CurrentTenantId() tenantId: string, @Query('includeHistory') includeHistory?: string, @Query('keyword') keyword?: string, @Query('page') page?: string, @Query('pageSize') pageSize?: string) {
listTemplates(
@CurrentTenantId() tenantId: string,
@Query('includeHistory') includeHistory?: string,
@Query('keyword') keyword?: string,
@Query('page') page?: string,
@Query('pageSize') pageSize?: string,
) {
return page || pageSize
? this.smsConfig.listTemplatesPage({ tenantId, status: includeHistory === 'true' ? 'all' : 'approved', keyword, page: Number(page), pageSize: Number(pageSize) })
? this.smsConfig.listTemplatesPage({
tenantId,
status: includeHistory === 'true' ? 'all' : 'approved',
keyword,
page: Number(page),
pageSize: Number(pageSize),
})
: this.smsConfig.listClientTemplates(tenantId, includeHistory === 'true');
}
@@ -151,7 +238,11 @@ export class ClientSmsConfigController {
@Put('templates/:id')
@UsePipes(strictValidationPipe)
updateTemplate(@Param('id') templateId: string, @Body() body: ClientSmsTemplateUpdateDto, @CurrentTenantId() tenantId: string) {
updateTemplate(
@Param('id') templateId: string,
@Body() body: ClientSmsTemplateUpdateDto,
@CurrentTenantId() tenantId: string,
) {
return this.smsConfig.updateClientTemplate(templateId, body, tenantId);
}
@@ -162,8 +253,14 @@ export class ClientSmsConfigController {
@Post('templates/:id/status')
@UsePipes(strictValidationPipe)
changeTemplateStatus(@Param('id') templateId: string, @Body() body: ClientStatusChangeDto, @CurrentTenantId() tenantId: string, @CurrentSessionUserId() operatorId?: string) {
if (body.status === 'deleted') return this.deletions.delete('template', templateId, { ...body, operatorId }, tenantId);
changeTemplateStatus(
@Param('id') templateId: string,
@Body() body: ClientDeleteResourceDto,
@CurrentTenantId() tenantId: string,
@CurrentSessionUserId() operatorId?: string,
) {
if (body.status === 'deleted')
return this.deletions.delete('template', templateId, { ...body, operatorId }, tenantId);
return this.smsConfig.changeTemplateStatus(templateId, { ...body, operatorId }, tenantId);
}
}