R50 通知推送:dispatcher 投递服务、业务事件接入与员工推送开关
这个提交包含在:
@@ -9,12 +9,11 @@ const { resolveApplicableBudgetPoolByContext } = require("../services/budgetPool
|
||||
const { reserveBudgetForEntity, releaseReservedBudgetIfAny } = require("../services/purchaseBudget");
|
||||
const { parseWorkflowSteps, resolveActionableStep } = require("../utils/workflow");
|
||||
const { sendNotificationEmailSafe } = require("../services/email");
|
||||
const { createNotifications, resolveRecipientsForAssignee } = require("../services/notifications");
|
||||
const { createNotificationsWithRecords, resolveRecipientsForAssignee } = require("../services/notifications");
|
||||
const {
|
||||
buildPendingTaskCopy,
|
||||
buildWorkflowEntityMeta,
|
||||
} = require("../services/notifications/workflowCopy");
|
||||
const { enqueueImNotifications } = require("../services/notifications/imEnqueue");
|
||||
const { buildTravelPaymentTrack } = require("../services/travelPayments");
|
||||
const { FEATURE_FLAG_KEYS, evaluateFeatureFlag } = require("../services/featureFlags");
|
||||
const { ensureCutoverAllowed } = require("../services/cutover");
|
||||
@@ -24,6 +23,7 @@ const {
|
||||
resolveEntityPrecheck,
|
||||
} = require("../services/feeControl");
|
||||
const { NOTIFICATION_TYPES } = require("../constants/notificationTypes");
|
||||
const { flushNotificationDispatchTasks } = require("../services/notificationDispatcher");
|
||||
|
||||
const UUID_SCHEMA = z.string().uuid();
|
||||
const BOOLEAN_QUERY_SCHEMA = z.enum(["0", "1", "true", "false"]).optional();
|
||||
@@ -929,6 +929,7 @@ async function createTravelRequestsRoutes(fastify) {
|
||||
const travelRequestId = parseTravelRequestId(request.params?.id);
|
||||
let response = null;
|
||||
const emailTasks = [];
|
||||
const dispatchTasks = [];
|
||||
|
||||
await fastify.prisma.$transaction(async (tx) => {
|
||||
const travelRequest = await loadTravelRequestForUpdate(tx, travelRequestId);
|
||||
@@ -1113,7 +1114,7 @@ async function createTravelRequestsRoutes(fastify) {
|
||||
);
|
||||
const { title, body } = pendingCopy;
|
||||
|
||||
await createNotifications(tx, {
|
||||
const notifications = await createNotificationsWithRecords(tx, {
|
||||
recipientEmployeeIds: recipients,
|
||||
type: NOTIFICATION_TYPES.workflowTaskAssigned,
|
||||
title,
|
||||
@@ -1121,19 +1122,14 @@ async function createTravelRequestsRoutes(fastify) {
|
||||
targetType: "workflow_task",
|
||||
targetId: workflowTask.id,
|
||||
});
|
||||
|
||||
await enqueueImNotifications(tx, {
|
||||
config: fastify.config,
|
||||
logger: fastify.log,
|
||||
recipientEmployeeIds: recipients,
|
||||
dispatchTasks.push({
|
||||
notifications,
|
||||
type: NOTIFICATION_TYPES.workflowTaskAssigned,
|
||||
title,
|
||||
body,
|
||||
targetType: "workflow_task",
|
||||
targetId: workflowTask.id,
|
||||
targetPath: `/workflow/tasks/${workflowTask.id}`,
|
||||
entityType: "travel_request",
|
||||
entityId: travelRequestId,
|
||||
actorId: request.employee.id,
|
||||
});
|
||||
|
||||
@@ -1184,6 +1180,13 @@ async function createTravelRequestsRoutes(fastify) {
|
||||
...emailTask,
|
||||
});
|
||||
}
|
||||
await flushNotificationDispatchTasks({
|
||||
prisma: fastify.prisma,
|
||||
config: fastify.config,
|
||||
logger: fastify.log,
|
||||
requestId: request.id,
|
||||
tasks: dispatchTasks,
|
||||
});
|
||||
|
||||
return sendData(reply, request, response);
|
||||
},
|
||||
|
||||
在新工单中引用
屏蔽一个用户