feat(P19IM1-1,P19IM1-2): 新增通知渠道配置与Outbox派发

这个提交包含在:
2026-03-08 13:14:04 +08:00
父节点 43a0af0803
当前提交 f6d9f23553
共修改 13 个文件,包含 1582 行新增和 364 行删除
+41 -15
查看文件
@@ -1,11 +1,12 @@
const { pushPaidReimbursementToErp } = require("./erp");
const { pushPaidReimbursementToErp } = require('./erp');
const { sendInstantMessageByChannel } = require('../notifications/channels');
class IntegrationDispatchError extends Error {
constructor({ code, message, retryable, statusCode, response }) {
super(message || code || "integration_dispatch_failed");
this.name = "IntegrationDispatchError";
this.code = code || "integration_dispatch_failed";
this.retryable = typeof retryable === "boolean" ? retryable : true;
super(message || code || 'integration_dispatch_failed');
this.name = 'IntegrationDispatchError';
this.code = code || 'integration_dispatch_failed';
this.retryable = typeof retryable === 'boolean' ? retryable : true;
this.statusCode = Number.isFinite(statusCode) ? Number(statusCode) : null;
this.response = response ?? null;
}
@@ -21,32 +22,57 @@ function toDispatchError(result) {
});
}
async function dispatchOutboxEvent({ config, eventType, payload }) {
if (eventType === "erp.reimbursement.paid") {
async function dispatchOutboxEvent({ prisma, config, eventType, payload }) {
if (eventType === 'erp.reimbursement.paid') {
const result = await pushPaidReimbursementToErp(config, payload);
if (!result.ok) {
throw toDispatchError(result);
}
return {
channel: "erp",
channel: 'erp',
code: result.code,
response: result.response ?? null,
};
}
if (eventType === "notification.im") {
if (eventType === 'notification.im') {
const channelId = String(payload?.channelId ?? '').trim();
const channel = channelId
? await prisma.notificationChannel.findUnique({
where: { id: channelId },
select: {
id: true,
channel_type: true,
name: true,
enabled: true,
config_json: true,
template_json: true,
},
})
: null;
const result = await sendInstantMessageByChannel({
config,
channel,
payload,
});
if (!result.ok) {
throw toDispatchError(result);
}
return {
channel: "im",
code: "mock_sent",
response: {
channelType: payload.channelType,
},
channel: 'im',
code: result.code,
response: result.response ?? null,
skipped: result.skipped ?? false,
previewMessage: result.previewMessage ?? null,
};
}
throw new IntegrationDispatchError({
code: "unsupported_outbox_event",
code: 'unsupported_outbox_event',
message: `unsupported_outbox_event:${eventType}`,
retryable: false,
});