@plusscommunities/pluss-maintenance-aws 2.1.44 → 2.1.46

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 (45) hide show
  1. package/createJob.js +201 -114
  2. package/createJobType.js +49 -49
  3. package/db/maintenance/addMaintenanceJob.js +100 -90
  4. package/db/maintenance/editMaintenanceJob.js +22 -12
  5. package/db/maintenance/getJobEmail.js +22 -22
  6. package/deleteJob.js +58 -58
  7. package/deleteJobType.js +40 -40
  8. package/editJob.js +126 -65
  9. package/editJobStatus.js +57 -57
  10. package/editJobType.js +61 -61
  11. package/editNote.js +117 -117
  12. package/feature.config.js +279 -262
  13. package/getData.js +48 -41
  14. package/getJob.js +4 -4
  15. package/getJobType.js +35 -35
  16. package/getJobTypes.js +66 -66
  17. package/getJobs.js +48 -48
  18. package/integration/IntegrationStrategy.js +52 -52
  19. package/integration/archibus/ArchibusStrategy.js +42 -28
  20. package/integration/index.js +19 -19
  21. package/jobChanged.js +88 -89
  22. package/jobTypesChanged.js +52 -39
  23. package/package.json +3 -3
  24. package/requests/assignRequest.js +81 -81
  25. package/requests/getAssignees.js +27 -27
  26. package/requests/getExternalSync.js +100 -100
  27. package/requests/getPropertyRequests.js +89 -0
  28. package/requests/getRequest.js +77 -77
  29. package/requests/getRequests.js +210 -144
  30. package/requests/helper/hasRequestPermission.js +12 -12
  31. package/requests/helper/isValidAssignee.js +10 -10
  32. package/requests/retrySync.js +90 -90
  33. package/requests/setExternalJobId.js +113 -113
  34. package/requests/updatePriority.js +33 -33
  35. package/scheduleJobImport.js +63 -63
  36. package/sendJobEmail.js +105 -104
  37. package/updateData.js +34 -34
  38. package/values.config.a.js +26 -25
  39. package/values.config.default.js +30 -28
  40. package/values.config.enquiry.js +222 -221
  41. package/values.config.feedback.js +194 -193
  42. package/values.config.food.js +29 -28
  43. package/values.config.forms.js +29 -28
  44. package/values.config.js +30 -28
  45. package/watchJobs.js +154 -154
