@plusscommunities/pluss-maintenance-aws-a 2.1.31 → 2.1.34-beta.0
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/feature.config.js +8 -0
- package/integration/IntegrationStrategy.js +6 -0
- package/integration/archibus/ArchibusStrategy.js +56 -1
- package/jobChanged.js +1 -1
- package/jobTypesChanged.js +55 -0
- package/package.json +3 -3
- package/requests/retrySync.js +161 -0
- package/requests/setExternalJobId.js +1 -0
- package/scheduleJobImport.js +9 -3
- package/updateData.js +4 -0
- package/values.config.a.js +1 -0
- package/values.config.default.js +1 -0
- package/values.config.enquiry.js +1 -0
- package/values.config.feedback.js +1 -0
- package/values.config.food.js +1 -0
- package/values.config.forms.js +1 -0
- package/values.config.js +1 -0
- package/package-lock.json +0 -8051
package/feature.config.js
CHANGED
|
@@ -155,6 +155,14 @@ exports.serverless = {
|
|
|
155
155
|
timeout: 300,
|
|
156
156
|
table: values.tableKeyMaintenance,
|
|
157
157
|
},
|
|
158
|
+
{
|
|
159
|
+
name: "jobTypesChanged",
|
|
160
|
+
file: "jobTypesChanged",
|
|
161
|
+
function: "jobTypesChanged",
|
|
162
|
+
memorySize: 512,
|
|
163
|
+
timeout: 60,
|
|
164
|
+
table: values.tableKeyJobTypes,
|
|
165
|
+
},
|
|
158
166
|
],
|
|
159
167
|
schedules: [
|
|
160
168
|
{
|
|
@@ -45,6 +45,12 @@ class IntegrationStrategy {
|
|
|
45
45
|
onCompleteRequest = async (request) => {
|
|
46
46
|
return null;
|
|
47
47
|
};
|
|
48
|
+
|
|
49
|
+
// TODO: Remove once all existing records have ActiveEntityType (PC-1382)
|
|
50
|
+
// backfills ActiveEntityType on existing externalentities records for the sparse GSI migration
|
|
51
|
+
backfillActiveEntityType = async (timeout) => {
|
|
52
|
+
return { backfillCount: 0, complete: true };
|
|
53
|
+
};
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
module.exports = IntegrationStrategy;
|
|
@@ -23,6 +23,7 @@ class ArchibusStrategy extends IntegrationStrategy {
|
|
|
23
23
|
this.host = url.host;
|
|
24
24
|
|
|
25
25
|
this.statusMap = config.StatusMap;
|
|
26
|
+
this.completedStatuses = config.CompletedStatuses ?? [];
|
|
26
27
|
this.siteMap = config.SiteMap ?? {};
|
|
27
28
|
this.buildingCodes = [];
|
|
28
29
|
}
|
|
@@ -51,7 +52,7 @@ class ArchibusStrategy extends IntegrationStrategy {
|
|
|
51
52
|
* @returns {Number} The refresh interval in milliseconds
|
|
52
53
|
*/
|
|
53
54
|
getRefreshInterval = () => {
|
|
54
|
-
return
|
|
55
|
+
return 60 * 60 * 1000; // 60 minutes
|
|
55
56
|
};
|
|
56
57
|
|
|
57
58
|
/**
|
|
@@ -125,6 +126,7 @@ class ArchibusStrategy extends IntegrationStrategy {
|
|
|
125
126
|
RowId: `${this.getEntityType()}_${response.data.wrId}`,
|
|
126
127
|
LastUpdated: moment().valueOf(),
|
|
127
128
|
EntityType: this.getEntityType(),
|
|
129
|
+
ActiveEntityType: this.getEntityType(),
|
|
128
130
|
InternalId: request.id,
|
|
129
131
|
ExternalId: response.data.wrId,
|
|
130
132
|
TrackedData: {},
|
|
@@ -304,6 +306,17 @@ class ArchibusStrategy extends IntegrationStrategy {
|
|
|
304
306
|
}
|
|
305
307
|
);
|
|
306
308
|
|
|
309
|
+
// If the external status is terminal, remove ActiveEntityType to exclude from sparse GSI
|
|
310
|
+
if (this.completedStatuses.includes(request.status)) {
|
|
311
|
+
log("Archibus:RefreshFromSource", "TerminalStatus", request.status, logId);
|
|
312
|
+
const entityRowId = `${this.getEntityType()}_${externalId}`;
|
|
313
|
+
const entity = await getRef("externalentities", "RowId", entityRowId);
|
|
314
|
+
if (entity && entity.ActiveEntityType) {
|
|
315
|
+
delete entity.ActiveEntityType;
|
|
316
|
+
await updateRef("externalentities", entity);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
307
320
|
log("Archibus:RefreshFromSource", "Result", true, logId);
|
|
308
321
|
return true;
|
|
309
322
|
};
|
|
@@ -630,6 +643,48 @@ class ArchibusStrategy extends IntegrationStrategy {
|
|
|
630
643
|
onCompleteRequest = async (request) => {
|
|
631
644
|
return true;
|
|
632
645
|
};
|
|
646
|
+
|
|
647
|
+
// TODO: Remove once all existing records have ActiveEntityType (PC-1382)
|
|
648
|
+
// Backfills ActiveEntityType on existing externalentities records for the sparse GSI migration.
|
|
649
|
+
// Runs as part of the cron job after normal processing, respecting the given timeout.
|
|
650
|
+
backfillActiveEntityType = async (timeout) => {
|
|
651
|
+
const logId = log("Archibus:Backfill", "Start", true);
|
|
652
|
+
const startTime = moment().valueOf();
|
|
653
|
+
let backfillCount = 0;
|
|
654
|
+
let lastEvaluatedKey = null;
|
|
655
|
+
|
|
656
|
+
do {
|
|
657
|
+
const query = {
|
|
658
|
+
IndexName: "EntityTypeIndex",
|
|
659
|
+
KeyConditionExpression: "EntityType = :entityType",
|
|
660
|
+
ExpressionAttributeValues: {
|
|
661
|
+
":entityType": this.getEntityType(),
|
|
662
|
+
},
|
|
663
|
+
Limit: 25,
|
|
664
|
+
};
|
|
665
|
+
if (lastEvaluatedKey) query.ExclusiveStartKey = lastEvaluatedKey;
|
|
666
|
+
|
|
667
|
+
const result = await indexQuery("externalentities", query);
|
|
668
|
+
lastEvaluatedKey = result.LastEvaluatedKey;
|
|
669
|
+
|
|
670
|
+
for (const item of result.Items) {
|
|
671
|
+
if (!item.ActiveEntityType) {
|
|
672
|
+
// Skip records already in a terminal status — they should stay out of the sparse GSI
|
|
673
|
+
const trackedStatus = item.TrackedData && item.TrackedData.status;
|
|
674
|
+
if (trackedStatus && this.completedStatuses.includes(trackedStatus)) {
|
|
675
|
+
continue;
|
|
676
|
+
}
|
|
677
|
+
item.ActiveEntityType = item.EntityType;
|
|
678
|
+
await updateRef("externalentities", item);
|
|
679
|
+
backfillCount++;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
} while (lastEvaluatedKey && moment().valueOf() < startTime + timeout);
|
|
683
|
+
|
|
684
|
+
const complete = !lastEvaluatedKey;
|
|
685
|
+
log("Archibus:Backfill", "End", { backfillCount, complete }, logId);
|
|
686
|
+
return { backfillCount, complete };
|
|
687
|
+
};
|
|
633
688
|
}
|
|
634
689
|
|
|
635
690
|
module.exports = ArchibusStrategy;
|
package/jobChanged.js
CHANGED
|
@@ -43,7 +43,7 @@ const onNotesAdded = async (request) => {
|
|
|
43
43
|
const checkIntegrationActions = async (request, prevRequest) => {
|
|
44
44
|
if (
|
|
45
45
|
request.ExtCreateRetry &&
|
|
46
|
-
request.ExtCreateRetry
|
|
46
|
+
request.ExtCreateRetry > prevRequest.ExtCreateRetry
|
|
47
47
|
) {
|
|
48
48
|
log("checkIntegrationActions", "Retrying", true);
|
|
49
49
|
await pushRequestToIntegration(request);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DynamoDB Stream Handler for JobTypes changes
|
|
3
|
+
*
|
|
4
|
+
* Republishes any templates using this site as source.
|
|
5
|
+
* Only notifies siteConfigs for variants with enableSiteConfigsPropagation: true
|
|
6
|
+
* (maintenance and maintenanceForms). Other variants (feedback, enquiry) are excluded.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const { Marshaller } = require("@aws/dynamodb-auto-marshaller");
|
|
10
|
+
const marshaller = new Marshaller();
|
|
11
|
+
const { log } = require("@plusscommunities/pluss-core-aws/helper");
|
|
12
|
+
const notifySiteConfigs = require("@plusscommunities/pluss-core-aws/helper/notifySiteConfigs");
|
|
13
|
+
const { values } = require("./values.config");
|
|
14
|
+
|
|
15
|
+
module.exports.jobTypesChanged = async (event, context, callback) => {
|
|
16
|
+
const logId = log("jobTypesChanged", "Start", { recordCount: event.Records.length, serviceKey: values.serviceKey });
|
|
17
|
+
|
|
18
|
+
// Check if this variant supports siteConfigs propagation
|
|
19
|
+
if (!values.enableSiteConfigsPropagation) {
|
|
20
|
+
log("jobTypesChanged", "SkipPropagation", { serviceKey: values.serviceKey }, logId);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const promises = [];
|
|
25
|
+
|
|
26
|
+
event.Records.forEach((record) => {
|
|
27
|
+
log("jobTypesChanged", "Record", { eventName: record.eventName }, logId);
|
|
28
|
+
|
|
29
|
+
if (record.eventName === "INSERT") {
|
|
30
|
+
const data = marshaller.unmarshallItem(record.dynamodb.NewImage);
|
|
31
|
+
log("jobTypesChanged", "Insert", { id: data.id, site: data.site }, logId);
|
|
32
|
+
|
|
33
|
+
if (data.site) {
|
|
34
|
+
promises.push(notifySiteConfigs(data.site, logId));
|
|
35
|
+
}
|
|
36
|
+
} else if (record.eventName === "MODIFY") {
|
|
37
|
+
const data = marshaller.unmarshallItem(record.dynamodb.NewImage);
|
|
38
|
+
log("jobTypesChanged", "Modify", { id: data.id, site: data.site }, logId);
|
|
39
|
+
|
|
40
|
+
if (data.site) {
|
|
41
|
+
promises.push(notifySiteConfigs(data.site, logId));
|
|
42
|
+
}
|
|
43
|
+
} else if (record.eventName === "REMOVE") {
|
|
44
|
+
const previousData = marshaller.unmarshallItem(record.dynamodb.OldImage);
|
|
45
|
+
log("jobTypesChanged", "Remove", { id: previousData.id, site: previousData.site }, logId);
|
|
46
|
+
|
|
47
|
+
if (previousData.site) {
|
|
48
|
+
promises.push(notifySiteConfigs(previousData.site, logId));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
await Promise.all(promises);
|
|
54
|
+
log("jobTypesChanged", "Complete", { promiseCount: promises.length }, logId);
|
|
55
|
+
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plusscommunities/pluss-maintenance-aws-a",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.34-beta.0",
|
|
4
4
|
"description": "Extension package to enable maintenance on Pluss Communities Platform",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"gc": "node ../../tools/gc ./",
|
|
7
|
-
"gs": "node ../../tools/gs ./ ../../
|
|
7
|
+
"gs": "node ../../tools/gs ./ ../../strings/serverless.yml",
|
|
8
8
|
"betapatch": "npm version prepatch --preid=beta",
|
|
9
9
|
"patch": "npm version patch",
|
|
10
10
|
"deploy": "npm run gc && npm run gs && serverless deploy",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"license": "ISC",
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@aws/dynamodb-auto-marshaller": "^0.7.1",
|
|
27
|
-
"@plusscommunities/pluss-core-aws": "2.0.
|
|
27
|
+
"@plusscommunities/pluss-core-aws": "2.0.24-beta.0",
|
|
28
28
|
"amazon-cognito-identity-js": "^2.0.19",
|
|
29
29
|
"aws-sdk": "^2.1591.0",
|
|
30
30
|
"axios": "^1.6.8",
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
const moment = require("moment");
|
|
2
|
+
const getRef = require("@plusscommunities/pluss-core-aws/db/common/getRef");
|
|
3
|
+
const editRef = require("@plusscommunities/pluss-core-aws/db/common/editRef");
|
|
4
|
+
const validateMasterAuth = require("@plusscommunities/pluss-core-aws/helper/auth/validateMasterAuth");
|
|
5
|
+
const { log } = require("@plusscommunities/pluss-core-aws/helper");
|
|
6
|
+
const { values } = require("../values.config");
|
|
7
|
+
const { getStrategy } = require("../integration");
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Checks if a job has already been successfully synced to an external system.
|
|
11
|
+
* Uses two methods to determine sync status:
|
|
12
|
+
* 1. Checks job history for an "ExternalIDSet" entry
|
|
13
|
+
* 2. Queries the integration strategy's getExternalId method if available
|
|
14
|
+
*
|
|
15
|
+
* @param {Object} job - The maintenance job record
|
|
16
|
+
* @param {string} job.id - The job's internal ID
|
|
17
|
+
* @param {string} job.site - The site the job belongs to
|
|
18
|
+
* @param {Array} [job.history] - The job's history entries
|
|
19
|
+
* @param {string} logId - The log ID for tracing
|
|
20
|
+
* @returns {Promise<boolean>} True if the job has already been synced
|
|
21
|
+
*/
|
|
22
|
+
const isAlreadySynced = async (job, logId) => {
|
|
23
|
+
const history = job.history || [];
|
|
24
|
+
const hasSuccessfulSync = history.some(
|
|
25
|
+
(entry) => entry.EntryType === "ExternalIDSet"
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
if (hasSuccessfulSync) {
|
|
29
|
+
log("isAlreadySynced", "FoundInHistory", true, logId);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const integrationStrategy = await getStrategy(job.site);
|
|
35
|
+
if (integrationStrategy.getExternalId) {
|
|
36
|
+
const externalId = await integrationStrategy.getExternalId(job);
|
|
37
|
+
if (externalId) {
|
|
38
|
+
log("isAlreadySynced", "FoundViaStrategy", externalId, logId);
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
} catch (error) {
|
|
43
|
+
log("isAlreadySynced", "StrategyCheckError", error.message, logId);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return false;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Initiates a retry of the external system sync for a maintenance job.
|
|
51
|
+
* This endpoint sets the ExtCreateRetry field on the job, which triggers
|
|
52
|
+
* the jobChanged stream handler to attempt pushing the request to the
|
|
53
|
+
* external integration system again.
|
|
54
|
+
*
|
|
55
|
+
* @param {Object} event - The Lambda event object
|
|
56
|
+
* @param {Object} event.headers - Request headers containing auth credentials
|
|
57
|
+
* @param {Object} data - The request body
|
|
58
|
+
* @param {string} data.id - The ID of the job to retry sync for
|
|
59
|
+
* @returns {Promise<Object>} Response object with status and data
|
|
60
|
+
* @returns {number} returns.status - HTTP status code
|
|
61
|
+
* @returns {Object} returns.data - Response payload
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* // Request
|
|
65
|
+
* POST /maintenance/update/retrysync
|
|
66
|
+
* { "id": "job-uuid-here" }
|
|
67
|
+
*
|
|
68
|
+
* // Success Response (200)
|
|
69
|
+
* {
|
|
70
|
+
* "success": true,
|
|
71
|
+
* "message": "Sync retry initiated. Check back shortly for results.",
|
|
72
|
+
* "job": { ... }
|
|
73
|
+
* }
|
|
74
|
+
*
|
|
75
|
+
* // Error Responses
|
|
76
|
+
* // 400 - Job already synced to external system
|
|
77
|
+
* // 403 - Not authorised
|
|
78
|
+
* // 404 - Job not found
|
|
79
|
+
* // 422 - Missing required field: id
|
|
80
|
+
* // 500 - Internal error
|
|
81
|
+
*/
|
|
82
|
+
module.exports = async (event, data) => {
|
|
83
|
+
const action = "retrySync";
|
|
84
|
+
const logId = log(action, "Input", data);
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
// Validate required fields
|
|
88
|
+
if (!data.id) {
|
|
89
|
+
return {
|
|
90
|
+
status: 422,
|
|
91
|
+
data: { error: "Missing required field: id" },
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Fetch the job record
|
|
96
|
+
let job;
|
|
97
|
+
try {
|
|
98
|
+
job = await getRef(values.tableNameMaintenance, "id", data.id);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
log(action, "Error:JobNotFound", { error: error.message }, logId);
|
|
101
|
+
return { status: 404, data: { error: "Job not found" } };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!job) {
|
|
105
|
+
log(action, "JobNotFound", { id: data.id }, logId);
|
|
106
|
+
return { status: 404, data: { error: "Job not found" } };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Validate user has permission to manage maintenance for this site
|
|
110
|
+
const authorised = await validateMasterAuth(
|
|
111
|
+
event,
|
|
112
|
+
values.permissionMaintenanceTracking,
|
|
113
|
+
job.site
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
if (!authorised) {
|
|
117
|
+
log(action, "NotAuthorised", { site: job.site }, logId);
|
|
118
|
+
return { status: 403, data: { error: "Not authorised" } };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Prevent duplicate syncs - check if already synced via history or external entity
|
|
122
|
+
const alreadySynced = await isAlreadySynced(job, logId);
|
|
123
|
+
if (alreadySynced) {
|
|
124
|
+
log(action, "AlreadySynced", { id: job.id }, logId);
|
|
125
|
+
return {
|
|
126
|
+
status: 400,
|
|
127
|
+
data: { error: "Job already synced to external system" },
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Set ExtCreateRetry to a new timestamp value.
|
|
132
|
+
// The jobChanged stream handler detects this field change and
|
|
133
|
+
// triggers pushRequestToIntegration() to retry the external sync.
|
|
134
|
+
const retryTimestamp = moment.utc().valueOf();
|
|
135
|
+
const updatedJob = await editRef(
|
|
136
|
+
values.tableNameMaintenance,
|
|
137
|
+
"id",
|
|
138
|
+
job.id,
|
|
139
|
+
{
|
|
140
|
+
ExtCreateRetry: retryTimestamp,
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
log(action, "RetryTriggered", { ExtCreateRetry: retryTimestamp }, logId);
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
status: 200,
|
|
148
|
+
data: {
|
|
149
|
+
success: true,
|
|
150
|
+
message: "Sync retry initiated. Check back shortly for results.",
|
|
151
|
+
job: updatedJob,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
} catch (error) {
|
|
155
|
+
log(action, "InternalError", error, logId);
|
|
156
|
+
return {
|
|
157
|
+
status: 500,
|
|
158
|
+
data: { error: "Internal error", message: error.message },
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
};
|
|
@@ -62,6 +62,7 @@ module.exports = async (event, data) => {
|
|
|
62
62
|
const externalEntity = await updateRef("externalentities", {
|
|
63
63
|
RowId: rowId,
|
|
64
64
|
EntityType: entityType,
|
|
65
|
+
ActiveEntityType: entityType,
|
|
65
66
|
InternalId: job.id,
|
|
66
67
|
ExternalId: data.externalId,
|
|
67
68
|
LastUpdated: moment().valueOf(),
|
package/scheduleJobImport.js
CHANGED
|
@@ -29,11 +29,11 @@ const processBatch = async (strategy, startTime) => {
|
|
|
29
29
|
|
|
30
30
|
// use index query to fetch IDs of requests
|
|
31
31
|
const query = {
|
|
32
|
-
IndexName: "
|
|
32
|
+
IndexName: "ActiveEntityTypeIndex",
|
|
33
33
|
KeyConditionExpression:
|
|
34
|
-
"
|
|
34
|
+
"ActiveEntityType = :activeEntityType AND LastUpdated < :lastUpdate", // only fetch items that haven't been updated in this scan
|
|
35
35
|
ExpressionAttributeValues: {
|
|
36
|
-
":
|
|
36
|
+
":activeEntityType": strategy.getEntityType(),
|
|
37
37
|
":lastUpdate": startTime - strategy.getRefreshInterval(),
|
|
38
38
|
},
|
|
39
39
|
Limit: 10,
|
|
@@ -77,5 +77,11 @@ module.exports.scheduleJobImport = async (event, context, callback) => {
|
|
|
77
77
|
}
|
|
78
78
|
log("scheduleJobImport", "EndLoop", moment().valueOf(), logId);
|
|
79
79
|
}
|
|
80
|
+
// TODO: Remove this call once all existing records have ActiveEntityType (PC-1382)
|
|
81
|
+
const remainingTime = (startTime + timeout) - moment().valueOf();
|
|
82
|
+
if (remainingTime > 0) {
|
|
83
|
+
await integrationStrategy.backfillActiveEntityType(remainingTime);
|
|
84
|
+
}
|
|
85
|
+
|
|
80
86
|
log("scheduleJobImport", "End", moment().valueOf(), logId);
|
|
81
87
|
};
|
package/updateData.js
CHANGED
|
@@ -5,6 +5,7 @@ const config = require("./config.json");
|
|
|
5
5
|
const assignRequest = require("./requests/assignRequest");
|
|
6
6
|
const updatePriority = require("./requests/updatePriority");
|
|
7
7
|
const setExternalJobId = require("./requests/setExternalJobId");
|
|
8
|
+
const retrySync = require("./requests/retrySync");
|
|
8
9
|
|
|
9
10
|
module.exports.updateData = async (event, context, callback) => {
|
|
10
11
|
init(config);
|
|
@@ -25,6 +26,9 @@ module.exports.updateData = async (event, context, callback) => {
|
|
|
25
26
|
case "externalid":
|
|
26
27
|
response = await setExternalJobId(event, data);
|
|
27
28
|
break;
|
|
29
|
+
case "retrysync":
|
|
30
|
+
response = await retrySync(event, data);
|
|
31
|
+
break;
|
|
28
32
|
default:
|
|
29
33
|
response = { status: 404, data: { error: "Action not found" } };
|
|
30
34
|
break;
|
package/values.config.a.js
CHANGED
package/values.config.default.js
CHANGED
package/values.config.enquiry.js
CHANGED
package/values.config.food.js
CHANGED
package/values.config.forms.js
CHANGED
package/values.config.js
CHANGED