@yrpri/api 9.0.231 → 9.0.233

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.
Files changed (69) hide show
  1. package/agents/managers/subscriptionManager.js +2 -2
  2. package/controllers/allOurIdeas.js +1 -1
  3. package/controllers/communities.cjs +282 -91
  4. package/controllers/domains.cjs +54 -8
  5. package/controllers/groups.cjs +51 -6
  6. package/controllers/points.cjs +4 -9
  7. package/controllers/posts.cjs +7 -9
  8. package/controllers/ratings.cjs +3 -6
  9. package/models/point.cjs +31 -3
  10. package/models/post.cjs +2 -3
  11. package/package.json +32 -67
  12. package/services/engine/allOurIdeas/aiHelper.d.ts +7 -4
  13. package/services/engine/allOurIdeas/aiHelper.js +34 -19
  14. package/services/engine/allOurIdeas/explainAnswersAssistant.d.ts +1 -1
  15. package/services/engine/allOurIdeas/explainAnswersAssistant.js +3 -9
  16. package/services/engine/moderation/fraud/CreateFraudAuditReport.cjs +35 -11
  17. package/services/engine/moderation/fraud/CreateFraudAuditReport.d.cts +21 -0
  18. package/services/engine/moderation/fraud/FraudBase.cjs +38 -18
  19. package/services/engine/moderation/fraud/FraudBase.d.cts +2 -0
  20. package/services/engine/moderation/fraud/FraudDeleteBase.cjs +48 -29
  21. package/services/engine/moderation/fraud/FraudDeleteBase.d.cts +8 -6
  22. package/services/engine/moderation/fraud/FraudDeleteEndorsements.cjs +5 -4
  23. package/services/engine/moderation/fraud/FraudDeleteEndorsements.d.cts +2 -2
  24. package/services/engine/moderation/fraud/FraudDeletePointQualities.cjs +3 -2
  25. package/services/engine/moderation/fraud/FraudDeletePointQualities.d.cts +1 -1
  26. package/services/engine/moderation/fraud/FraudDeletePoints.cjs +3 -2
  27. package/services/engine/moderation/fraud/FraudDeletePoints.d.cts +1 -1
  28. package/services/engine/moderation/fraud/FraudDeletePosts.cjs +3 -2
  29. package/services/engine/moderation/fraud/FraudDeleteRatings.cjs +61 -4
  30. package/services/engine/moderation/fraud/FraudGetBase.cjs +44 -20
  31. package/services/engine/moderation/fraud/FraudGetBase.d.cts +5 -0
  32. package/services/engine/moderation/fraud/FraudGetEndorsements.cjs +4 -13
  33. package/services/engine/moderation/fraud/FraudGetEndorsements.d.cts +1 -1
  34. package/services/engine/moderation/fraud/FraudGetPointQualities.cjs +3 -0
  35. package/services/engine/moderation/fraud/FraudGetPointQualities.d.cts +1 -1
  36. package/services/engine/moderation/fraud/FraudGetPoints.cjs +3 -0
  37. package/services/engine/moderation/fraud/FraudGetPoints.d.cts +1 -1
  38. package/services/engine/moderation/fraud/FraudGetPosts.cjs +17 -16
  39. package/services/engine/moderation/fraud/FraudGetPosts.d.cts +3 -3
  40. package/services/engine/moderation/fraud/FraudGetRatings.cjs +62 -30
  41. package/services/engine/moderation/fraud/FraudGetRatings.d.cts +4 -1
  42. package/services/engine/moderation/fraud/FraudRequestValidation.cjs +143 -0
  43. package/services/engine/moderation/fraud/FraudRequestValidation.d.cts +21 -0
  44. package/services/engine/moderation/fraud/FraudScannerNotifier.cjs +59 -35
  45. package/services/engine/moderation/fraud/FraudScannerNotifier.d.cts +20 -1
  46. package/services/llms/baseChatBot.d.ts +2 -0
  47. package/services/llms/baseChatBot.js +25 -9
  48. package/services/llms/imageGeneration/chatGptImageGenerator.d.ts +2 -2
  49. package/services/llms/imageGeneration/chatGptImageGenerator.js +13 -10
  50. package/services/llms/imageGeneration/collectionImageGenerator.js +31 -13
  51. package/services/llms/imageGeneration/dalleImageGenerator.d.ts +2 -2
  52. package/services/llms/imageGeneration/dalleImageGenerator.js +28 -16
  53. package/services/llms/imageGeneration/fluxImageGenerator.d.ts +2 -2
  54. package/services/llms/imageGeneration/fluxImageGenerator.js +9 -3
  55. package/services/llms/imageGeneration/iImageGenerator.d.ts +8 -1
  56. package/services/llms/imageGeneration/imageModelConfig.cjs +319 -0
  57. package/services/llms/imageGeneration/imageModelConfig.d.cts +79 -0
  58. package/services/llms/imageGeneration/imagenImageGenerator.d.ts +2 -3
  59. package/services/llms/imageGeneration/imagenImageGenerator.js +10 -10
  60. package/tests/fraudManagement.test.cjs +470 -0
  61. package/tests/fraudManagement.test.d.cts +1 -0
  62. package/tests/imageModelConfig.test.cjs +144 -0
  63. package/tests/imageModelConfig.test.d.cts +1 -0
  64. package/utils/ai_image_generation_guard.cjs +268 -0
  65. package/utils/ai_image_generation_guard.d.cts +34 -0
  66. package/utils/fingerprint_data.cjs +32 -0
  67. package/utils/fingerprint_data.d.cts +6 -0
  68. package/utils/recount_utils.cjs +53 -37
  69. package/utils/recount_utils.d.cts +7 -7
