This commit is contained in:
phaichayon
2026-06-27 10:04:43 +07:00
parent 2ace5dbb83
commit 3fdd681dd0
29 changed files with 8593 additions and 15 deletions

View File

@@ -55,6 +55,24 @@ const EVENT_RULES: Record<string, EventRule> = {
'approval.returned': {
severity: 'warning',
recipients: [{ type: 'approval_requester' }]
},
'approval.reminder': {
severity: 'warning',
recipients: [{ type: 'approval_current_step_approvers', excludeActor: true }]
},
'approval.escalated': {
severity: 'warning',
recipients: [
{ type: 'explicit_user', excludeActor: true },
{ type: 'approval_requester' }
]
},
'approval.timeout': {
severity: 'error',
recipients: [
{ type: 'explicit_user', excludeActor: true },
{ type: 'approval_requester' }
]
}
};
@@ -77,7 +95,9 @@ function mapEventRecord(row: typeof appNotificationEvents.$inferSelect): Notific
};
}
function mapTemplateRecord(row: typeof appNotificationTemplates.$inferSelect): NotificationTemplateRecord {
function mapTemplateRecord(
row: typeof appNotificationTemplates.$inferSelect
): NotificationTemplateRecord {
return {
id: row.id,
organizationId: row.organizationId,
@@ -195,9 +215,7 @@ export async function processNotificationEvent(eventId: string) {
const recipients = [...new Set(recipientLists.flat())];
const existingRows = recipients.length
? await db
.select({
recipientUserId: appNotifications.recipientUserId
})
.select({ recipientUserId: appNotifications.recipientUserId })
.from(appNotifications)
.where(
and(
@@ -207,9 +225,10 @@ export async function processNotificationEvent(eventId: string) {
)
: [];
const existingRecipientIds = new Set(existingRows.map((row) => row.recipientUserId));
const recipientsToCreate = recipients.filter((recipientUserId) => !existingRecipientIds.has(recipientUserId));
const recipientsToCreate = recipients.filter((userId) => !existingRecipientIds.has(userId));
const createdIds: string[] = [];
for (const recipientUserId of recipientsToCreate) {
const rendered = renderNotificationTemplate(template, payload);
const notificationId = crypto.randomUUID();
@@ -250,7 +269,11 @@ export async function processNotificationEvent(eventId: string) {
entityType: 'app_notification',
entityId: notificationId,
action: 'notification_created',
afterData: { recipientUserId, eventId: event.id, eventType: event.eventType }
afterData: {
recipientUserId,
eventId: event.id,
eventType: event.eventType
}
});
}
@@ -292,7 +315,7 @@ export async function processPendingNotificationEvents() {
try {
await processNotificationEvent(row.id);
} catch {
// Errors are recorded on the event row for later inspection.
// Event failures are persisted for inspection.
}
}
}
@@ -351,7 +374,7 @@ export async function publishNotificationEvent(input: PublishNotificationEventIn
try {
await processNotificationEvent(row.id);
} catch {
// Event failures are persisted on the event row and must not block the caller.
// Event failures are recorded and must not block callers.
}
return mapEventRecord(row);