@tiledesk/tiledesk-server 2.19.12 → 2.19.14
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/CHANGELOG.md +7 -0
- package/app.js +3 -0
- package/channels/chat21/chat21WebHook.js +13 -2
- package/docs/activities-client.md +864 -0
- package/event/requestEvent.js +14 -0
- package/jobs.js +1 -0
- package/jobsManager.js +2 -0
- package/models/dataTable.js +64 -0
- package/package.json +2 -2
- package/pubmodules/activities/activityArchiver.js +699 -377
- package/pubmodules/activities/activityMessageUtil.js +336 -0
- package/pubmodules/activities/index.js +1 -1
- package/pubmodules/activities/models/activity.js +99 -2
- package/pubmodules/activities/routes/activity.js +114 -144
- package/pubmodules/messageActions/messageActionsInterceptor.js +15 -2
- package/pubmodules/queue/reconnect.js +307 -2
- package/pubmodules/rules/conciergeBot.js +7 -1
- package/pubmodules/trigger/rulesTrigger.js +33 -5
- package/routes/dataTable.js +280 -0
- package/routes/faq_kb.js +24 -1
- package/routes/kb.js +90 -2
- package/routes/project_user.js +66 -17
- package/routes/request.js +20 -8
- package/services/chatbotService.js +6 -3
- package/services/dataTableService.js +545 -0
- package/services/requestService.js +180 -27
- package/test/dataTablesRoute.test.js +844 -0
- package/test/faqkbRoute.js +1 -0
- package/test/kbRoute.js +59 -0
- package/utils/activityActorUtil.js +167 -0
- package/utils/assignmentContextUtil.js +283 -0
- package/utils/dataTableBsonUtils.js +12 -0
- package/utils/dataTableUtils.js +353 -0
- package/utils/projectUserUpdateContextUtil.js +325 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
const winston = require('../config/winston');
|
|
4
|
+
const dataTableService = require('../services/dataTableService');
|
|
5
|
+
|
|
6
|
+
function getRowPayload(body) {
|
|
7
|
+
if (body && body.data && typeof body.data === 'object' && !Array.isArray(body.data)) {
|
|
8
|
+
return body.data;
|
|
9
|
+
}
|
|
10
|
+
return body;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function isValidationError(err) {
|
|
14
|
+
if (!err || !err.message) return false;
|
|
15
|
+
const msg = err.message;
|
|
16
|
+
return msg.indexOf('does not exist') !== -1 ||
|
|
17
|
+
msg.indexOf('required') !== -1 ||
|
|
18
|
+
msg.indexOf('Invalid') !== -1 ||
|
|
19
|
+
msg.indexOf('must be') !== -1 ||
|
|
20
|
+
msg.indexOf('already exists') !== -1 ||
|
|
21
|
+
msg.indexOf('Column id') !== -1 ||
|
|
22
|
+
msg.indexOf('not provided') !== -1 ||
|
|
23
|
+
msg.indexOf('Operator') !== -1 ||
|
|
24
|
+
msg.indexOf('id_row or conditions') !== -1 ||
|
|
25
|
+
msg.indexOf('data is required') !== -1 ||
|
|
26
|
+
msg.indexOf('valid JSON') !== -1;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function handleError(res, err, action) {
|
|
30
|
+
if (err && err.message === 'TABLE_SIZE_LIMIT_EXCEEDED') {
|
|
31
|
+
return res.status(413).send({ success: false, message: 'TABLE_SIZE_LIMIT_EXCEEDED' });
|
|
32
|
+
}
|
|
33
|
+
if (isValidationError(err)) {
|
|
34
|
+
const status = err.message.indexOf('already exists') !== -1 ? 409 : 400;
|
|
35
|
+
return res.status(status).send({ success: false, message: err.message });
|
|
36
|
+
}
|
|
37
|
+
if (err.message === 'Column not found' || err.message.indexOf('Column not found:') === 0) {
|
|
38
|
+
return res.status(404).send({ success: false, message: err.message });
|
|
39
|
+
}
|
|
40
|
+
winston.error('DataTable ' + action + ': ', err);
|
|
41
|
+
return res.status(500).send({ success: false, error: 'Error ' + action });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// --- Tables ---
|
|
45
|
+
|
|
46
|
+
router.get('/', async function (req, res) {
|
|
47
|
+
try {
|
|
48
|
+
res.status(200).send(await dataTableService.listTables(req.projectid));
|
|
49
|
+
} catch (err) {
|
|
50
|
+
handleError(res, err, 'finding tables');
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
router.get('/:id', async function (req, res) {
|
|
55
|
+
try {
|
|
56
|
+
const table = await dataTableService.getTable(req.projectid, req.params.id);
|
|
57
|
+
if (!table) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
58
|
+
res.status(200).send(table);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
handleError(res, err, 'finding table');
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
router.post('/', async function (req, res) {
|
|
65
|
+
try {
|
|
66
|
+
const table = await dataTableService.createTable(
|
|
67
|
+
req.projectid,
|
|
68
|
+
req.body,
|
|
69
|
+
req.user.id || req.user._id
|
|
70
|
+
);
|
|
71
|
+
res.status(200).send(table);
|
|
72
|
+
} catch (err) {
|
|
73
|
+
handleError(res, err, 'creating table');
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
router.put('/:id', async function (req, res) {
|
|
78
|
+
try {
|
|
79
|
+
const table = await dataTableService.updateTable(req.projectid, req.params.id, req.body);
|
|
80
|
+
if (!table) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
81
|
+
res.status(200).send(table);
|
|
82
|
+
} catch (err) {
|
|
83
|
+
handleError(res, err, 'updating table');
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
router.delete('/:id', async function (req, res) {
|
|
88
|
+
try {
|
|
89
|
+
const deleted = await dataTableService.deleteTable(req.projectid, req.params.id);
|
|
90
|
+
if (!deleted) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
91
|
+
res.status(200).send({ success: true, message: 'Table deleted successfully' });
|
|
92
|
+
} catch (err) {
|
|
93
|
+
handleError(res, err, 'deleting table');
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// --- Columns ---
|
|
98
|
+
|
|
99
|
+
router.post('/:id/columns', async function (req, res) {
|
|
100
|
+
try {
|
|
101
|
+
const table = await dataTableService.addColumn(req.projectid, req.params.id, req.body);
|
|
102
|
+
if (!table) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
103
|
+
res.status(200).send(table);
|
|
104
|
+
} catch (err) {
|
|
105
|
+
handleError(res, err, 'adding column');
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
router.patch('/:id/columns/:columnId', async function (req, res) {
|
|
110
|
+
try {
|
|
111
|
+
const table = await dataTableService.renameColumn(
|
|
112
|
+
req.projectid,
|
|
113
|
+
req.params.id,
|
|
114
|
+
req.params.columnId,
|
|
115
|
+
req.body.name
|
|
116
|
+
);
|
|
117
|
+
if (!table) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
118
|
+
res.status(200).send(table);
|
|
119
|
+
} catch (err) {
|
|
120
|
+
handleError(res, err, 'renaming column');
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
router.delete('/:id/columns/:columnId', async function (req, res) {
|
|
125
|
+
try {
|
|
126
|
+
const table = await dataTableService.deleteColumn(
|
|
127
|
+
req.projectid,
|
|
128
|
+
req.params.id,
|
|
129
|
+
req.params.columnId
|
|
130
|
+
);
|
|
131
|
+
if (!table) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
132
|
+
res.status(200).send(table);
|
|
133
|
+
} catch (err) {
|
|
134
|
+
handleError(res, err, 'deleting column');
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// --- Rows (insert / update / upsert / delete by id_row or conditions) ---
|
|
139
|
+
|
|
140
|
+
function getRowsListParams(req) {
|
|
141
|
+
var params = Object.assign({}, req.query);
|
|
142
|
+
if (req.body && typeof req.body === 'object' && !Array.isArray(req.body)) {
|
|
143
|
+
if (req.body.must_match !== undefined) params.must_match = req.body.must_match;
|
|
144
|
+
if (req.body.match !== undefined) params.match = req.body.match;
|
|
145
|
+
if (req.body.conditions !== undefined) params.conditions = req.body.conditions;
|
|
146
|
+
}
|
|
147
|
+
return params;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
router.get('/:id/rows/list', async function (req, res) {
|
|
151
|
+
|
|
152
|
+
console.log("List rows")
|
|
153
|
+
try {
|
|
154
|
+
const rows = await dataTableService.listRowsWithFilter(
|
|
155
|
+
req.projectid,
|
|
156
|
+
req.params.id,
|
|
157
|
+
Object.assign({}, getRowsListParams(req), { sort: -1, limit: 200 })
|
|
158
|
+
);
|
|
159
|
+
if (rows === null) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
160
|
+
res.status(200).send(rows);
|
|
161
|
+
} catch (err) {
|
|
162
|
+
handleError(res, err, 'listing rows');
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
router.post('/:id/row/insert', async function (req, res) {
|
|
167
|
+
console.log("Insert row")
|
|
168
|
+
try {
|
|
169
|
+
const row = await dataTableService.insertRowByBody(req.projectid, req.params.id, req.body);
|
|
170
|
+
if (!row) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
171
|
+
res.status(200).send(row);
|
|
172
|
+
} catch (err) {
|
|
173
|
+
handleError(res, err, 'inserting row');
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
router.put('/:id/row/update', async function (req, res) {
|
|
178
|
+
try {
|
|
179
|
+
const row = await dataTableService.updateRowByBody(req.projectid, req.params.id, req.body);
|
|
180
|
+
if (row === null) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
181
|
+
if (row === undefined) return res.status(404).send({ success: false, error: 'Row not found' });
|
|
182
|
+
res.status(200).send(row);
|
|
183
|
+
} catch (err) {
|
|
184
|
+
handleError(res, err, 'updating row');
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
router.put('/:id/row/upsert', async function (req, res) {
|
|
189
|
+
try {
|
|
190
|
+
const result = await dataTableService.upsertRowByBody(req.projectid, req.params.id, req.body);
|
|
191
|
+
if (result === null) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
192
|
+
res.status(200).send(result);
|
|
193
|
+
} catch (err) {
|
|
194
|
+
if (err.message === 'Multiple rows match the conditions') {
|
|
195
|
+
return res.status(409).send({ success: false, message: err.message });
|
|
196
|
+
}
|
|
197
|
+
handleError(res, err, 'upserting row');
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
router.put('/:id/row/delete', async function (req, res) {
|
|
202
|
+
try {
|
|
203
|
+
const row = await dataTableService.deleteRowByBody(req.projectid, req.params.id, req.body);
|
|
204
|
+
if (row === null) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
205
|
+
if (row === undefined) return res.status(404).send({ success: false, error: 'Row not found' });
|
|
206
|
+
res.status(200).send(row);
|
|
207
|
+
} catch (err) {
|
|
208
|
+
handleError(res, err, 'deleting row');
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// --- Rows (REST) ---
|
|
213
|
+
|
|
214
|
+
// router.get('/:id/rows', async function (req, res) {
|
|
215
|
+
// try {
|
|
216
|
+
// const rows = await dataTableService.listRows(req.projectid, req.params.id);
|
|
217
|
+
// if (rows === null) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
218
|
+
// res.status(200).send(rows);
|
|
219
|
+
// } catch (err) {
|
|
220
|
+
// handleError(res, err, 'finding rows');
|
|
221
|
+
// }
|
|
222
|
+
// });
|
|
223
|
+
|
|
224
|
+
// router.get('/:id/rows/:rowId', async function (req, res) {
|
|
225
|
+
// try {
|
|
226
|
+
// const row = await dataTableService.getRow(req.projectid, req.params.id, req.params.rowId);
|
|
227
|
+
// if (!row) return res.status(404).send({ success: false, error: 'Row not found' });
|
|
228
|
+
// res.status(200).send(row);
|
|
229
|
+
// } catch (err) {
|
|
230
|
+
// handleError(res, err, 'finding row');
|
|
231
|
+
// }
|
|
232
|
+
// });
|
|
233
|
+
|
|
234
|
+
// router.post('/:id/rows', async function (req, res) {
|
|
235
|
+
// try {
|
|
236
|
+
// const row = await dataTableService.insertRow(req.projectid, req.params.id, getRowPayload(req.body));
|
|
237
|
+
// if (!row) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
238
|
+
// res.status(200).send(row);
|
|
239
|
+
// } catch (err) {
|
|
240
|
+
// handleError(res, err, 'inserting row');
|
|
241
|
+
// }
|
|
242
|
+
// });
|
|
243
|
+
|
|
244
|
+
// router.put('/:id/rows/:rowId', async function (req, res) {
|
|
245
|
+
// try {
|
|
246
|
+
// const row = await dataTableService.updateRow(
|
|
247
|
+
// req.projectid,
|
|
248
|
+
// req.params.id,
|
|
249
|
+
// req.params.rowId,
|
|
250
|
+
// getRowPayload(req.body)
|
|
251
|
+
// );
|
|
252
|
+
// if (row === null) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
253
|
+
// if (row === undefined) return res.status(404).send({ success: false, error: 'Row not found' });
|
|
254
|
+
// res.status(200).send(row);
|
|
255
|
+
// } catch (err) {
|
|
256
|
+
// handleError(res, err, 'updating row');
|
|
257
|
+
// }
|
|
258
|
+
// });
|
|
259
|
+
|
|
260
|
+
// router.delete('/:id/rows/:rowId', async function (req, res) {
|
|
261
|
+
// try {
|
|
262
|
+
// const row = await dataTableService.deleteRow(req.projectid, req.params.id, req.params.rowId);
|
|
263
|
+
// if (!row) return res.status(404).send({ success: false, error: 'Row not found' });
|
|
264
|
+
// res.status(200).send(row);
|
|
265
|
+
// } catch (err) {
|
|
266
|
+
// handleError(res, err, 'deleting row');
|
|
267
|
+
// }
|
|
268
|
+
// });
|
|
269
|
+
|
|
270
|
+
// router.post('/:id/rows/search', async function (req, res) {
|
|
271
|
+
// try {
|
|
272
|
+
// const rows = await dataTableService.searchRows(req.projectid, req.params.id, req.body);
|
|
273
|
+
// if (rows === null) return res.status(404).send({ success: false, error: 'Table not found' });
|
|
274
|
+
// res.status(200).send(rows);
|
|
275
|
+
// } catch (err) {
|
|
276
|
+
// handleError(res, err, 'searching rows');
|
|
277
|
+
// }
|
|
278
|
+
// });
|
|
279
|
+
|
|
280
|
+
module.exports = router;
|
package/routes/faq_kb.js
CHANGED
|
@@ -52,6 +52,9 @@ router.post('/', roleChecker.hasRole('admin'), async function (req, res) {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
faqService.create(req.projectid, req.user.id, req.body).then((savedFaq_kb) => {
|
|
55
|
+
if (req.query.skip_activity !== 'true') {
|
|
56
|
+
botEvent.emit('faqbot.created', { req, chatbot: savedFaq_kb });
|
|
57
|
+
}
|
|
55
58
|
res.status(200).send(savedFaq_kb);
|
|
56
59
|
}).catch((err) => {
|
|
57
60
|
res.status(500).send({ succes: false, error: err })
|
|
@@ -269,7 +272,7 @@ router.put('/:faq_kbid/publish', roleChecker.hasRole('admin'), async (req, res)
|
|
|
269
272
|
|
|
270
273
|
try {
|
|
271
274
|
// fork(id_faq_kb, api_url, token, project_id)
|
|
272
|
-
let forked = await cs.fork(chatbot_id, api_url, token, current_project_id);
|
|
275
|
+
let forked = await cs.fork(chatbot_id, api_url, token, current_project_id, { forPublish: true });
|
|
273
276
|
// winston.debug("forked: ", forked)
|
|
274
277
|
|
|
275
278
|
let forkedChatBotId = forked.bot_id;
|
|
@@ -294,6 +297,13 @@ router.put('/:faq_kbid/publish', roleChecker.hasRole('admin'), async (req, res)
|
|
|
294
297
|
|
|
295
298
|
botEvent.emit('faqbot.update', updatedOriginalChabot);
|
|
296
299
|
|
|
300
|
+
botEvent.emit('faqbot.publish', {
|
|
301
|
+
req: req,
|
|
302
|
+
chatbot: updatedOriginalChabot,
|
|
303
|
+
publishedBotId: forkedChatBotId,
|
|
304
|
+
release_note: release_note
|
|
305
|
+
});
|
|
306
|
+
|
|
297
307
|
return res.status(200).send({ message: "Chatbot published successfully", bot_id: forkedChatBotId });
|
|
298
308
|
|
|
299
309
|
} catch (e) {
|
|
@@ -355,6 +365,13 @@ router.put('/:faq_kbid', roleChecker.hasRoleOrTypes('admin', ['bot', 'subscripti
|
|
|
355
365
|
}
|
|
356
366
|
|
|
357
367
|
botEvent.emit('faqbot.update', updatedFaq_kb);
|
|
368
|
+
|
|
369
|
+
// A soft-delete is performed via PUT by setting trashed: true (the schema applies a TTL).
|
|
370
|
+
// Emit faqbot.deleted so the deletion is tracked just like the hard-delete endpoint.
|
|
371
|
+
if (req.body.trashed === true || req.body.trashed === 'true') {
|
|
372
|
+
botEvent.emit('faqbot.deleted', { req, chatbot: updatedFaq_kb });
|
|
373
|
+
}
|
|
374
|
+
|
|
358
375
|
res.json(updatedFaq_kb);
|
|
359
376
|
});
|
|
360
377
|
});
|
|
@@ -460,6 +477,7 @@ router.delete('/:faq_kbid', roleChecker.hasRole('admin'), function (req, res) {
|
|
|
460
477
|
* WARNING: faq_kb is the operation result, not the faq_kb object. The event subscriber will not receive the object as expected.
|
|
461
478
|
*/
|
|
462
479
|
botEvent.emit('faqbot.delete', faq_kb);
|
|
480
|
+
botEvent.emit('faqbot.deleted', { req, chatbot: faq_kb });
|
|
463
481
|
res.status(200).send({ success: true, message: "Chatbot with id " + req.params.faq_kbid + " deleted successfully" })
|
|
464
482
|
});
|
|
465
483
|
});
|
|
@@ -707,6 +725,10 @@ router.post('/fork/:id_faq_kb', roleChecker.hasRole('admin'), async (req, res) =
|
|
|
707
725
|
return res.status(500).send({ success: false, message: "Unable to import intents in the new chatbot" });
|
|
708
726
|
}
|
|
709
727
|
|
|
728
|
+
if (req.query.for_publish !== 'true') {
|
|
729
|
+
botEvent.emit('faqbot.created', { req, chatbot: savedChatbot, id_project: landing_project_id });
|
|
730
|
+
}
|
|
731
|
+
|
|
710
732
|
return res.status(200).send({ message: "Chatbot forked successfully", bot_id: savedChatbot._id });
|
|
711
733
|
|
|
712
734
|
})
|
|
@@ -774,6 +796,7 @@ router.post('/importjson/:id_faq_kb', roleChecker.hasRole('admin'), upload.singl
|
|
|
774
796
|
})
|
|
775
797
|
|
|
776
798
|
botEvent.emit('faqbot.create', savedChatbot);
|
|
799
|
+
botEvent.emit('faqbot.created', { req, chatbot: savedChatbot });
|
|
777
800
|
|
|
778
801
|
if (json.intents) {
|
|
779
802
|
|
package/routes/kb.js
CHANGED
|
@@ -894,7 +894,13 @@ router.delete('/deleteall', async (req, res) => {
|
|
|
894
894
|
|
|
895
895
|
aiService.deleteNamespace(data).then((resp) => {
|
|
896
896
|
winston.debug("delete namespace resp: ", resp.data);
|
|
897
|
-
kbEvent.emit('kb.contents.delete', {
|
|
897
|
+
kbEvent.emit('kb.contents.delete', {
|
|
898
|
+
req,
|
|
899
|
+
namespace_id,
|
|
900
|
+
project_id,
|
|
901
|
+
namespace_name: namespace.name,
|
|
902
|
+
deleteMode: 'contents_only'
|
|
903
|
+
});
|
|
898
904
|
res.status(200).send(resp.data);
|
|
899
905
|
}).catch((err) => {
|
|
900
906
|
winston.error("delete namespace err: ", err);
|
|
@@ -1443,7 +1449,14 @@ router.delete('/namespace/:id', async (req, res) => {
|
|
|
1443
1449
|
})
|
|
1444
1450
|
winston.debug("delete all contents response: ", deleteResponse);
|
|
1445
1451
|
|
|
1446
|
-
kbEvent.emit('kb.contents.delete', {
|
|
1452
|
+
kbEvent.emit('kb.contents.delete', {
|
|
1453
|
+
req,
|
|
1454
|
+
namespace_id,
|
|
1455
|
+
project_id,
|
|
1456
|
+
namespace_name: namespace.name,
|
|
1457
|
+
deletedCount: deleteResponse?.deletedCount,
|
|
1458
|
+
deleteMode: 'contents_only'
|
|
1459
|
+
});
|
|
1447
1460
|
|
|
1448
1461
|
return res.status(200).send({ success: true, message: "All contents deleted successfully" })
|
|
1449
1462
|
|
|
@@ -1485,6 +1498,14 @@ router.delete('/namespace/:id', async (req, res) => {
|
|
|
1485
1498
|
})
|
|
1486
1499
|
winston.debug("delete namespace response: ", deleteNamespaceResponse);
|
|
1487
1500
|
|
|
1501
|
+
kbEvent.emit('kb.namespace.delete', {
|
|
1502
|
+
req,
|
|
1503
|
+
namespace_id,
|
|
1504
|
+
project_id,
|
|
1505
|
+
namespace_name: namespace.name,
|
|
1506
|
+
deletedCount: deleteResponse?.deletedCount
|
|
1507
|
+
});
|
|
1508
|
+
|
|
1488
1509
|
return res.status(200).send({ success: true, message: "Namespace deleted succesfully" })
|
|
1489
1510
|
|
|
1490
1511
|
}).catch((err) => {
|
|
@@ -1757,6 +1778,18 @@ router.post('/', async (req, res) => {
|
|
|
1757
1778
|
}
|
|
1758
1779
|
|
|
1759
1780
|
aiManager.scheduleScrape([json], namespace.hybrid);
|
|
1781
|
+
|
|
1782
|
+
kbEvent.emit('kb.contents.add', {
|
|
1783
|
+
req,
|
|
1784
|
+
project_id: id_project,
|
|
1785
|
+
namespace_id: namespace_id,
|
|
1786
|
+
namespace_name: namespace.name,
|
|
1787
|
+
contentAddType: 'content',
|
|
1788
|
+
count: 1,
|
|
1789
|
+
type: saved_kb.type,
|
|
1790
|
+
source: saved_kb.source || saved_kb.name
|
|
1791
|
+
});
|
|
1792
|
+
|
|
1760
1793
|
return res.status(200).send(raw_content);
|
|
1761
1794
|
|
|
1762
1795
|
}
|
|
@@ -1825,6 +1858,14 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
|
|
|
1825
1858
|
|
|
1826
1859
|
try {
|
|
1827
1860
|
const result = await aiManager.addMultipleUrls(namespace, list, options);
|
|
1861
|
+
kbEvent.emit('kb.contents.add', {
|
|
1862
|
+
req,
|
|
1863
|
+
project_id: id_project,
|
|
1864
|
+
namespace_id: namespace_id,
|
|
1865
|
+
namespace_name: namespace.name,
|
|
1866
|
+
contentAddType: 'url_list',
|
|
1867
|
+
count: list.length
|
|
1868
|
+
});
|
|
1828
1869
|
return res.status(200).send(result);
|
|
1829
1870
|
} catch (err) {
|
|
1830
1871
|
winston.error("addMultipleUrls error: ", err)
|
|
@@ -1931,6 +1972,16 @@ router.post('/csv', upload.single('uploadFile'), async (req, res) => {
|
|
|
1931
1972
|
}
|
|
1932
1973
|
|
|
1933
1974
|
aiManager.scheduleScrape(resources, hybrid);
|
|
1975
|
+
|
|
1976
|
+
kbEvent.emit('kb.contents.add', {
|
|
1977
|
+
req,
|
|
1978
|
+
project_id: project_id,
|
|
1979
|
+
namespace_id: namespace_id,
|
|
1980
|
+
namespace_name: namespace.name,
|
|
1981
|
+
contentAddType: 'csv',
|
|
1982
|
+
count: kbs.length
|
|
1983
|
+
});
|
|
1984
|
+
|
|
1934
1985
|
return res.status(200).send(result);
|
|
1935
1986
|
|
|
1936
1987
|
}).catch((err) => {
|
|
@@ -2068,6 +2119,18 @@ router.post('/sitemap/import', async (req, res) => {
|
|
|
2068
2119
|
return res.status(200).send(result);
|
|
2069
2120
|
}
|
|
2070
2121
|
result.push(saved_content);
|
|
2122
|
+
|
|
2123
|
+
kbEvent.emit('kb.contents.add', {
|
|
2124
|
+
req,
|
|
2125
|
+
project_id: id_project,
|
|
2126
|
+
namespace_id: namespace_id,
|
|
2127
|
+
namespace_name: namespace.name,
|
|
2128
|
+
contentAddType: 'sitemap',
|
|
2129
|
+
count: urls.length,
|
|
2130
|
+
type: 'sitemap',
|
|
2131
|
+
source: source
|
|
2132
|
+
});
|
|
2133
|
+
|
|
2071
2134
|
return res.status(200).send(result);
|
|
2072
2135
|
} catch (err) {
|
|
2073
2136
|
return res.status(500).send({ success: false, error: "Unable to add multiple urls from sitemap due to an error." });
|
|
@@ -2279,6 +2342,29 @@ router.delete('/:kb_id', async (req, res) => {
|
|
|
2279
2342
|
data.engine = namespace.engine || default_engine;
|
|
2280
2343
|
winston.verbose("/:delete_id data: ", data);
|
|
2281
2344
|
|
|
2345
|
+
const emitKbContentDelete = (deletedKb) => {
|
|
2346
|
+
const content = deletedKb || kb;
|
|
2347
|
+
const contentSnapshot = content.toObject ? content.toObject() : content;
|
|
2348
|
+
kbEvent.emit('kb.content.delete', {
|
|
2349
|
+
req,
|
|
2350
|
+
kb_id,
|
|
2351
|
+
project_id,
|
|
2352
|
+
namespace_id,
|
|
2353
|
+
namespace_name: namespace.name,
|
|
2354
|
+
kb: {
|
|
2355
|
+
_id: contentSnapshot._id,
|
|
2356
|
+
name: contentSnapshot.name,
|
|
2357
|
+
source: contentSnapshot.source,
|
|
2358
|
+
type: contentSnapshot.type
|
|
2359
|
+
}
|
|
2360
|
+
});
|
|
2361
|
+
};
|
|
2362
|
+
|
|
2363
|
+
if (process.env.NODE_ENV === 'test') {
|
|
2364
|
+
emitKbContentDelete(kb);
|
|
2365
|
+
return res.status(200).send({ success: true, message: "Content deleted successfully" });
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2282
2368
|
aiService.deleteIndex(data).then((resp) => {
|
|
2283
2369
|
winston.debug("delete resp: ", resp.data);
|
|
2284
2370
|
if (resp.data.success === true) {
|
|
@@ -2288,6 +2374,7 @@ router.delete('/:kb_id', async (req, res) => {
|
|
|
2288
2374
|
winston.error("Delete kb error: ", err);
|
|
2289
2375
|
return res.status(500).send({ success: false, error: err });
|
|
2290
2376
|
}
|
|
2377
|
+
emitKbContentDelete(deletedKb);
|
|
2291
2378
|
res.status(200).send(deletedKb);
|
|
2292
2379
|
})
|
|
2293
2380
|
|
|
@@ -2303,6 +2390,7 @@ router.delete('/:kb_id', async (req, res) => {
|
|
|
2303
2390
|
winston.verbose("Unable to delete the content in indexing status")
|
|
2304
2391
|
return res.status(500).send({ success: false, error: "Unable to delete the content in indexing status" })
|
|
2305
2392
|
} else {
|
|
2393
|
+
emitKbContentDelete(deletedKb);
|
|
2306
2394
|
res.status(200).send(deletedKb);
|
|
2307
2395
|
}
|
|
2308
2396
|
})
|
package/routes/project_user.js
CHANGED
|
@@ -18,6 +18,25 @@ var validtoken = require('../middleware/valid-token')
|
|
|
18
18
|
var roleChecker = require('../middleware/has-role');
|
|
19
19
|
const puEvent = require('../event/projectUserEvent');
|
|
20
20
|
const { track } = require('../lib/analyticsClient');
|
|
21
|
+
const projectUserUpdateContextUtil = require('../utils/projectUserUpdateContextUtil');
|
|
22
|
+
|
|
23
|
+
function emitProjectUserDeleteActivity(req, project_user, deleteType) {
|
|
24
|
+
if (!project_user) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
project_user.populate({ path: 'id_user', select: { firstname: 1, lastname: 1, email: 1 } }, function (populateErr, project_userPopulated) {
|
|
28
|
+
if (populateErr) {
|
|
29
|
+
winston.error('Error populating project_user for delete activity', populateErr);
|
|
30
|
+
}
|
|
31
|
+
const pu = project_userPopulated || project_user;
|
|
32
|
+
const payload = pu.toJSON ? pu.toJSON() : pu;
|
|
33
|
+
authEvent.emit('project_user.delete', {
|
|
34
|
+
req: req,
|
|
35
|
+
project_userPopulated: payload,
|
|
36
|
+
deleteType: deleteType
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
21
40
|
|
|
22
41
|
|
|
23
42
|
router.post('/invite', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], function (req, res) {
|
|
@@ -111,15 +130,19 @@ router.post('/invite', [passport.authenticate(['basic', 'jwt'], { session: false
|
|
|
111
130
|
|
|
112
131
|
emailService.sendYouHaveBeenInvited(email, req.user.firstname, req.user.lastname, req.project.name, id_project, user.firstname, user.lastname, req.body.role)
|
|
113
132
|
|
|
114
|
-
|
|
115
|
-
|
|
133
|
+
savedProject_user.populate({path:'id_user', select:{'firstname':1, 'lastname':1, 'email': 1}},function (err, savedProject_userPopulated){
|
|
134
|
+
if (err) {
|
|
135
|
+
winston.error("Error populating project user after re-invite", err);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
var pu = savedProject_userPopulated.toJSON();
|
|
116
139
|
pu.isBusy = ProjectUserUtil.isBusy(savedProject_userPopulated, req.project.settings && req.project.settings.max_agent_assigned_chat);
|
|
117
|
-
var eventData = {req:req,
|
|
140
|
+
var eventData = {req:req, savedProject_userPopulated: pu};
|
|
118
141
|
winston.debug("eventData",eventData);
|
|
119
142
|
authEvent.emit('project_user.invite', eventData);
|
|
120
143
|
});
|
|
121
144
|
|
|
122
|
-
return res.status(200).send(
|
|
145
|
+
return res.status(200).send(savedProject_user);
|
|
123
146
|
})
|
|
124
147
|
|
|
125
148
|
} else {
|
|
@@ -220,6 +243,13 @@ router.put('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
|
|
|
220
243
|
}
|
|
221
244
|
|
|
222
245
|
const previousUserAvailable = req.projectuser.user_available;
|
|
246
|
+
const previousProfileStatus = req.projectuser.profileStatus;
|
|
247
|
+
const updateContext = projectUserUpdateContextUtil.buildProjectUserUpdateContext(
|
|
248
|
+
req,
|
|
249
|
+
previousUserAvailable,
|
|
250
|
+
previousProfileStatus,
|
|
251
|
+
projectUserUpdateContextUtil.resolveUserId(req.projectuser.id_user)
|
|
252
|
+
);
|
|
223
253
|
|
|
224
254
|
Project_user.findByIdAndUpdate(req.projectuser.id, update, { new: true, upsert: true }, function (err, updatedProject_user) {
|
|
225
255
|
if (err) {
|
|
@@ -230,7 +260,13 @@ router.put('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
|
|
|
230
260
|
updatedProject_user.populate({ path:'id_user', select: { 'firstname': 1, 'lastname': 1 }}, function (err, updatedProject_userPopulated) {
|
|
231
261
|
var pu = updatedProject_userPopulated.toJSON();
|
|
232
262
|
pu.isBusy = ProjectUserUtil.isBusy(updatedProject_userPopulated, req.project.settings && req.project.settings.max_agent_assigned_chat);
|
|
233
|
-
authEvent.emit('project_user.update', {
|
|
263
|
+
authEvent.emit('project_user.update', {
|
|
264
|
+
updatedProject_userPopulated: pu,
|
|
265
|
+
req: req,
|
|
266
|
+
previousUserAvailable: previousUserAvailable,
|
|
267
|
+
previousProfileStatus: previousProfileStatus,
|
|
268
|
+
updateContext: updateContext
|
|
269
|
+
});
|
|
234
270
|
});
|
|
235
271
|
|
|
236
272
|
res.json(updatedProject_user);
|
|
@@ -286,7 +322,14 @@ router.put('/:project_userid', [passport.authenticate(['basic', 'jwt'], { sessio
|
|
|
286
322
|
|
|
287
323
|
winston.debug("project_userid update", update);
|
|
288
324
|
|
|
289
|
-
function _doUpdateProjectUser(previousUserAvailable) {
|
|
325
|
+
function _doUpdateProjectUser(previousUserAvailable, previousProfileStatus, targetUserId) {
|
|
326
|
+
const updateContext = projectUserUpdateContextUtil.buildProjectUserUpdateContext(
|
|
327
|
+
req,
|
|
328
|
+
previousUserAvailable,
|
|
329
|
+
previousProfileStatus,
|
|
330
|
+
targetUserId
|
|
331
|
+
);
|
|
332
|
+
|
|
290
333
|
Project_user.findByIdAndUpdate(req.params.project_userid, update, { new: true, upsert: true }, function (err, updatedProject_user) {
|
|
291
334
|
if (err) {
|
|
292
335
|
winston.error("Error gettting project_user for update", err);
|
|
@@ -299,7 +342,13 @@ router.put('/:project_userid', [passport.authenticate(['basic', 'jwt'], { sessio
|
|
|
299
342
|
var pu = updatedProject_userPopulated.toJSON();
|
|
300
343
|
pu.isBusy = ProjectUserUtil.isBusy(updatedProject_user, req.project.settings && req.project.settings.max_agent_assigned_chat);
|
|
301
344
|
|
|
302
|
-
authEvent.emit('project_user.update', {
|
|
345
|
+
authEvent.emit('project_user.update', {
|
|
346
|
+
updatedProject_userPopulated: pu,
|
|
347
|
+
req: req,
|
|
348
|
+
previousUserAvailable: previousUserAvailable,
|
|
349
|
+
previousProfileStatus: previousProfileStatus,
|
|
350
|
+
updateContext: updateContext
|
|
351
|
+
});
|
|
303
352
|
});
|
|
304
353
|
|
|
305
354
|
|
|
@@ -307,12 +356,16 @@ router.put('/:project_userid', [passport.authenticate(['basic', 'jwt'], { sessio
|
|
|
307
356
|
});
|
|
308
357
|
}
|
|
309
358
|
|
|
310
|
-
if (update.user_available !== undefined
|
|
311
|
-
Project_user.findById(req.params.project_userid, 'user_available').lean().exec(function(err, currentPu) {
|
|
312
|
-
_doUpdateProjectUser(
|
|
359
|
+
if (update.user_available !== undefined || update.profileStatus !== undefined) {
|
|
360
|
+
Project_user.findById(req.params.project_userid, 'user_available profileStatus id_user').lean().exec(function(err, currentPu) {
|
|
361
|
+
_doUpdateProjectUser(
|
|
362
|
+
currentPu ? currentPu.user_available : null,
|
|
363
|
+
currentPu ? currentPu.profileStatus : null,
|
|
364
|
+
currentPu ? currentPu.id_user : null
|
|
365
|
+
);
|
|
313
366
|
});
|
|
314
367
|
} else {
|
|
315
|
-
_doUpdateProjectUser(null);
|
|
368
|
+
_doUpdateProjectUser(null, null, null);
|
|
316
369
|
}
|
|
317
370
|
});
|
|
318
371
|
|
|
@@ -340,7 +393,7 @@ router.delete('/:project_userid', [passport.authenticate(['basic', 'jwt'], { ses
|
|
|
340
393
|
}
|
|
341
394
|
|
|
342
395
|
puEvent.emit('project_user.deleted', project_user);
|
|
343
|
-
|
|
396
|
+
emitProjectUserDeleteActivity(req, project_user, 'soft');
|
|
344
397
|
return res.status(200).send(project_user);
|
|
345
398
|
|
|
346
399
|
})
|
|
@@ -360,11 +413,7 @@ router.delete('/:project_userid', [passport.authenticate(['basic', 'jwt'], { ses
|
|
|
360
413
|
|
|
361
414
|
winston.debug("Hard deleted project_user", project_user);
|
|
362
415
|
|
|
363
|
-
|
|
364
|
-
project_user.populate({ path: 'id_user', select: { 'firstname': 1, 'lastname': 1 } }, function (err, project_userPopulated) {
|
|
365
|
-
authEvent.emit('project_user.delete', { req: req, project_userPopulated: project_userPopulated });
|
|
366
|
-
});
|
|
367
|
-
}
|
|
416
|
+
emitProjectUserDeleteActivity(req, project_user, 'hard');
|
|
368
417
|
|
|
369
418
|
puEvent.emit('project_user.deleted', project_user);
|
|
370
419
|
return res.status(200).send(project_user);
|