@@ -11,6 +11,16 @@ const formatWorksheet = (worksheet) => {
11
11
  worksheet.getRow(1).font = { bold: true };
12
12
  // worksheet.properties.defaultRowHeight = 20;
13
13
  };
14
+ const sanitizeWorksheetName = (name) => {
15
+ const sanitizedName = String(name || "Fraud Audit")
16
+ .replace(/[\\/\*\?:\[\]]/g, " ")
17
+ .replace(/\s+/g, " ")
18
+ .trim()
19
+ .substring(0, 31)
20
+ .trim()
21
+ .replace(/^'+|'+$/g, "");
22
+ return sanitizedName.trim() || "Fraud Audit";
23
+ };
14
24
  class FraudAuditReport {
15
25
  constructor(workPackage) {
16
26
  this.workPackage = workPackage;
@@ -100,7 +110,7 @@ class FraudAuditReport {
100
110
  return items;
101
111
  }
102
112
  async getPostItems(ids) {
103
- return await model.unscoped().findAll({
113
+ return await models.Post.unscoped().findAll({
104
114
  attributes: ["id", "created_at", "group_id", "user_id", "user_agent", "ip_address", "data"],
105
115
  where: {
106
116
  id: {
@@ -133,7 +143,7 @@ class FraudAuditReport {
133
143
  this.workBook = new Excel.Workbook();
134
144
  this.workBook.creator = "Your Priorities Report - Automated";
135
145
  this.workBook.created = new Date();
136
- this.worksheet = this.workBook.addWorksheet(`Community Users ${this.workPackage.community.id} ${this.workPackage.userName}`);
146
+ this.worksheet = this.workBook.addWorksheet(sanitizeWorksheetName(`Community Users ${this.workPackage.community.id} ${this.workPackage.userName}`));
137
147
  this.worksheet.columns = [
138
148
  { header: "Type", key: "collectionType", width: 20 },
139
149
  { header: "Method", key: "selectedMethod", width: 20 },
@@ -159,7 +169,7 @@ class FraudAuditReport {
159
169
  }
160
170
  if (['pointQualities'].indexOf(originalWorkPackage.collectionType) !== -1) {
161
171
  this.worksheet.columns = this.worksheet.columns.concat([
162
- { header: "Point Id", key: "postId", width: 20 },
172
+ { header: "Point Id", key: "pointId", width: 20 },
163
173
  ]);
164
174
  }
165
175
  this.worksheet.columns = this.worksheet.columns.concat([
@@ -176,8 +186,8 @@ class FraudAuditReport {
176
186
  communityName +
177
187
  "_" +
178
188
  dateString +
179
- ".xls";
180
- this.workPackage.fileEnding = "xls";
189
+ ".xlsx";
190
+ this.workPackage.fileEnding = "xlsx";
181
191
  }
182
192
  async getCommunity() {
183
193
  this.workPackage.community = await models.Community.findOne({
@@ -240,8 +250,8 @@ class FraudAuditReport {
240
250
  dateDeleted: this.workPackage.auditReportData.date,
241
251
  id: item.id,
242
252
  date: item.created_at,
243
- userId: item.User.id,
244
- email: item.User.email,
253
+ userId: item.User ? item.User.id : item.user_id,
254
+ email: item.User ? item.User.email : "",
245
255
  ipAddress: item.ip_address,
246
256
  userAgent: item.user_agent,
247
257
  };
@@ -250,14 +260,14 @@ class FraudAuditReport {
250
260
  row.browserId = item.data.browserId;
251
261
  }
252
262
  if (['posts', 'pointQualities'].indexOf(originalWorkPackage.collectionType) === -1) {
253
- row.postId = item.Post.id;
254
- row.postName = item.Post.name;
263
+ row.postId = item.Post ? item.Post.id : item.post_id;
264
+ row.postName = item.Post ? item.Post.name : "";
255
265
  }
256
266
  if (['endorsements', 'pointQualities', 'ratings'].indexOf(originalWorkPackage.collectionType) !== -1) {
257
267
  row.value = item.value;
258
268
  }
259
269
  if (['pointQualities'].indexOf(originalWorkPackage.collectionType) !== -1) {
260
- row.pointId = item.Point.id;
270
+ row.pointId = item.Point ? item.Point.id : item.point_id;
261
271
  }
262
272
  this.worksheet.addRow(row);
263
273
  }
@@ -272,6 +282,7 @@ class FraudAuditReport {
272
282
  }
273
283
  });
274
284
  if (auditReport && auditReport.data) {
285
+ this.validateAuditReportCommunity(auditReport);
275
286
  this.workPackage.auditReportData = auditReport.data;
276
287
  await this.getCommunity();
277
288
  this.setupFilename();
@@ -296,6 +307,17 @@ class FraudAuditReport {
296
307
  }
297
308
  });
298
309
  }
310
+ validateAuditReportCommunity(auditReport) {
311
+ const auditCommunityId = auditReport &&
312
+ auditReport.data &&
313
+ auditReport.data.workPackage &&
314
+ auditReport.data.workPackage.communityId;
315
+ if (auditCommunityId === undefined ||
316
+ auditCommunityId === null ||
317
+ String(auditCommunityId) !== String(this.workPackage.communityId)) {
318
+ throw new Error("Fraud audit report does not belong to this community");
319
+ }
320
+ }
299
321
  }
300
322
  const createFraudAuditReport = async (workPackage, done) => {
301
323
  return await new Promise(async (resolve, reject) => {
@@ -310,5 +332,7 @@ const createFraudAuditReport = async (workPackage, done) => {
310
332
  });
311
333
  };
312
334
  module.exports = {
313
- createFraudAuditReport
335
+ createFraudAuditReport,
336
+ FraudAuditReport,
337
+ sanitizeWorksheetName
314
338
  };
@@ -1 +1,22 @@
1
1
  export function createFraudAuditReport(workPackage: any, done: any): Promise<any>;
2
+ export class FraudAuditReport {
3
+ constructor(workPackage: any);
4
+ workPackage: any;
5
+ exportedData: Excel.Buffer | null;
6
+ items: any;
7
+ workBook: Excel.Workbook | null;
8
+ worksheet: Excel.Worksheet | null;
9
+ getPointQualityItems(ids: any): Promise<(import("sequelize").Model<YpPointQuality, Partial<YpPointQuality>> & YpPointQuality)[]>;
10
+ getPostDependedItems(model: any, ids: any): Promise<any>;
11
+ getPostItems(ids: any): Promise<(import("sequelize").Model<YpPostData, Partial<YpPostData>> & YpPostData)[]>;
12
+ setupXls(): Promise<void>;
13
+ setupFilename(): void;
14
+ getCommunity(): Promise<void>;
15
+ uploadToS3(): Promise<any>;
16
+ setupItems(): Promise<void>;
17
+ populateXls(): Promise<void>;
18
+ createReport(): Promise<any>;
19
+ validateAuditReportCommunity(auditReport: any): void;
20
+ }
21
+ export function sanitizeWorksheetName(name: any): string;
22
+ import Excel = require("exceljs");
@@ -2,6 +2,7 @@
2
2
  const _ = require("lodash");
3
3
  const moment = require("moment");
4
4
  const log = require("../../../../utils/logger.cjs");
5
+ const { normalizeFingerprintValue, } = require("../../../../utils/fingerprint_data.cjs");
5
6
  class FraudBase {
6
7
  constructor(workPackage) {
7
8
  this.workPackage = workPackage;
@@ -38,6 +39,21 @@ class FraudBase {
38
39
  return -item.count;
39
40
  });
40
41
  }
42
+ isDebugFraudDetectionCountAll() {
43
+ return process.env.DEBUG_FRAUD_DETECTION_COUNT_ALL === "true" &&
44
+ this.workPackage.type === "get-items";
45
+ }
46
+ getDebugTopItems(topItems) {
47
+ _.forEach(topItems, topItem => {
48
+ _.forEach(topItem.items, item => {
49
+ item.dataValues = item.dataValues || {};
50
+ if (!item.dataValues.confidenceScore) {
51
+ item.dataValues.confidenceScore = "0%";
52
+ }
53
+ });
54
+ });
55
+ return topItems;
56
+ }
41
57
  getTopDataByIp() {
42
58
  return this.getTopItems(this.groupTopDataByIp(), "byIpAddress");
43
59
  }
@@ -141,7 +157,7 @@ class FraudBase {
141
157
  for (let i = 0; i < items.length; i++) {
142
158
  const item = items[i];
143
159
  const hasData = item.data ? Object.keys(item.data).length === 0 : false;
144
- if (hasData && !item.data.browserId && moment(item.created_at) > this.getStartFingerprintMoment()) {
160
+ if (hasData && !normalizeFingerprintValue(item.data.browserId) && moment(item.created_at) > this.getStartFingerprintMoment()) {
145
161
  if (["posts", "points"].indexOf(this.workPackage.collectionType) > -1) {
146
162
  item.dataValues.confidenceScore = `50%`;
147
163
  }
@@ -180,50 +196,54 @@ class FraudBase {
180
196
  groupTopDataByIpFingerprintPostId() {
181
197
  const filtered = _.filter(this.items, (item) => {
182
198
  return item.data &&
183
- item.data.browserFingerprint &&
184
- item.data.browserFingerprint !== "undefined";
199
+ normalizeFingerprintValue(item.data.browserFingerprint);
185
200
  });
186
201
  return _.groupBy(filtered, (item) => {
187
- return item.ip_address + ":" + item.post_id + ":" + item.data.browserFingerprint;
202
+ return item.ip_address + ":" + item.post_id + ":" + normalizeFingerprintValue(item.data.browserFingerprint);
188
203
  });
189
204
  }
190
205
  groupTopDataByIpFingerprintPointId() {
191
206
  const filtered = _.filter(this.items, (item) => {
192
207
  return item.data &&
193
- item.data.browserFingerprint &&
194
- item.data.browserFingerprint !== "undefined";
208
+ normalizeFingerprintValue(item.data.browserFingerprint);
195
209
  });
196
210
  return _.groupBy(filtered, (item) => {
197
- return item.ip_address + ":" + item.point_id + ":" + item.data.browserFingerprint;
211
+ return item.ip_address + ":" + item.point_id + ":" + normalizeFingerprintValue(item.data.browserFingerprint);
198
212
  });
199
213
  }
200
214
  groupTopDataByIpFingerprint() {
201
215
  const filtered = _.filter(this.items, (item) => {
202
216
  return item.data &&
203
- item.data.browserFingerprint &&
204
- item.data.browserFingerprint !== "undefined";
217
+ normalizeFingerprintValue(item.data.browserFingerprint);
205
218
  });
206
219
  return _.groupBy(filtered, (item) => {
207
- return item.ip_address + ":" + item.data.browserFingerprint;
220
+ return item.ip_address + ":" + normalizeFingerprintValue(item.data.browserFingerprint);
208
221
  });
209
222
  }
210
223
  groupTopDataByNoFingerprints() {
211
224
  const filtered = _.filter(this.items, item => {
212
- return item.data &&
213
- (!item.data.browserFingerprint ||
214
- !item.data.browserId) &&
215
- moment(item.created_at).valueOf() > this.getStartFingerprintMoment();
225
+ item.data = item.data || {};
226
+ const missingFingerprint = !normalizeFingerprintValue(item.data.browserFingerprint) ||
227
+ !normalizeFingerprintValue(item.data.browserId);
228
+ if (this.isDebugFraudDetectionCountAll()) {
229
+ return missingFingerprint;
230
+ }
231
+ else {
232
+ return missingFingerprint &&
233
+ moment(item.created_at).valueOf() > this.getStartFingerprintMoment();
234
+ }
216
235
  });
217
236
  const scoreHundred = (["posts", "points"].indexOf(this.workPackage.collectionType) > -1) ? "50%" : "100%";
218
237
  const scoreNinety = (["posts", "points"].indexOf(this.workPackage.collectionType) > -1) ? "45%" : "90%";
219
238
  const scoreSeventy = (["posts", "points"].indexOf(this.workPackage.collectionType) > -1) ? "60%" : "70%";
220
239
  _.forEach(filtered, item => {
221
- if (!item.data.browserFingerprint &&
222
- !item.data.browserId) {
240
+ const browserFingerprint = normalizeFingerprintValue(item.data.browserFingerprint);
241
+ const browserId = normalizeFingerprintValue(item.data.browserId);
242
+ if (!browserFingerprint && !browserId) {
223
243
  item.dataValues.confidenceScore = scoreHundred;
224
244
  item.dataValues.key = "bothUndefined";
225
245
  }
226
- else if (!item.data.browserId) {
246
+ else if (!browserId) {
227
247
  item.dataValues.confidenceScore = scoreNinety;
228
248
  item.dataValues.key = "browserIdUndefined";
229
249
  }
@@ -233,7 +253,7 @@ class FraudBase {
233
253
  }
234
254
  });
235
255
  return _.groupBy(filtered, item => {
236
- return item.key;
256
+ return item.dataValues.key;
237
257
  });
238
258
  }
239
259
  }
@@ -9,6 +9,8 @@ declare class FraudBase {
9
9
  getAllItems(): Promise<null>;
10
10
  getPostIdsFromItems(topItems: any): any[];
11
11
  setupTopItems(items: any): any[];
12
+ isDebugFraudDetectionCountAll(): boolean;
13
+ getDebugTopItems(topItems: any): any;
12
14
  getTopDataByIp(): null;
13
15
  getTopDataByIpUserAgentPostId(): null;
14
16
  getTopDataByIpUserAgentPointId(): null;
@@ -12,6 +12,7 @@ class FraudDeleteBase extends FraudBase {
12
12
  super(workPackage);
13
13
  this.postsToRecount = [];
14
14
  this.pointsToRecount = [];
15
+ this.deletedItemIds = [];
15
16
  this.job = null;
16
17
  }
17
18
  sliceIntoChunks(arr, chunkSize) {
@@ -30,18 +31,22 @@ class FraudDeleteBase extends FraudBase {
30
31
  async destroyChunkItems(chunks) {
31
32
  log.error("Should be implemented in a sub class");
32
33
  }
34
+ getUserEmail(item) {
35
+ return item.User && item.User.email ? item.User.email : "";
36
+ }
33
37
  getAllItemsExceptOne(items) {
34
38
  if (items.length === 1 && this.getAllowedSingleDelete()) {
35
39
  return items;
36
40
  }
37
41
  else {
38
42
  const sortedItems = _.sortBy(items, function (item) {
39
- return item.date;
43
+ return moment(item.created_at || item.date).valueOf();
40
44
  });
41
45
  const finalItems = [];
42
46
  let foundEmail = false;
43
47
  for (let i = 0; i < sortedItems.length; i++) {
44
- if (!foundEmail && sortedItems[i].User.email && sortedItems[i].User.email.indexOf("_anonymous@citizens.i") === -1) {
48
+ const userEmail = this.getUserEmail(sortedItems[i]);
49
+ if (!foundEmail && userEmail && userEmail.indexOf("_anonymous@citizens.i") === -1) {
45
50
  foundEmail = true;
46
51
  }
47
52
  else {
@@ -54,27 +59,38 @@ class FraudDeleteBase extends FraudBase {
54
59
  return finalItems;
55
60
  }
56
61
  }
57
- async createAuditLog() {
62
+ async createAuditLog(transaction) {
58
63
  return await new Promise(async (resolve, reject) => {
59
64
  try {
60
65
  const user = await models.User.findOne({
61
66
  where: {
62
67
  id: this.workPackage.userId,
63
68
  },
64
- attributes: ['name']
69
+ attributes: ['name'],
70
+ transaction
65
71
  });
72
+ const userName = user && user.name ? user.name : "Unknown";
73
+ const deleteData = {
74
+ ...this.job.internal_data,
75
+ requestedIdsToDelete: this.job.internal_data.idsToDelete,
76
+ idsToDelete: this.deletedItemIds,
77
+ };
66
78
  const fraudAuditLog = await models.GeneralDataStore.create({ data: {
67
79
  date: new Date(),
68
- userName: user.name,
80
+ userName,
69
81
  workPackage: this.workPackage,
70
- deleteData: this.job.internal_data
71
- } });
82
+ deleteData
83
+ } }, { transaction });
72
84
  const community = await models.Community.findOne({
73
85
  where: {
74
86
  id: this.workPackage.communityId
75
87
  },
76
- attributes: ['data', 'id']
88
+ attributes: ['data', 'id'],
89
+ transaction
77
90
  });
91
+ if (!community) {
92
+ throw new Error("Community not found for fraud audit log");
93
+ }
78
94
  if (!community.data) {
79
95
  community.data = {};
80
96
  }
@@ -84,10 +100,10 @@ class FraudDeleteBase extends FraudBase {
84
100
  community.data.fraudDeletionsAuditLogs.push({
85
101
  logId: fraudAuditLog.id,
86
102
  date: fraudAuditLog.data.date,
87
- userName: user.name
103
+ userName
88
104
  });
89
105
  community.changed('data', true);
90
- await community.save();
106
+ await community.save({ transaction });
91
107
  resolve();
92
108
  }
93
109
  catch (error) {
@@ -109,13 +125,13 @@ class FraudDeleteBase extends FraudBase {
109
125
  getTopItems(items, type) {
110
126
  return this.setupTopItems(items);
111
127
  }
112
- async destroyAllItems(chunks) {
128
+ async destroyAllItems(chunks, transaction) {
113
129
  return await new Promise(async (resolve, reject) => {
114
130
  try {
115
131
  const progressAdvanceForChunk = 75 / 10;
116
132
  let progress = 25;
117
133
  for (let c = 0; c < chunks.length; c++) {
118
- await this.destroyChunkItems(chunks[c]);
134
+ await this.destroyChunkItems(chunks[c], transaction);
119
135
  progress = Math.round(Math.min(80, progress += progressAdvanceForChunk));
120
136
  await models.AcBackgroundJob.updateProgressAsync(this.workPackage.jobId, progress);
121
137
  }
@@ -126,7 +142,7 @@ class FraudDeleteBase extends FraudBase {
126
142
  }
127
143
  });
128
144
  }
129
- async deleteData() {
145
+ async deleteData(transaction) {
130
146
  return await new Promise(async (resolve, reject) => {
131
147
  try {
132
148
  const keys = Object.keys(this.dataToProcess);
@@ -134,7 +150,8 @@ class FraudDeleteBase extends FraudBase {
134
150
  for (let c = 0; c < keys.length; c++) {
135
151
  itemsToDelete = itemsToDelete.concat(this.getAllItemsExceptOne(this.dataToProcess[keys[c]].items));
136
152
  }
137
- await this.destroyAllItems(this.sliceIntoChunks(itemsToDelete, 100));
153
+ this.deletedItemIds = itemsToDelete.map(item => item.id);
154
+ await this.destroyAllItems(this.sliceIntoChunks(itemsToDelete, 100), transaction);
138
155
  resolve();
139
156
  }
140
157
  catch (error) {
@@ -142,7 +159,7 @@ class FraudDeleteBase extends FraudBase {
142
159
  }
143
160
  });
144
161
  }
145
- async recountPosts() {
162
+ async recountPosts(transaction) {
146
163
  return await new Promise(async (resolve, reject) => {
147
164
  recountPosts(this.postsToRecount, error => {
148
165
  if (error) {
@@ -151,10 +168,10 @@ class FraudDeleteBase extends FraudBase {
151
168
  else {
152
169
  resolve();
153
170
  }
154
- });
171
+ }, transaction);
155
172
  });
156
173
  }
157
- async recountPoints() {
174
+ async recountPoints(transaction) {
158
175
  return await new Promise(async (resolve, reject) => {
159
176
  recountPoints(this.pointsToRecount, error => {
160
177
  if (error) {
@@ -163,10 +180,10 @@ class FraudDeleteBase extends FraudBase {
163
180
  else {
164
181
  resolve();
165
182
  }
166
- });
183
+ }, transaction);
167
184
  });
168
185
  }
169
- async recountCommunity() {
186
+ async recountCommunity(transaction) {
170
187
  return await new Promise(async (resolve, reject) => {
171
188
  recountCommunity(this.workPackage.communityId, error => {
172
189
  if (error) {
@@ -175,7 +192,7 @@ class FraudDeleteBase extends FraudBase {
175
192
  else {
176
193
  resolve();
177
194
  }
178
- });
195
+ }, transaction);
179
196
  });
180
197
  }
181
198
  async deleteItems() {
@@ -189,15 +206,17 @@ class FraudDeleteBase extends FraudBase {
189
206
  });
190
207
  this.items = await this.getItemsById();
191
208
  this.setupDataToProcess();
192
- await this.deleteData();
193
- await this.createAuditLog();
194
- if (this.postsToRecount.length > 0) {
195
- await this.recountPosts();
196
- }
197
- if (this.pointsToRecount.length > 0) {
198
- await this.recountPoints();
199
- }
200
- await this.recountCommunity();
209
+ await models.sequelize.transaction(async (transaction) => {
210
+ await this.deleteData(transaction);
211
+ await this.createAuditLog(transaction);
212
+ if (this.postsToRecount.length > 0) {
213
+ await this.recountPosts(transaction);
214
+ }
215
+ if (this.pointsToRecount.length > 0) {
216
+ await this.recountPoints(transaction);
217
+ }
218
+ await this.recountCommunity(transaction);
219
+ });
201
220
  await models.AcBackgroundJob.updateProgressAsync(this.workPackage.jobId, 100);
202
221
  resolve();
203
222
  }
@@ -2,20 +2,22 @@ export = FraudDeleteBase;
2
2
  declare class FraudDeleteBase extends FraudBase {
3
3
  postsToRecount: any[];
4
4
  pointsToRecount: any[];
5
+ deletedItemIds: any[];
5
6
  job: any;
6
7
  sliceIntoChunks(arr: any, chunkSize: any): any[];
7
8
  getItemsById(): Promise<null>;
8
9
  destroyChunkItems(chunks: any): Promise<void>;
10
+ getUserEmail(item: any): any;
9
11
  getAllItemsExceptOne(items: any): any;
10
- createAuditLog(): Promise<any>;
12
+ createAuditLog(transaction: any): Promise<any>;
11
13
  getAllowedSingleDelete(): boolean;
12
14
  getMomentInYourPriorities(): number;
13
15
  getTopItems(items: any, type: any): any[];
14
- destroyAllItems(chunks: any): Promise<any>;
15
- deleteData(): Promise<any>;
16
- recountPosts(): Promise<any>;
17
- recountPoints(): Promise<any>;
18
- recountCommunity(): Promise<any>;
16
+ destroyAllItems(chunks: any, transaction: any): Promise<any>;
17
+ deleteData(transaction: any): Promise<any>;
18
+ recountPosts(transaction: any): Promise<any>;
19
+ recountPoints(transaction: any): Promise<any>;
20
+ recountCommunity(transaction: any): Promise<any>;
19
21
  deleteItems(): Promise<any>;
20
22
  }
21
23
  import FraudBase = require("./FraudBase.cjs");
@@ -3,7 +3,7 @@ const _ = require("lodash");
3
3
  const FraudDeleteBase = require('./FraudDeleteBase.cjs');
4
4
  const models = require("../../../../models/index.cjs");
5
5
  class FraudDeleteEndorsements extends FraudDeleteBase {
6
- async destroyChunkItemsByModel(model, items) {
6
+ async destroyChunkItemsByModel(model, items, transaction) {
7
7
  return await new Promise(async (resolve, reject) => {
8
8
  const idsToDestroy = items.map(i => i.id);
9
9
  try {
@@ -37,7 +37,8 @@ class FraudDeleteEndorsements extends FraudDeleteBase {
37
37
  ]
38
38
  }
39
39
  ],
40
- attributes: ['id']
40
+ attributes: ['id'],
41
+ transaction
41
42
  });
42
43
  for (let i = 0; i < items.length; i++) {
43
44
  if (this.postsToRecount.indexOf(items[i].post_id) === -1) {
@@ -51,8 +52,8 @@ class FraudDeleteEndorsements extends FraudDeleteBase {
51
52
  }
52
53
  });
53
54
  }
54
- async destroyChunkItems(items) {
55
- return this.destroyChunkItemsByModel(models.Endorsement, items);
55
+ async destroyChunkItems(items, transaction) {
56
+ return this.destroyChunkItemsByModel(models.Endorsement, items, transaction);
56
57
  }
57
58
  async getModelItemsById(model, getGroup) {
58
59
  return await new Promise(async (resolve, reject) => {
@@ -1,7 +1,7 @@
1
1
  export = FraudDeleteEndorsements;
2
2
  declare class FraudDeleteEndorsements extends FraudDeleteBase {
3
- destroyChunkItemsByModel(model: any, items: any): Promise<any>;
4
- destroyChunkItems(items: any): Promise<any>;
3
+ destroyChunkItemsByModel(model: any, items: any, transaction: any): Promise<any>;
4
+ destroyChunkItems(items: any, transaction: any): Promise<any>;
5
5
  getModelItemsById(model: any, getGroup: any): Promise<any>;
6
6
  getItemsById(): Promise<any>;
7
7
  }
@@ -4,7 +4,7 @@ const FraudDeleteBase = require('./FraudDeleteBase.cjs');
4
4
  const models = require("../../../../models/index.cjs");
5
5
  //TODO: Change to native JS instead of lodash
6
6
  class FraudDeletePointQualities extends FraudDeleteBase {
7
- async destroyChunkItems(items) {
7
+ async destroyChunkItems(items, transaction) {
8
8
  return await new Promise(async (resolve, reject) => {
9
9
  const idsToDestroy = items.map(i => i.id);
10
10
  try {
@@ -44,7 +44,8 @@ class FraudDeletePointQualities extends FraudDeleteBase {
44
44
  ]
45
45
  },
46
46
  ],
47
- attributes: ['id']
47
+ attributes: ['id'],
48
+ transaction
48
49
  });
49
50
  for (let i = 0; i < items.length; i++) {
50
51
  if (this.pointsToRecount.indexOf(items[i].Point.id) === -1) {
@@ -1,6 +1,6 @@
1
1
  export = FraudDeletePointQualities;
2
2
  declare class FraudDeletePointQualities extends FraudDeleteBase {
3
- destroyChunkItems(items: any): Promise<any>;
3
+ destroyChunkItems(items: any, transaction: any): Promise<any>;
4
4
  getItemsById(): Promise<any>;
5
5
  }
6
6
  import FraudDeleteBase = require("./FraudDeleteBase.cjs");
@@ -3,7 +3,7 @@ const _ = require("lodash");
3
3
  const FraudDeleteBase = require('./FraudDeleteBase.cjs');
4
4
  const models = require("../../../../models/index.cjs");
5
5
  class FraudDeletePointQualities extends FraudDeleteBase {
6
- async destroyChunkItems(items) {
6
+ async destroyChunkItems(items, transaction) {
7
7
  return await new Promise(async (resolve, reject) => {
8
8
  const idsToDestroy = items.map(i => i.id);
9
9
  try {
@@ -37,7 +37,8 @@ class FraudDeletePointQualities extends FraudDeleteBase {
37
37
  ]
38
38
  }
39
39
  ],
40
- attributes: ['id']
40
+ attributes: ['id'],
41
+ transaction
41
42
  });
42
43
  for (let i = 0; i < items.length; i++) {
43
44
  if (this.postsToRecount.indexOf(items[i].Post.id) === -1) {
@@ -1,6 +1,6 @@
1
1
  export = FraudDeletePointQualities;
2
2
  declare class FraudDeletePointQualities extends FraudDeleteBase {
3
- destroyChunkItems(items: any): Promise<any>;
3
+ destroyChunkItems(items: any, transaction: any): Promise<any>;
4
4
  getItemsById(): Promise<any>;
5
5
  }
6
6
  import FraudDeleteBase = require("./FraudDeleteBase.cjs");
@@ -3,7 +3,7 @@ const _ = require("lodash");
3
3
  const FraudDeleteEndorsements = require('./FraudDeleteEndorsements.cjs');
4
4
  const models = require("../../../../models/index.cjs");
5
5
  class FraudDeletePosts extends FraudDeleteEndorsements {
6
- async destroyChunkItems(items) {
6
+ async destroyChunkItems(items, transaction) {
7
7
  return await new Promise(async (resolve, reject) => {
8
8
  const idsToDestroy = items.map(i => i.id);
9
9
  try {
@@ -31,7 +31,8 @@ class FraudDeletePosts extends FraudDeleteEndorsements {
31
31
  ]
32
32
  }
33
33
  ],
34
- attributes: ['id']
34
+ attributes: ['id'],
35
+ transaction
35
36
  });
36
37
  resolve();
37
38
  }