@@ -2,27 +2,27 @@ const indexQuery = require("@plusscommunities/pluss-core-aws/db/common/indexQuer
2
2
  const { values } = require("../../values.config");
3
3
 
4
4
  module.exports = (site, typeName) => {
5
- return new Promise((resolve, reject) => {
6
- const query = {
7
- IndexName: "JobTypeSiteIndex",
8
- KeyConditionExpression: "site = :site and typeName = :typeName",
9
- ExpressionAttributeValues: {
10
- ":site": site,
11
- ":typeName": typeName,
12
- },
13
- };
5
+ return new Promise((resolve, reject) => {
6
+ const query = {
7
+ IndexName: "JobTypeSiteIndex",
8
+ KeyConditionExpression: "site = :site and typeName = :typeName",
9
+ ExpressionAttributeValues: {
10
+ ":site": site,
11
+ ":typeName": typeName,
12
+ },
13
+ };
14
14
 
15
- console.log("running jobType email query");
16
- console.log(query);
17
- indexQuery(values.tableNameJobTypes, query)
18
- .then((data) => {
19
- console.log("successful query");
20
- resolve(data.Items[0]);
21
- })
22
- .catch((error) => {
23
- console.log("query failed");
24
- console.log(error);
25
- reject();
26
- });
27
- });
15
+ console.log("running jobType email query");
16
+ console.log(query);
17
+ indexQuery(values.tableNameJobTypes, query)
18
+ .then((data) => {
19
+ console.log("successful query");
20
+ resolve(data.Items[0]);
21
+ })
22
+ .catch((error) => {
23
+ console.log("query failed");
24
+ console.log(error);
25
+ reject();
26
+ });
27
+ });
28
28
  };
package/deleteJob.js CHANGED
@@ -10,65 +10,65 @@ const getUserPreviewFromReq = require("@plusscommunities/pluss-core-aws/helper/g
10
10
  const { values } = require("./values.config");
11
11
 
12
12
  module.exports.deleteJob = (event, context, callback) => {
13
- init(config);
14
- const data = getBody(event);
13
+ init(config);
14
+ const data = getBody(event);
15
15
 
16
- if (!data.site || !data.id) {
17
- callback(
18
- null,
19
- generateJsonResponse(422, { error: "No site or id attached" })
20
- );
21
- return;
22
- }
16
+ if (!data.site || !data.id) {
17
+ callback(
18
+ null,
19
+ generateJsonResponse(422, { error: "No site or id attached" }),
20
+ );
21
+ return;
22
+ }
23
23
 
24
- validateMasterAuth(event, values.permissionMaintenanceTracking).then(
25
- (authorised) => {
26
- if (!authorised) {
27
- console.error("Authorization not valid");
28
- callback(
29
- null,
30
- generateJsonResponse(403, {
31
- error: {
32
- message: "Authorization not valid.",
33
- },
34
- })
35
- );
36
- return;
37
- }
24
+ validateMasterAuth(event, values.permissionMaintenanceTracking).then(
25
+ (authorised) => {
26
+ if (!authorised) {
27
+ console.error("Authorization not valid");
28
+ callback(
29
+ null,
30
+ generateJsonResponse(403, {
31
+ error: {
32
+ message: "Authorization not valid.",
33
+ },
34
+ }),
35
+ );
36
+ return;
37
+ }
38
38
 
39
- getRef(values.tableNameMaintenance, "id", data.id).then((result) => {
40
- if (result.site !== data.site) {
41
- return callback(
42
- null,
43
- generateJsonResponse(422, {
44
- error: {
45
- message: "Incorrect site.",
46
- },
47
- })
48
- );
49
- }
50
- deleteRef(values.tableNameMaintenance, "id", data.id)
51
- .then(() => {
52
- getUserPreviewFromReq(event).then((user) => {
53
- publishActivity(
54
- values.activityDeleteMaintenanceJob,
55
- data.site,
56
- data.id,
57
- user,
58
- {
59
- title: result.title,
60
- description: result.description,
61
- }
62
- );
63
- });
64
- callback(null, generateJsonResponse(200, { success: true }));
65
- return;
66
- })
67
- .catch((error) => {
68
- callback(null, generateJsonResponse(422, { error }));
69
- return;
70
- });
71
- });
72
- }
73
- );
39
+ getRef(values.tableNameMaintenance, "id", data.id).then((result) => {
40
+ if (result.site !== data.site) {
41
+ return callback(
42
+ null,
43
+ generateJsonResponse(422, {
44
+ error: {
45
+ message: "Incorrect site.",
46
+ },
47
+ }),
48
+ );
49
+ }
50
+ deleteRef(values.tableNameMaintenance, "id", data.id)
51
+ .then(() => {
52
+ getUserPreviewFromReq(event).then((user) => {
53
+ publishActivity(
54
+ values.activityDeleteMaintenanceJob,
55
+ data.site,
56
+ data.id,
57
+ user,
58
+ {
59
+ title: result.title,
60
+ description: result.description,
61
+ },
62
+ );
63
+ });
64
+ callback(null, generateJsonResponse(200, { success: true }));
65
+ return;
66
+ })
67
+ .catch((error) => {
68
+ callback(null, generateJsonResponse(422, { error }));
69
+ return;
70
+ });
71
+ });
72
+ },
73
+ );
74
74
  };
package/deleteJobType.js CHANGED
@@ -8,47 +8,47 @@ const getRef = require("@plusscommunities/pluss-core-aws/db/common/getRef");
8
8
  const { values } = require("./values.config");
9
9
 
10
10
  module.exports.deleteJobType = (event, context, callback) => {
11
- init(config);
12
- const data = getBody(event);
11
+ init(config);
12
+ const data = getBody(event);
13
13
 
14
- if (!data.site || !data.id) {
15
- return callback(
16
- null,
17
- generateJsonResponse(422, { error: "No site or id attached" })
18
- );
19
- }
14
+ if (!data.site || !data.id) {
15
+ return callback(
16
+ null,
17
+ generateJsonResponse(422, { error: "No site or id attached" }),
18
+ );
19
+ }
20
20
 
21
- validateMasterAuth(event, values.permissionMaintenanceTypes).then(
22
- (authorised) => {
23
- if (!authorised) {
24
- console.error("Authorization not valid");
25
- return callback(
26
- null,
27
- generateJsonResponse(422, {
28
- error: { message: "Admin - Create User - not authorized." },
29
- })
30
- );
31
- }
21
+ validateMasterAuth(event, values.permissionMaintenanceTypes).then(
22
+ (authorised) => {
23
+ if (!authorised) {
24
+ console.error("Authorization not valid");
25
+ return callback(
26
+ null,
27
+ generateJsonResponse(422, {
28
+ error: { message: "Admin - Create User - not authorized." },
29
+ }),
30
+ );
31
+ }
32
32
 
33
- getRef(values.tableNameJobTypes, "id", data.id).then((result) => {
34
- if (result.site !== data.site) {
35
- return callback(
36
- null,
37
- generateJsonResponse(422, {
38
- error: {
39
- message: "Incorrect site.",
40
- },
41
- })
42
- );
43
- }
44
- deleteRef(values.tableNameJobTypes, "id", data.id)
45
- .then(() => {
46
- return callback(null, generateJsonResponse(200, { success: true }));
47
- })
48
- .catch((error) => {
49
- return callback(null, generateJsonResponse(422, { error }));
50
- });
51
- });
52
- }
53
- );
33
+ getRef(values.tableNameJobTypes, "id", data.id).then((result) => {
34
+ if (result.site !== data.site) {
35
+ return callback(
36
+ null,
37
+ generateJsonResponse(422, {
38
+ error: {
39
+ message: "Incorrect site.",
40
+ },
41
+ }),
42
+ );
43
+ }
44
+ deleteRef(values.tableNameJobTypes, "id", data.id)
45
+ .then(() => {
46
+ return callback(null, generateJsonResponse(200, { success: true }));
47
+ })
48
+ .catch((error) => {
49
+ return callback(null, generateJsonResponse(422, { error }));
50
+ });
51
+ });
52
+ },
53
+ );
54
54
  };
package/editJob.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const _ = require("lodash");
2
2
  const config = require("./config.json");
3
3
  const { init } = require("@plusscommunities/pluss-core-aws/config");
4
- const { getBody } = require("@plusscommunities/pluss-core-aws/helper");
4
+ const { getBody, log } = require("@plusscommunities/pluss-core-aws/helper");
5
5
  const generateJsonResponse = require("@plusscommunities/pluss-core-aws/helper/generateJsonResponse");
6
6
  const sendJobEmail = require("./sendJobEmail");
7
7
  const getRef = require("@plusscommunities/pluss-core-aws/db/common/getRef");
@@ -10,74 +10,135 @@ const editMaintenanceJob = require("./db/maintenance/editMaintenanceJob");
10
10
  const { getConfig } = require("@plusscommunities/pluss-core-aws/config");
11
11
  const hasRequestPermission = require("./requests/helper/hasRequestPermission");
12
12
  const getUserPreviewFromReq = require("@plusscommunities/pluss-core-aws/helper/getUserPreviewFromReq");
13
+ const {
14
+ PropertyRepository,
15
+ } = require("@plusscommunities/pluss-core-aws/db/property/PropertyRepository");
13
16
  const { values } = require("./values.config");
14
17
 
18
+ const properties = new PropertyRepository();
19
+
15
20
  module.exports.editJob = (event, context, callback) => {
16
- init(config);
17
- const data = getBody(event);
21
+ // Avoids waiting on the pooled DB connection to close before returning.
22
+ context.callbackWaitsForEmptyEventLoop = false;
23
+ init(config);
24
+ const data = getBody(event);
18
25
 
19
- if (!data.job) {
20
- return callback(
21
- null,
22
- generateJsonResponse(422, { error: { message: "No data for edit job." } })
23
- );
24
- }
26
+ if (!data.job) {
27
+ return callback(
28
+ null,
29
+ generateJsonResponse(422, {
30
+ error: { message: "No data for edit job." },
31
+ }),
32
+ );
33
+ }
25
34
 
26
- getRef(values.tableNameMaintenance, "id", data.job.id)
27
- .then((prevData) => {
28
- hasRequestPermission(event, prevData).then((authorised) => {
29
- if (!authorised) {
30
- console.error("Authorization not valid");
31
- return callback(
32
- null,
33
- generateJsonResponse(422, {
34
- error: { message: "not authorized." },
35
- })
36
- );
37
- }
38
- getUserPreviewFromReq(event).then((user) => {
39
- editMaintenanceJob(data.job)
40
- .then((result) => {
41
- if (!getConfig().maintenanceInstantComplete) {
42
- sendJobEmail(data.job, true);
43
- publishActivity(
44
- values.activityEditMaintenanceJob,
45
- data.site,
46
- data.job.id,
47
- user,
48
- { title: result.title, description: result.description }
49
- );
50
- }
35
+ getRef(values.tableNameMaintenance, "id", data.job.id)
36
+ .then((prevData) => {
37
+ // Returned so a rejection reaches the outer catch instead of hanging the Lambda.
38
+ return hasRequestPermission(event, prevData).then(async (authorised) => {
39
+ if (!authorised) {
40
+ console.error("Authorization not valid");
41
+ return callback(
42
+ null,
43
+ generateJsonResponse(422, {
44
+ error: { message: "not authorized." },
45
+ }),
46
+ );
47
+ }
48
+ if (values.linkToProperty) {
49
+ // A set propertyId is client input; verify it against the job's own
50
+ // site (the site the edit was authorised for), failing closed.
51
+ if (data.job.propertyId != null) {
52
+ let property;
53
+ try {
54
+ property = await properties.byId({
55
+ site: prevData.site,
56
+ propertyId: data.job.propertyId,
57
+ });
58
+ } catch (error) {
59
+ // A resolver outage is not invalid input.
60
+ log("editJob", "PropertyResolveError", error.message);
61
+ return callback(
62
+ null,
63
+ generateJsonResponse(500, {
64
+ error: { message: "Internal Error" },
65
+ }),
66
+ );
67
+ }
68
+ if (!property) {
69
+ return callback(
70
+ null,
71
+ generateJsonResponse(422, {
72
+ error: { message: "Invalid property for this site" },
73
+ }),
74
+ );
75
+ }
76
+ // Record keeps the verified name so link and label never disagree.
77
+ data.job.propertyName = property.name;
78
+ data.job.room = property.name;
79
+ } else if (
80
+ _.isUndefined(data.job.propertyId) &&
81
+ prevData.propertyId &&
82
+ prevData.propertyName
83
+ ) {
84
+ // An omitted propertyId keeps the link, so the label stays pinned to it.
85
+ data.job.propertyName = prevData.propertyName;
86
+ data.job.room = prevData.propertyName;
87
+ }
88
+ }
89
+ return getUserPreviewFromReq(event).then((user) => {
90
+ return editMaintenanceJob(data.job)
91
+ .then(async (result) => {
92
+ if (!getConfig().maintenanceInstantComplete) {
93
+ // Awaited (allSettled) — the frozen event loop would drop
94
+ // fire-and-forget work, one failure must not strand the other,
95
+ // and a failed side effect must not fail the edit.
96
+ const settled = await Promise.allSettled([
97
+ sendJobEmail(data.job, true),
98
+ publishActivity(
99
+ values.activityEditMaintenanceJob,
100
+ data.site,
101
+ data.job.id,
102
+ user,
103
+ { title: result.title, description: result.description },
104
+ ),
105
+ ]);
106
+ settled
107
+ .filter((r) => r.status === "rejected")
108
+ .forEach((r) => {
109
+ log("editJob", "SideEffectError", r.reason);
110
+ });
111
+ }
51
112
 
52
- return callback(
53
- null,
54
- generateJsonResponse(200, {
55
- success: true,
56
- job: result,
57
- })
58
- );
59
- })
60
- .catch((error) => {
61
- console.log(error);
62
- console.error("Failed to edit maintenance node -->", data.job.id);
63
- return callback(
64
- null,
65
- generateJsonResponse(422, {
66
- error,
67
- })
68
- );
69
- });
70
- });
71
- });
72
- })
73
- .catch((error) => {
74
- console.log("Fail on edit job authentication");
75
- console.log(error);
76
- return callback(
77
- null,
78
- generateJsonResponse(422, {
79
- error,
80
- })
81
- );
82
- });
113
+ return callback(
114
+ null,
115
+ generateJsonResponse(200, {
116
+ success: true,
117
+ job: result,
118
+ }),
119
+ );
120
+ })
121
+ .catch((error) => {
122
+ console.log(error);
123
+ console.error("Failed to edit maintenance node -->", data.job.id);
124
+ return callback(
125
+ null,
126
+ generateJsonResponse(422, {
127
+ error,
128
+ }),
129
+ );
130
+ });
131
+ });
132
+ });
133
+ })
134
+ .catch((error) => {
135
+ console.log("Fail on edit job authentication");
136
+ console.log(error);
137
+ return callback(
138
+ null,
139
+ generateJsonResponse(422, {
140
+ error,
141
+ }),
142
+ );
143
+ });
83
144
  };
package/editJobStatus.js CHANGED
@@ -14,68 +14,68 @@ const hasRequestPermission = require("./requests/helper/hasRequestPermission");
14
14
  const { values } = require("./values.config");
15
15
 
16
16
  module.exports.editJobStatus = async (event, context, callback) => {
17
- init(config);
18
- const data = getBody(event);
17
+ init(config);
18
+ const data = getBody(event);
19
19
 
20
- try {
21
- const job = await getRef(values.tableNameMaintenance, "id", data.id);
22
- const authorised = await hasRequestPermission(event, job);
23
- if (!authorised) {
24
- console.error("Authorization not valid");
25
- return callback(
26
- null,
27
- generateJsonResponse(403, {
28
- error: {
29
- message: "Authorization not valid.",
30
- },
31
- })
32
- );
33
- }
20
+ try {
21
+ const job = await getRef(values.tableNameMaintenance, "id", data.id);
22
+ const authorised = await hasRequestPermission(event, job);
23
+ if (!authorised) {
24
+ console.error("Authorization not valid");
25
+ return callback(
26
+ null,
27
+ generateJsonResponse(403, {
28
+ error: {
29
+ message: "Authorization not valid.",
30
+ },
31
+ }),
32
+ );
33
+ }
34
34
 
35
- const user = await getUserPreviewFromReq(event);
35
+ const user = await getUserPreviewFromReq(event);
36
36
 
37
- // Update history
38
- if (!job.history) job.history = [];
39
- job.history.push({
40
- timestamp: moment.utc().valueOf(),
41
- status: data.status,
42
- user,
43
- });
44
- job.status = data.status;
45
- const result = await editMaintenanceJob(job);
37
+ // Update history
38
+ if (!job.history) job.history = [];
39
+ job.history.push({
40
+ timestamp: moment.utc().valueOf(),
41
+ status: data.status,
42
+ user,
43
+ });
44
+ job.status = data.status;
45
+ const result = await editMaintenanceJob(job);
46
46
 
47
- // Log activity & notify
48
- publishActivity(
49
- values.activityMaintenanceJobStatusChanged,
50
- result.site,
51
- result.id,
52
- user,
53
- { title: result.title, status: result.status }
54
- );
47
+ // Log activity & notify
48
+ publishActivity(
49
+ values.activityMaintenanceJobStatusChanged,
50
+ result.site,
51
+ result.id,
52
+ user,
53
+ { title: result.title, status: result.status },
54
+ );
55
55
 
56
- if (job.status === "Completed") {
57
- logAnalyticsActivity(
58
- `RequestCompleted`,
59
- values.entityKey,
60
- result.site,
61
- user,
62
- result.id
63
- );
64
- }
56
+ if (job.status === "Completed") {
57
+ logAnalyticsActivity(
58
+ `RequestCompleted`,
59
+ values.entityKey,
60
+ result.site,
61
+ user,
62
+ result.id,
63
+ );
64
+ }
65
65
 
66
- if (result.userID) {
67
- publishNotifications(
68
- [result.userID],
69
- values.activityMaintenanceJobStatusChanged,
70
- result.site,
71
- result.id,
72
- result,
73
- true
74
- );
75
- }
66
+ if (result.userID) {
67
+ publishNotifications(
68
+ [result.userID],
69
+ values.activityMaintenanceJobStatusChanged,
70
+ result.site,
71
+ result.id,
72
+ result,
73
+ true,
74
+ );
75
+ }
76
76
 
77
- callback(null, generateJsonResponse(200, { success: true, job: result }));
78
- } catch (error) {
79
- callback(null, generateJsonResponse(422, { error }));
80
- }
77
+ callback(null, generateJsonResponse(200, { success: true, job: result }));
78
+ } catch (error) {
79
+ callback(null, generateJsonResponse(422, { error }));
80
+ }
81
81
  };