feat(P23IM2-1,P23IM2-2,P23IM2-3): 密钥加密持久化/遮罩读模型/企微可重试语义/迁移脚本
这个提交包含在:
@@ -487,6 +487,46 @@ describe('dispatchOutboxEvent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('maps encrypted secret decrypt failure as non-retryable IM dispatch error', async () => {
|
||||
await expect(
|
||||
dispatchOutboxEvent({
|
||||
prisma: {
|
||||
notificationChannel: {
|
||||
findUnique: vi.fn().mockResolvedValue({
|
||||
id: 'channel-6',
|
||||
channel_type: 'wecom',
|
||||
name: 'wecom-secret-bad',
|
||||
enabled: true,
|
||||
config_json: {
|
||||
mode: 'wecom_webhook',
|
||||
webhookUrl: 'https://example.com/wecom',
|
||||
secretEncrypted: 'v1:bad:payload:value',
|
||||
timeoutMs: 500,
|
||||
routing: {},
|
||||
},
|
||||
template_json: null,
|
||||
}),
|
||||
},
|
||||
},
|
||||
config: {
|
||||
imNotifierEnabled: true,
|
||||
fieldEncryptionKey: Buffer.alloc(32, 7).toString('base64'),
|
||||
},
|
||||
eventType: 'notification.im',
|
||||
payload: {
|
||||
channelId: 'channel-6',
|
||||
channelType: 'wecom',
|
||||
title: 'test',
|
||||
body: 'body',
|
||||
},
|
||||
}),
|
||||
).rejects.toMatchObject({
|
||||
name: 'IntegrationDispatchError',
|
||||
code: 'wecom_secret_decrypt_failed',
|
||||
retryable: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('throws error for unsupported event', async () => {
|
||||
await expect(
|
||||
dispatchOutboxEvent({
|
||||
|
||||
在新工单中引用
屏蔽一个用户