@mj-biz-apps/tasks-server 0.0.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/event-handlers/TaskNotificationHandler.d.ts +6 -0
- package/dist/event-handlers/TaskNotificationHandler.d.ts.map +1 -0
- package/dist/event-handlers/TaskNotificationHandler.js +363 -0
- package/dist/event-handlers/TaskNotificationHandler.js.map +1 -0
- package/dist/generated/generated.d.ts +930 -0
- package/dist/generated/generated.d.ts.map +1 -0
- package/dist/generated/generated.js +5354 -0
- package/dist/generated/generated.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/scheduled-jobs/OverdueTaskNotificationJob.d.ts +45 -0
- package/dist/scheduled-jobs/OverdueTaskNotificationJob.d.ts.map +1 -0
- package/dist/scheduled-jobs/OverdueTaskNotificationJob.js +305 -0
- package/dist/scheduled-jobs/OverdueTaskNotificationJob.js.map +1 -0
- package/package.json +41 -7
- package/README.md +0 -45
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskNotificationHandler.d.ts","sourceRoot":"","sources":["../../src/event-handlers/TaskNotificationHandler.ts"],"names":[],"mappings":"AA6BA;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAuBlD"}
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BizAppsTasks Notification Handler
|
|
3
|
+
*
|
|
4
|
+
* Subscribes to MJGlobal entity events and creates in-app notifications
|
|
5
|
+
* (MJ: User Notifications) for key task events:
|
|
6
|
+
*
|
|
7
|
+
* - Task assigned → notify the assignee
|
|
8
|
+
* - Task completed → notify all assignees
|
|
9
|
+
* - Task status changed to Blocked → notify all assignees
|
|
10
|
+
* - Task comment created → notify all assignees except the commenter
|
|
11
|
+
* - TaskType action hooks → invoke linked MJ Actions (OnAssign, OnComplete, OnOverdue, OnPercentChange)
|
|
12
|
+
*/
|
|
13
|
+
import { BaseEntity, LogError, LogStatus, Metadata, RunView, } from '@memberjunction/core';
|
|
14
|
+
import { MJEventType, MJGlobal } from '@memberjunction/global';
|
|
15
|
+
/** Entity names we listen for */
|
|
16
|
+
const TASKS_ENTITY = 'MJ_BizApps_Tasks: Tasks';
|
|
17
|
+
const TASK_ASSIGNMENTS_ENTITY = 'MJ_BizApps_Tasks: Task Assignments';
|
|
18
|
+
const TASK_COMMENTS_ENTITY = 'MJ_BizApps_Tasks: Task Comments';
|
|
19
|
+
/**
|
|
20
|
+
* Initializes the global event subscription for task notifications.
|
|
21
|
+
* Call once at server startup from {@link LoadBizAppsTasksServer}.
|
|
22
|
+
*/
|
|
23
|
+
export function InitTaskNotificationHandler() {
|
|
24
|
+
const storeKey = '___BizAppsTasks___NotificationHandler___Subscription';
|
|
25
|
+
const store = MJGlobal.Instance.GetGlobalObjectStore();
|
|
26
|
+
// Guard against double-subscription (bundler duplication / hot-reload)
|
|
27
|
+
if (store[storeKey]) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const subscription = MJGlobal.Instance.GetEventListener(true).subscribe((event) => {
|
|
31
|
+
if (event.event === MJEventType.ComponentEvent &&
|
|
32
|
+
event.eventCode === BaseEntity.BaseEventCode) {
|
|
33
|
+
const entityEvent = event.args;
|
|
34
|
+
handleEntityEvent(entityEvent);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
store[storeKey] = subscription;
|
|
38
|
+
LogStatus('[BizAppsTasks] Notification handler initialized');
|
|
39
|
+
}
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Event Router
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
function handleEntityEvent(event) {
|
|
44
|
+
if (event.type !== 'save' || !event.baseEntity) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const entityName = event.baseEntity.EntityInfo.Name;
|
|
48
|
+
switch (entityName) {
|
|
49
|
+
case TASKS_ENTITY:
|
|
50
|
+
handleTaskSave(event).catch(logHandlerError('TaskSave'));
|
|
51
|
+
break;
|
|
52
|
+
case TASK_ASSIGNMENTS_ENTITY:
|
|
53
|
+
handleAssignmentSave(event).catch(logHandlerError('AssignmentSave'));
|
|
54
|
+
break;
|
|
55
|
+
case TASK_COMMENTS_ENTITY:
|
|
56
|
+
handleCommentSave(event).catch(logHandlerError('CommentSave'));
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function logHandlerError(handler) {
|
|
61
|
+
return (err) => {
|
|
62
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
63
|
+
LogError(`[BizAppsTasks] ${handler} notification error: ${msg}`);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// Task Notifications (status changes)
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
/**
|
|
70
|
+
* When a task is saved:
|
|
71
|
+
* - If completed → notify all assignees: "Task completed: {name}"
|
|
72
|
+
* - If blocked → notify all assignees: "Task blocked: {name}"
|
|
73
|
+
* - If newly created → no notification (assignment creation handles that)
|
|
74
|
+
*
|
|
75
|
+
* Also invokes TaskType action hooks if configured (OnComplete, OnOverdue, OnPercentChange).
|
|
76
|
+
*/
|
|
77
|
+
async function handleTaskSave(event) {
|
|
78
|
+
const task = event.baseEntity;
|
|
79
|
+
const contextUser = task.ContextCurrentUser;
|
|
80
|
+
if (!contextUser)
|
|
81
|
+
return;
|
|
82
|
+
const taskID = task.Get('ID');
|
|
83
|
+
const taskName = task.Get('Name');
|
|
84
|
+
const status = task.Get('Status');
|
|
85
|
+
// Only notify on specific status values, and only on update (not create)
|
|
86
|
+
if (event.saveSubType === 'create') {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (status === 'Completed') {
|
|
90
|
+
const userIDs = await getTaskAssigneeUserIDs(taskID, contextUser);
|
|
91
|
+
if (userIDs.length > 0) {
|
|
92
|
+
await createNotificationsForUsers(userIDs, `Task Completed: ${taskName}`, `"${taskName}" has been marked as completed.`, contextUser);
|
|
93
|
+
LogStatus(`[BizAppsTasks] Sent completion notification for "${taskName}" to ${userIDs.length} assignee(s)`);
|
|
94
|
+
}
|
|
95
|
+
// Invoke OnComplete action if configured on TaskType
|
|
96
|
+
await invokeTaskTypeAction(task, 'OnCompleteActionID', contextUser);
|
|
97
|
+
}
|
|
98
|
+
if (status === 'Blocked') {
|
|
99
|
+
const blockedReason = task.Get('BlockedReason');
|
|
100
|
+
const userIDs = await getTaskAssigneeUserIDs(taskID, contextUser);
|
|
101
|
+
if (userIDs.length > 0) {
|
|
102
|
+
const reasonStr = blockedReason ? ` Reason: ${blockedReason}` : '';
|
|
103
|
+
await createNotificationsForUsers(userIDs, `Task Blocked: ${taskName}`, `"${taskName}" has been blocked.${reasonStr}`, contextUser);
|
|
104
|
+
LogStatus(`[BizAppsTasks] Sent blocked notification for "${taskName}" to ${userIDs.length} assignee(s)`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// Assignment Notifications
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
/**
|
|
112
|
+
* When a NEW task assignment is created, notify the assignee:
|
|
113
|
+
* "You've been assigned: {task name}"
|
|
114
|
+
*
|
|
115
|
+
* Also invokes OnAssign action if configured on the task's TaskType.
|
|
116
|
+
*/
|
|
117
|
+
async function handleAssignmentSave(event) {
|
|
118
|
+
if (event.saveSubType !== 'create') {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const assignment = event.baseEntity;
|
|
122
|
+
const contextUser = assignment.ContextCurrentUser;
|
|
123
|
+
if (!contextUser)
|
|
124
|
+
return;
|
|
125
|
+
const assigneeRecordID = assignment.Get('AssigneeRecordID');
|
|
126
|
+
const taskID = assignment.Get('TaskID');
|
|
127
|
+
// Resolve the assignee's linked MJ UserID
|
|
128
|
+
const userID = await getPersonLinkedUserID(assigneeRecordID, contextUser);
|
|
129
|
+
if (!userID)
|
|
130
|
+
return;
|
|
131
|
+
// Load the task to get its name and details
|
|
132
|
+
const rv = new RunView();
|
|
133
|
+
const taskResult = await rv.RunView({
|
|
134
|
+
EntityName: TASKS_ENTITY,
|
|
135
|
+
ExtraFilter: `ID='${taskID}'`,
|
|
136
|
+
ResultType: 'simple',
|
|
137
|
+
MaxRows: 1,
|
|
138
|
+
}, contextUser);
|
|
139
|
+
const task = taskResult?.Results?.[0];
|
|
140
|
+
if (!task)
|
|
141
|
+
return;
|
|
142
|
+
const taskName = task.Name;
|
|
143
|
+
const priority = task.Priority;
|
|
144
|
+
const dueAt = task.DueAt ? formatDate(new Date(task.DueAt)) : null;
|
|
145
|
+
const dueStr = dueAt ? ` Due: ${dueAt}.` : '';
|
|
146
|
+
// Resolve role name if present
|
|
147
|
+
const roleID = assignment.Get('RoleID');
|
|
148
|
+
let roleStr = '';
|
|
149
|
+
if (roleID) {
|
|
150
|
+
const roleResult = await new RunView().RunView({
|
|
151
|
+
EntityName: 'MJ_BizApps_Tasks: Task Roles',
|
|
152
|
+
ExtraFilter: `ID='${roleID}'`,
|
|
153
|
+
ResultType: 'simple',
|
|
154
|
+
MaxRows: 1,
|
|
155
|
+
}, contextUser);
|
|
156
|
+
const roleName = roleResult?.Results?.[0]?.Name;
|
|
157
|
+
if (roleName)
|
|
158
|
+
roleStr = ` Role: ${roleName}.`;
|
|
159
|
+
}
|
|
160
|
+
await createNotificationsForUsers([userID], `Task Assigned: ${taskName}`, `You've been assigned to "${taskName}". Priority: ${priority}.${roleStr}${dueStr}`, contextUser);
|
|
161
|
+
LogStatus(`[BizAppsTasks] Sent assignment notification for "${taskName}"`);
|
|
162
|
+
// Invoke OnAssign action if configured on the task's TaskType
|
|
163
|
+
await invokeTaskTypeActionByTaskID(taskID, 'OnAssignActionID', contextUser);
|
|
164
|
+
}
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
// Comment Notifications
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
/**
|
|
169
|
+
* When a NEW comment is created on a task, notify all assignees
|
|
170
|
+
* except the comment author.
|
|
171
|
+
*/
|
|
172
|
+
async function handleCommentSave(event) {
|
|
173
|
+
if (event.saveSubType !== 'create') {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const comment = event.baseEntity;
|
|
177
|
+
const contextUser = comment.ContextCurrentUser;
|
|
178
|
+
if (!contextUser)
|
|
179
|
+
return;
|
|
180
|
+
const taskID = comment.Get('TaskID');
|
|
181
|
+
const authorPersonID = comment.Get('PersonID');
|
|
182
|
+
const content = comment.Get('Content');
|
|
183
|
+
const preview = content.length > 100 ? content.substring(0, 100) + '...' : content;
|
|
184
|
+
// Get task name
|
|
185
|
+
const rv = new RunView();
|
|
186
|
+
const taskResult = await rv.RunView({
|
|
187
|
+
EntityName: TASKS_ENTITY,
|
|
188
|
+
ExtraFilter: `ID='${taskID}'`,
|
|
189
|
+
ResultType: 'simple',
|
|
190
|
+
MaxRows: 1,
|
|
191
|
+
}, contextUser);
|
|
192
|
+
const taskName = taskResult?.Results?.[0]?.Name ?? 'a task';
|
|
193
|
+
// Get author name
|
|
194
|
+
const authorName = await getPersonName(authorPersonID, contextUser) ?? 'Someone';
|
|
195
|
+
// Get all assignee UserIDs except the author
|
|
196
|
+
const allUserIDs = await getTaskAssigneeUserIDs(taskID, contextUser);
|
|
197
|
+
const authorUserID = await getPersonLinkedUserID(authorPersonID, contextUser);
|
|
198
|
+
const notifyUserIDs = allUserIDs.filter(id => id !== authorUserID);
|
|
199
|
+
if (notifyUserIDs.length === 0)
|
|
200
|
+
return;
|
|
201
|
+
await createNotificationsForUsers(notifyUserIDs, `Comment on: ${taskName}`, `${authorName} commented: "${preview}"`, contextUser);
|
|
202
|
+
LogStatus(`[BizAppsTasks] Sent comment notification for "${taskName}" to ${notifyUserIDs.length} assignee(s)`);
|
|
203
|
+
}
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
// TaskType Action Invocation
|
|
206
|
+
// ---------------------------------------------------------------------------
|
|
207
|
+
/**
|
|
208
|
+
* Looks up the TaskType for a task entity and invokes the specified action
|
|
209
|
+
* FK column if it has a value.
|
|
210
|
+
*/
|
|
211
|
+
async function invokeTaskTypeAction(task, actionColumn, contextUser) {
|
|
212
|
+
const typeID = task.Get('TypeID');
|
|
213
|
+
if (!typeID)
|
|
214
|
+
return;
|
|
215
|
+
const rv = new RunView();
|
|
216
|
+
const typeResult = await rv.RunView({
|
|
217
|
+
EntityName: 'MJ_BizApps_Tasks: Task Types',
|
|
218
|
+
ExtraFilter: `ID='${typeID}'`,
|
|
219
|
+
ResultType: 'simple',
|
|
220
|
+
MaxRows: 1,
|
|
221
|
+
}, contextUser);
|
|
222
|
+
const taskType = typeResult?.Results?.[0];
|
|
223
|
+
if (!taskType)
|
|
224
|
+
return;
|
|
225
|
+
const actionID = taskType[actionColumn];
|
|
226
|
+
if (!actionID)
|
|
227
|
+
return;
|
|
228
|
+
try {
|
|
229
|
+
// Dynamic import to avoid hard dependency on @memberjunction/actions
|
|
230
|
+
const { ActionEngineServer } = await import('@memberjunction/actions');
|
|
231
|
+
await ActionEngineServer.Instance.Config(false, contextUser);
|
|
232
|
+
const action = ActionEngineServer.Instance.Actions.find((a) => a.ID === actionID);
|
|
233
|
+
if (!action) {
|
|
234
|
+
LogError(`[BizAppsTasks] Action ${actionID} not found for TaskType ${actionColumn}`);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
await ActionEngineServer.Instance.RunAction({
|
|
238
|
+
Action: action,
|
|
239
|
+
ContextUser: contextUser,
|
|
240
|
+
Params: [
|
|
241
|
+
{ Name: 'TaskID', Value: task.Get('ID'), Type: 'Input' },
|
|
242
|
+
{ Name: 'TaskName', Value: task.Get('Name'), Type: 'Input' },
|
|
243
|
+
{ Name: 'Status', Value: task.Get('Status'), Type: 'Input' },
|
|
244
|
+
],
|
|
245
|
+
Filters: [],
|
|
246
|
+
});
|
|
247
|
+
LogStatus(`[BizAppsTasks] Invoked ${actionColumn} action for task "${task.Get('Name')}"`);
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
251
|
+
LogError(`[BizAppsTasks] Failed to invoke ${actionColumn}: ${msg}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Convenience wrapper: loads a task by ID, then invokes a TaskType action.
|
|
256
|
+
*/
|
|
257
|
+
async function invokeTaskTypeActionByTaskID(taskID, actionColumn, contextUser) {
|
|
258
|
+
const rv = new RunView();
|
|
259
|
+
const result = await rv.RunView({
|
|
260
|
+
EntityName: TASKS_ENTITY,
|
|
261
|
+
ExtraFilter: `ID='${taskID}'`,
|
|
262
|
+
ResultType: 'entity_object',
|
|
263
|
+
MaxRows: 1,
|
|
264
|
+
}, contextUser);
|
|
265
|
+
const task = result?.Results?.[0];
|
|
266
|
+
if (task) {
|
|
267
|
+
await invokeTaskTypeAction(task, actionColumn, contextUser);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// ---------------------------------------------------------------------------
|
|
271
|
+
// Helpers
|
|
272
|
+
// ---------------------------------------------------------------------------
|
|
273
|
+
/**
|
|
274
|
+
* Returns MJ UserIDs for all people assigned to a task.
|
|
275
|
+
* Two-step: TaskAssignment → Person → LinkedUserID.
|
|
276
|
+
*/
|
|
277
|
+
async function getTaskAssigneeUserIDs(taskID, contextUser) {
|
|
278
|
+
const rv = new RunView();
|
|
279
|
+
const assignments = await rv.RunView({
|
|
280
|
+
EntityName: TASK_ASSIGNMENTS_ENTITY,
|
|
281
|
+
ExtraFilter: `TaskID='${taskID}'`,
|
|
282
|
+
ResultType: 'simple',
|
|
283
|
+
}, contextUser);
|
|
284
|
+
if (!assignments?.Success || assignments.Results.length === 0) {
|
|
285
|
+
return [];
|
|
286
|
+
}
|
|
287
|
+
const personIDs = assignments.Results.map((a) => a.AssigneeRecordID);
|
|
288
|
+
const inClause = personIDs.map((id) => `'${id}'`).join(',');
|
|
289
|
+
const people = await rv.RunView({
|
|
290
|
+
EntityName: 'MJ_BizApps_Common: People',
|
|
291
|
+
ExtraFilter: `ID IN (${inClause}) AND LinkedUserID IS NOT NULL`,
|
|
292
|
+
Fields: ['ID', 'LinkedUserID'],
|
|
293
|
+
ResultType: 'simple',
|
|
294
|
+
}, contextUser);
|
|
295
|
+
if (!people?.Success) {
|
|
296
|
+
return [];
|
|
297
|
+
}
|
|
298
|
+
return people.Results
|
|
299
|
+
.map((p) => p.LinkedUserID)
|
|
300
|
+
.filter((id) => id != null);
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Resolves a PersonID to their linked MJ UserID (if any).
|
|
304
|
+
*/
|
|
305
|
+
async function getPersonLinkedUserID(personID, contextUser) {
|
|
306
|
+
const rv = new RunView();
|
|
307
|
+
const result = await rv.RunView({
|
|
308
|
+
EntityName: 'MJ_BizApps_Common: People',
|
|
309
|
+
ExtraFilter: `ID='${personID}'`,
|
|
310
|
+
Fields: ['ID', 'LinkedUserID'],
|
|
311
|
+
ResultType: 'simple',
|
|
312
|
+
MaxRows: 1,
|
|
313
|
+
}, contextUser);
|
|
314
|
+
return result?.Results?.[0]?.LinkedUserID ?? null;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Resolves a PersonID to their display name.
|
|
318
|
+
*/
|
|
319
|
+
async function getPersonName(personID, contextUser) {
|
|
320
|
+
const rv = new RunView();
|
|
321
|
+
const result = await rv.RunView({
|
|
322
|
+
EntityName: 'MJ_BizApps_Common: People',
|
|
323
|
+
ExtraFilter: `ID='${personID}'`,
|
|
324
|
+
Fields: ['ID', 'FirstName', 'LastName'],
|
|
325
|
+
ResultType: 'simple',
|
|
326
|
+
MaxRows: 1,
|
|
327
|
+
}, contextUser);
|
|
328
|
+
const p = result?.Results?.[0];
|
|
329
|
+
return p ? `${p.FirstName} ${p.LastName}` : null;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Creates an in-app notification for each UserID in the list.
|
|
333
|
+
*/
|
|
334
|
+
async function createNotificationsForUsers(userIDs, title, message, contextUser) {
|
|
335
|
+
const md = new Metadata();
|
|
336
|
+
const saves = userIDs.map(async (userID) => {
|
|
337
|
+
const notification = await md.GetEntityObject('MJ: User Notifications', contextUser);
|
|
338
|
+
notification.NewRecord();
|
|
339
|
+
notification.Set('UserID', userID);
|
|
340
|
+
notification.Set('Title', title);
|
|
341
|
+
notification.Set('Message', message);
|
|
342
|
+
notification.Set('Unread', true);
|
|
343
|
+
const saved = await notification.Save();
|
|
344
|
+
if (!saved) {
|
|
345
|
+
LogError(`[BizAppsTasks] Failed to save notification for user ${userID}`);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
await Promise.all(saves);
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Formats a Date to a readable string like "Mar 12, 2026"
|
|
352
|
+
*/
|
|
353
|
+
function formatDate(date) {
|
|
354
|
+
if (!(date instanceof Date) || isNaN(date.getTime())) {
|
|
355
|
+
return 'TBD';
|
|
356
|
+
}
|
|
357
|
+
return date.toLocaleDateString('en-US', {
|
|
358
|
+
month: 'short',
|
|
359
|
+
day: 'numeric',
|
|
360
|
+
year: 'numeric',
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=TaskNotificationHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskNotificationHandler.js","sourceRoot":"","sources":["../../src/event-handlers/TaskNotificationHandler.ts"],"names":[],"mappings":"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"}
|