feat: add report material workflows and gateway safeguards
This commit is contained in:
@@ -224,9 +224,12 @@ function createPrismaMock() {
|
||||
findUnique: jest.fn().mockResolvedValue({
|
||||
id: 'dead-1',
|
||||
tenantId: 'tenant-1',
|
||||
channelId: 'channel-1',
|
||||
streamMessageId: '1710000000000-0',
|
||||
submitId: 'SUB-1',
|
||||
messageId: 'MSG-1',
|
||||
status: 'pending',
|
||||
manualRetryCount: 0,
|
||||
commandPayload: {
|
||||
schemaVersion: 'v1',
|
||||
messageType: 'SubmitCommand',
|
||||
@@ -1517,7 +1520,7 @@ describe('SendChainService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('records gateway submit dead letters and allows manual requeue', async () => {
|
||||
it('records gateway submit exceptions and safely allows manual requeue', async () => {
|
||||
const { service, prisma } = createService();
|
||||
service['publishGatewaySubmitCommand'] = jest.fn().mockResolvedValue('1710000001000-0');
|
||||
|
||||
@@ -1551,9 +1554,17 @@ describe('SendChainService', () => {
|
||||
}),
|
||||
});
|
||||
|
||||
await service.requeueGatewaySubmitDeadLetter('dead-1');
|
||||
await service.requeueGatewaySubmitDeadLetter('dead-1', {
|
||||
confirmedNotSubmitted: true,
|
||||
reason: '确认通道连接失败且运营商未收到该短信',
|
||||
operatorId: 'user-1',
|
||||
});
|
||||
|
||||
expect(service['publishGatewaySubmitCommand']).toHaveBeenCalledWith(expect.objectContaining({ submitId: 'SUB-1' }));
|
||||
expect(prisma.gatewaySubmitDeadLetter.updateMany).toHaveBeenCalledWith({
|
||||
where: { id: 'dead-1', status: 'pending' },
|
||||
data: { status: 'requeueing' },
|
||||
});
|
||||
expect(prisma.gatewaySubmitDeadLetter.update).toHaveBeenCalledWith({
|
||||
where: { id: 'dead-1' },
|
||||
data: expect.objectContaining({
|
||||
@@ -1567,10 +1578,32 @@ describe('SendChainService', () => {
|
||||
action: 'gateway.submit_dead_letter_requeue',
|
||||
resource: 'gateway_submit_dead_letter',
|
||||
resourceId: 'dead-1',
|
||||
userId: 'user-1',
|
||||
detail: expect.objectContaining({
|
||||
reason: '确认通道连接失败且运营商未收到该短信',
|
||||
confirmedNotSubmitted: true,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
it('blocks submit exception requeue when the upstream result may already be accepted', async () => {
|
||||
const { service, prisma } = createService();
|
||||
prisma.smsMessageRecord.findUnique.mockResolvedValueOnce({
|
||||
id: 'record-1',
|
||||
messageId: 'MSG-1',
|
||||
status: 'submitted',
|
||||
submitStatus: 'accepted',
|
||||
receiptStatus: null,
|
||||
});
|
||||
|
||||
await expect(service.requeueGatewaySubmitDeadLetter('dead-1', {
|
||||
confirmedNotSubmitted: true,
|
||||
reason: '尝试重新发送这条短信',
|
||||
})).rejects.toThrow('为避免重复发送,禁止重新入队');
|
||||
expect(service['publishGatewaySubmitCommand']).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('records gateway downstream recovery statuses', async () => {
|
||||
const { service, prisma } = createService();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user