feat: improve operations diagnostics and channel management
This commit is contained in:
@@ -68,6 +68,29 @@ describe('DeletionGovernanceService', () => {
|
||||
]));
|
||||
});
|
||||
|
||||
it('does not classify approved or abandoned report history as unfinished', async () => {
|
||||
const { service, prisma } = setup();
|
||||
prisma.smsSignature.findFirst.mockResolvedValue({
|
||||
id: 'signature-1', name: '示例签名', auditStatus: 'approved', updatedAt: now,
|
||||
tenant: { name: '示例企业' }, application: { name: '验证码应用' },
|
||||
templates: [], drainageItems: [], reportTasks: [],
|
||||
});
|
||||
|
||||
const result = await service.preflight('signature', 'signature-1', 'tenant-1');
|
||||
|
||||
expect(prisma.smsSignature.findFirst).toHaveBeenCalledWith(expect.objectContaining({
|
||||
include: expect.objectContaining({
|
||||
reportTasks: expect.objectContaining({
|
||||
where: { status: { notIn: expect.arrayContaining(['approved', 'abandoned']) } },
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
expect(result.dependencies).toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ kind: 'report_tasks', count: 0 }),
|
||||
]));
|
||||
expect(result.allowedActions).toEqual(['delete']);
|
||||
});
|
||||
|
||||
it('requires version, idempotency key and a meaningful reason', async () => {
|
||||
const { service } = setup();
|
||||
await expect(service.delete('template', 'template-1', {})).rejects.toBeInstanceOf(BadRequestException);
|
||||
|
||||
@@ -13,6 +13,10 @@ export type DeleteTargetDto = {
|
||||
|
||||
type Dependency = { kind: string; label: string; count: number; items: string[] };
|
||||
|
||||
// Report tasks use more terminal values than generic send tasks. Keep this explicit so
|
||||
// completed approval and deliberately abandoned history do not block signature deletion.
|
||||
const TERMINAL_REPORT_TASK_STATUSES = ['approved', 'completed', 'failed', 'cancelled', 'rejected', 'abandoned', 'partial', 'partial_success'];
|
||||
|
||||
export type DeletionPreflight = {
|
||||
type: DeletionTargetType;
|
||||
id: string;
|
||||
@@ -114,7 +118,7 @@ export class DeletionGovernanceService {
|
||||
tenant: { select: { name: true } }, application: { select: { name: true } },
|
||||
templates: { where: { auditStatus: { not: 'deleted' } }, select: { id: true, name: true } },
|
||||
drainageItems: { where: { auditStatus: { not: 'deleted' } }, select: { id: true, siteName: true } },
|
||||
reportTasks: { where: { status: { notIn: ['completed', 'failed', 'cancelled', 'rejected'] } }, select: { id: true, status: true } },
|
||||
reportTasks: { where: { status: { notIn: TERMINAL_REPORT_TASK_STATUSES } }, select: { id: true, status: true } },
|
||||
},
|
||||
});
|
||||
if (!item) throw new NotFoundException('签名不存在或无权访问');
|
||||
|
||||
Reference in New Issue
Block a user