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