shuttlepro-shared 1.3.38 → 1.3.40
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/common/repositories/customerProfile.repository.js +14 -83
- package/common/repositories/userRole.repository.js +2 -5
- package/config/redis.js +73 -72
- package/middlewares/checkPermission/index.js +23 -36
- package/models/ActivityLogs.js +0 -1
- package/models/AgentActivity.js +4 -5
- package/models/Card.js +1 -50
- package/models/Chatbot.js +1 -1
- package/models/Column.js +0 -6
- package/models/Conversation.js +0 -40
- package/models/Customer.js +1 -2
- package/models/Integration.js +0 -6
- package/models/Order.js +0 -11
- package/models/Profile.js +1 -3
- package/models/Workspace.js +4 -78
- package/models.js +49 -166
- package/package.json +1 -1
- package/models/Activity.js +0 -28
- package/models/Attribute.js +0 -130
- package/models/Automation.js +0 -242
- package/models/BusinessRule.js +0 -16
- package/models/BusinessRuleHelper.js +0 -13
- package/models/Catalogue.js +0 -22
- package/models/Category.js +0 -129
- package/models/ChatMemberSession.js +0 -21
- package/models/ChatMessage.js +0 -43
- package/models/Color.js +0 -10
- package/models/CustomerCheckpoint.js +0 -21
- package/models/DeviceInfo.js +0 -13
- package/models/Email.js +0 -21
- package/models/EmailMessage.js +0 -30
- package/models/EmailNotification.js +0 -17
- package/models/EscalationConfiguration.js +0 -123
- package/models/EscalationManager.js +0 -50
- package/models/Faq.js +0 -29
- package/models/FeedbackResponse.js +0 -72
- package/models/FormTemplate.js +0 -27
- package/models/InternalComments.js +0 -27
- package/models/InternalThreads.js +0 -20
- package/models/JobDesign.js +0 -32
- package/models/JobQueue.js +0 -17
- package/models/LabelsPdf.js +0 -12
- package/models/Layout.js +0 -12
- package/models/LoadSheet.js +0 -31
- package/models/Location.js +0 -147
- package/models/Logo.js +0 -11
- package/models/MailGroup.js +0 -21
- package/models/Notification.js +0 -32
- package/models/OrderPdf.js +0 -29
- package/models/PostsAutomation.js +0 -66
- package/models/Product.js +0 -336
- package/models/ProductAttachment.js +0 -158
- package/models/ProductAttribute.js +0 -140
- package/models/ProductCategory.js +0 -128
- package/models/ProductLabels.js +0 -11
- package/models/ProductShopify.js +0 -13
- package/models/ProductTag.js +0 -124
- package/models/ProductVariant.js +0 -156
- package/models/ServiceUsage.js +0 -26
- package/models/ShipperSetting.js +0 -24
- package/models/SocialGroup.js +0 -127
- package/models/SocialPost.js +0 -40
- package/models/SocialProfile.js +0 -56
- package/models/Story.js +0 -86
- package/models/Tag.js +0 -77
- package/models/Template.js +0 -76
- package/models/TemplateFrame.js +0 -55
- package/models/TemplateTag.js +0 -10
- package/models/UserSession.js +0 -47
- package/models/VariantLocation.js +0 -145
- package/models/WhatsappFlow.js +0 -29
- package/models/Workflow.js +0 -34
|
@@ -1,103 +1,42 @@
|
|
|
1
|
-
const { getRedisData, setRedisData } = require("../../config/redis");
|
|
2
1
|
const CustomerProfile = require("../../models/CustomerProfile");
|
|
3
2
|
|
|
4
|
-
const CACHE_KEY_ALL = "customer_profiles_all";
|
|
5
|
-
|
|
6
|
-
const getCachedAllCustomerProfiles = async () => {
|
|
7
|
-
let profiles = await getRedisData(CACHE_KEY_ALL);
|
|
8
|
-
if (!profiles) {
|
|
9
|
-
profiles = await CustomerProfile.find({}).lean().exec();
|
|
10
|
-
await setRedisData(CACHE_KEY_ALL, profiles);
|
|
11
|
-
}
|
|
12
|
-
return profiles;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const updateCachedAllCustomerProfiles = async () => {
|
|
16
|
-
const profiles = await CustomerProfile.find({}).lean().exec();
|
|
17
|
-
await setRedisData(CACHE_KEY_ALL, profiles);
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const getCachedCustomerProfiles = async (workspaceId) => {
|
|
21
|
-
const allProfiles = await getCachedAllCustomerProfiles();
|
|
22
|
-
return allProfiles.filter((profile) => profile.workspaceId === workspaceId);
|
|
23
|
-
};
|
|
24
|
-
|
|
25
3
|
const createCustomerProfile = async (data) => {
|
|
26
4
|
const newProfile = new CustomerProfile(data);
|
|
27
5
|
const savedProfile = await newProfile.save();
|
|
28
|
-
|
|
29
|
-
updateCachedAllCustomerProfiles();
|
|
30
6
|
return savedProfile;
|
|
31
7
|
};
|
|
32
8
|
|
|
33
9
|
const findCustomerProfilesByWorkspaceId = async (workspaceId) => {
|
|
34
|
-
return await
|
|
10
|
+
return await CustomerProfile.find({ workspaceId }).lean().exec();
|
|
35
11
|
};
|
|
36
12
|
|
|
37
13
|
const findCustomerProfilesByWorkspace = async (workspaceId, filter = {}) => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
);
|
|
14
|
+
return await CustomerProfile.find({ workspaceId, ...filter })
|
|
15
|
+
.lean()
|
|
16
|
+
.exec();
|
|
42
17
|
};
|
|
43
18
|
|
|
44
19
|
const findCustomerProfileByFilter = async (
|
|
45
20
|
filter = {},
|
|
46
|
-
|
|
21
|
+
|
|
47
22
|
workspaceId = null
|
|
48
23
|
) => {
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
const filtered = workspaceId
|
|
52
|
-
? allProfiles.filter((p) => p.workspaceId === workspaceId)
|
|
53
|
-
: allProfiles;
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
filtered.find(
|
|
57
|
-
(profile) =>
|
|
58
|
-
Object.entries(filter).every(
|
|
59
|
-
([key, value]) => profile[key] === value
|
|
60
|
-
) &&
|
|
61
|
-
Object.entries(bodyFilter).every(
|
|
62
|
-
([key, value]) => profile.body?.[key] === value
|
|
63
|
-
)
|
|
64
|
-
) || null
|
|
65
|
-
);
|
|
24
|
+
const query = workspaceId ? { ...filter, workspaceId } : filter;
|
|
25
|
+
return await CustomerProfile.findOne(query).lean().exec();
|
|
66
26
|
};
|
|
67
27
|
|
|
68
28
|
const findAllCustomerProfilesByFilter = async (
|
|
69
29
|
filter = {},
|
|
70
|
-
bodyFilter = {},
|
|
71
30
|
workspaceId = null
|
|
72
31
|
) => {
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
const filtered = workspaceId
|
|
76
|
-
? allProfiles.filter((p) => p.workspaceId === workspaceId)
|
|
77
|
-
: allProfiles;
|
|
78
|
-
|
|
79
|
-
return (
|
|
80
|
-
filtered.filter(
|
|
81
|
-
(profile) =>
|
|
82
|
-
Object.entries(filter).every(
|
|
83
|
-
([key, value]) => profile[key] === value
|
|
84
|
-
) &&
|
|
85
|
-
Object.entries(bodyFilter).every(
|
|
86
|
-
([key, value]) => profile.body?.[key] === value
|
|
87
|
-
)
|
|
88
|
-
) || []
|
|
89
|
-
);
|
|
32
|
+
const query = workspaceId ? { ...filter, workspaceId } : filter;
|
|
33
|
+
return await CustomerProfile.find(query).lean().exec();
|
|
90
34
|
};
|
|
91
35
|
|
|
92
36
|
const updateCustomerProfile = async (id, data) => {
|
|
93
37
|
const updated = await CustomerProfile.findByIdAndUpdate(id, data, {
|
|
94
38
|
new: true,
|
|
95
39
|
}).exec();
|
|
96
|
-
|
|
97
|
-
if (updated) {
|
|
98
|
-
updateCachedAllCustomerProfiles();
|
|
99
|
-
}
|
|
100
|
-
|
|
101
40
|
return updated;
|
|
102
41
|
};
|
|
103
42
|
|
|
@@ -107,33 +46,24 @@ const updateCustomerProfileByFilter = async (
|
|
|
107
46
|
workspaceId = null
|
|
108
47
|
) => {
|
|
109
48
|
const query = workspaceId ? { ...filter, workspaceId } : filter;
|
|
110
|
-
|
|
111
49
|
const updated = await CustomerProfile.findOneAndUpdate(query, data, {
|
|
112
50
|
new: true,
|
|
113
51
|
}).exec();
|
|
114
|
-
|
|
115
|
-
if (updated) {
|
|
116
|
-
updateCachedAllCustomerProfiles();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
52
|
return updated;
|
|
120
53
|
};
|
|
121
54
|
|
|
122
55
|
const deleteCustomerProfile = async (id) => {
|
|
123
56
|
const deleted = await CustomerProfile.findByIdAndDelete(id).exec();
|
|
124
|
-
|
|
125
|
-
if (deleted) {
|
|
126
|
-
updateCachedAllCustomerProfiles();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
57
|
return deleted;
|
|
130
58
|
};
|
|
131
59
|
|
|
132
60
|
const deleteAllCustomerProfilesByWorkspace = async (workspaceId) => {
|
|
133
61
|
await CustomerProfile.deleteMany({ workspaceId }).exec();
|
|
134
|
-
await updateCachedAllCustomerProfiles();
|
|
135
62
|
};
|
|
136
|
-
|
|
63
|
+
const findAllCustomerProfilesByFilterFromDb = async (filter = {}) => {
|
|
64
|
+
const profiles = await CustomerProfile.find(filter).lean().exec();
|
|
65
|
+
return profiles ?? [];
|
|
66
|
+
};
|
|
137
67
|
module.exports = {
|
|
138
68
|
createCustomerProfile,
|
|
139
69
|
findCustomerProfilesByWorkspaceId,
|
|
@@ -144,4 +74,5 @@ module.exports = {
|
|
|
144
74
|
deleteCustomerProfile,
|
|
145
75
|
deleteAllCustomerProfilesByWorkspace,
|
|
146
76
|
findAllCustomerProfilesByFilter,
|
|
77
|
+
findAllCustomerProfilesByFilterFromDb,
|
|
147
78
|
};
|
|
@@ -2,7 +2,7 @@ const { UserRole } = require("../../models/UserRole");
|
|
|
2
2
|
const { getRedisData, setRedisData } = require("../../config/redis");
|
|
3
3
|
|
|
4
4
|
const defaultSelect =
|
|
5
|
-
"iconUrl thumbUrl name productsCount ordersCount contact email address websiteUrl facebookUrl twitterUrl instagramUrl members defaultModule
|
|
5
|
+
"iconUrl thumbUrl name productsCount ordersCount contact email address websiteUrl facebookUrl twitterUrl instagramUrl members defaultModule";
|
|
6
6
|
|
|
7
7
|
// Cache keys
|
|
8
8
|
const MEMBERS = "members";
|
|
@@ -35,7 +35,6 @@ const updateCachedMembers = async (workspaceId) => {
|
|
|
35
35
|
|
|
36
36
|
const getMembers = async (workspaceId) => {
|
|
37
37
|
let members = await getRedisData(workspaceId, MEMBERS);
|
|
38
|
-
|
|
39
38
|
if (!members || members?.length === 0) {
|
|
40
39
|
members = await UserRole.find({ workspaceId })
|
|
41
40
|
.select("userId role userShift roleId isOwner workspaceId")
|
|
@@ -54,7 +53,6 @@ const getMembers = async (workspaceId) => {
|
|
|
54
53
|
.exec();
|
|
55
54
|
await setRedisData(workspaceId, members, MEMBERS, 3600);
|
|
56
55
|
}
|
|
57
|
-
|
|
58
56
|
return members;
|
|
59
57
|
};
|
|
60
58
|
|
|
@@ -63,8 +61,7 @@ const getMemberByWorkspaceIdAndUserId = async (workspaceId, userId) => {
|
|
|
63
61
|
return (
|
|
64
62
|
members?.find(
|
|
65
63
|
(member) =>
|
|
66
|
-
member?.workspaceId
|
|
67
|
-
member?.userId?._id?.toString() === userId?.toString()
|
|
64
|
+
member?.workspaceId === workspaceId && member?.userId?._id === userId
|
|
68
65
|
) || null
|
|
69
66
|
);
|
|
70
67
|
};
|
package/config/redis.js
CHANGED
|
@@ -8,51 +8,53 @@ const client = createClient({
|
|
|
8
8
|
url: REDIS_URL,
|
|
9
9
|
socket: { reconnectStrategy: (retries) => Math.min(retries * 50, 1000) }, // Exponential backoff
|
|
10
10
|
});
|
|
11
|
+
|
|
12
|
+
// ✅ Create separate Pub/Sub clients
|
|
11
13
|
const publisher = client.duplicate();
|
|
12
14
|
const subscriber = client.duplicate();
|
|
13
15
|
|
|
14
|
-
// ✅ Redis Events
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
client.on("end", () => console.log(`❗ ${label} Connection Closed`));
|
|
20
|
-
client.on("reconnecting", () => console.warn(`🔄 ${label} Reconnecting...`));
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
handleEvents(client, "Main Redis");
|
|
24
|
-
handleEvents(publisher, "Publisher Redis");
|
|
25
|
-
handleEvents(subscriber, "Subscriber Redis");
|
|
16
|
+
// ✅ Handle Redis Connection Events
|
|
17
|
+
client.on("error", (err) => console.error("❌ Redis Error:", err));
|
|
18
|
+
client.on("connect", () => console.log("✅ Redis Connected"));
|
|
19
|
+
client.on("ready", () => console.log("🚀 Redis Ready to use"));
|
|
20
|
+
client.on("end", () => console.log("❗ Redis Connection Closed"));
|
|
26
21
|
|
|
27
|
-
// ✅ Ensure Redis is connected
|
|
22
|
+
// ✅ Ensure Redis is connected before performing operations
|
|
28
23
|
const connectRedis = async () => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (!config["notify-keyspace-events"]?.includes("Ex")) {
|
|
37
|
-
await client.configSet("notify-keyspace-events", "Ex");
|
|
24
|
+
if (!client.isOpen) {
|
|
25
|
+
try {
|
|
26
|
+
await client.connect();
|
|
27
|
+
await publisher.connect();
|
|
28
|
+
await subscriber.connect();
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.error("❌ Failed to connect to Redis:", err);
|
|
38
31
|
}
|
|
39
|
-
} catch (err) {
|
|
40
|
-
console.error("❌ Failed to connect to Redis:", err);
|
|
41
32
|
}
|
|
33
|
+
await client.configSet("notify-keyspace-events", "Ex");
|
|
42
34
|
};
|
|
43
35
|
|
|
44
|
-
|
|
36
|
+
/**
|
|
37
|
+
* ✅ Publish Data to a Channel
|
|
38
|
+
* @param {string} channel - The Redis Pub/Sub channel
|
|
39
|
+
* @param {any} message - The message to send
|
|
40
|
+
*/
|
|
45
41
|
const publishToChannel = async (channel, message) => {
|
|
46
42
|
try {
|
|
43
|
+
await connectRedis();
|
|
47
44
|
await publisher.publish(channel, JSON.stringify(message));
|
|
48
45
|
} catch (err) {
|
|
49
46
|
console.error("❌ Error publishing message:", err);
|
|
50
47
|
}
|
|
51
48
|
};
|
|
52
49
|
|
|
53
|
-
|
|
50
|
+
/**
|
|
51
|
+
* ✅ Subscribe & Listen for Messages
|
|
52
|
+
* @param {string} channel - The Redis Pub/Sub channel
|
|
53
|
+
* @param {function} callback - Callback function to handle messages
|
|
54
|
+
*/
|
|
54
55
|
const subscribeToChannel = async (channel, callback, expiry = false) => {
|
|
55
56
|
try {
|
|
57
|
+
await connectRedis();
|
|
56
58
|
await subscriber.subscribe(channel, (message) => {
|
|
57
59
|
if (expiry) callback(message);
|
|
58
60
|
else callback(JSON.parse(message));
|
|
@@ -62,7 +64,13 @@ const subscribeToChannel = async (channel, callback, expiry = false) => {
|
|
|
62
64
|
}
|
|
63
65
|
};
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
/**
|
|
68
|
+
* ✅ Set Data in Redis (Supports String & Hash)
|
|
69
|
+
* @param {string} key - The Redis key
|
|
70
|
+
* @param {any} value - The value to store
|
|
71
|
+
* @param {string|null} field - Optional field for Hash storage
|
|
72
|
+
* @param {number} expiryInSeconds - Expiry time in seconds (default: 3600)
|
|
73
|
+
*/
|
|
66
74
|
const setRedisData = async (
|
|
67
75
|
key,
|
|
68
76
|
value,
|
|
@@ -70,6 +78,7 @@ const setRedisData = async (
|
|
|
70
78
|
expiryInSeconds = 3600
|
|
71
79
|
) => {
|
|
72
80
|
try {
|
|
81
|
+
await connectRedis();
|
|
73
82
|
const stringifiedValue = JSON.stringify(value);
|
|
74
83
|
let result;
|
|
75
84
|
|
|
@@ -90,27 +99,43 @@ const setRedisData = async (
|
|
|
90
99
|
}
|
|
91
100
|
};
|
|
92
101
|
|
|
93
|
-
|
|
94
|
-
const getRedisData = async (key, field = null) => {
|
|
102
|
+
const addDataToRedisSet = async (key, value) => {
|
|
95
103
|
try {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return result ? JSON.parse(result) : null;
|
|
104
|
+
await connectRedis();
|
|
105
|
+
await client.sAdd(key, value);
|
|
106
|
+
return true;
|
|
100
107
|
} catch (err) {
|
|
101
|
-
|
|
102
|
-
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const removeDataFromRedisSet = async (key, value) => {
|
|
113
|
+
try {
|
|
114
|
+
await connectRedis();
|
|
115
|
+
await client.sRem(key, value);
|
|
116
|
+
return true;
|
|
117
|
+
} catch (err) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
const isMemberOfRedisSet = async (key, value) => {
|
|
122
|
+
try {
|
|
123
|
+
await connectRedis();
|
|
124
|
+
return await client.sIsMember(key, value);
|
|
125
|
+
} catch (err) {
|
|
126
|
+
console.log(err, "err");
|
|
127
|
+
return false;
|
|
103
128
|
}
|
|
104
129
|
};
|
|
105
130
|
/**
|
|
106
|
-
* ✅ Get
|
|
131
|
+
* ✅ Get Data from Redis (Supports String & Hash)
|
|
107
132
|
* @param {string} key - The Redis key
|
|
108
133
|
* @param {string|null} field - Optional field for Hash retrieval
|
|
109
134
|
*/
|
|
110
|
-
const
|
|
135
|
+
const getRedisData = async (key, field = null) => {
|
|
111
136
|
try {
|
|
112
137
|
await connectRedis();
|
|
113
|
-
let result = await client.
|
|
138
|
+
let result = field ? await client.hGet(key, field) : await client.get(key);
|
|
114
139
|
return result ? JSON.parse(result) : null;
|
|
115
140
|
} catch (err) {
|
|
116
141
|
console.error("❌ Error getting Redis data:", err);
|
|
@@ -118,9 +143,14 @@ const getRedisDataTime = async (key) => {
|
|
|
118
143
|
}
|
|
119
144
|
};
|
|
120
145
|
|
|
121
|
-
|
|
146
|
+
/**
|
|
147
|
+
* ✅ Delete Data from Redis (Supports String & Hash)
|
|
148
|
+
* @param {string} key - The Redis key
|
|
149
|
+
* @param {string|null} field - Optional field for Hash deletion
|
|
150
|
+
*/
|
|
122
151
|
const deleteRedisData = async (key, field = null) => {
|
|
123
152
|
try {
|
|
153
|
+
await connectRedis();
|
|
124
154
|
return field ? await client.hDel(key, field) : await client.del(key);
|
|
125
155
|
} catch (err) {
|
|
126
156
|
console.error("❌ Error deleting Redis data:", err);
|
|
@@ -128,37 +158,9 @@ const deleteRedisData = async (key, field = null) => {
|
|
|
128
158
|
}
|
|
129
159
|
};
|
|
130
160
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
await client.sAdd(key, value);
|
|
135
|
-
return true;
|
|
136
|
-
} catch (err) {
|
|
137
|
-
console.error("❌ Error adding to Redis set:", err);
|
|
138
|
-
return false;
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const removeDataFromRedisSet = async (key, value) => {
|
|
143
|
-
try {
|
|
144
|
-
await client.sRem(key, value);
|
|
145
|
-
return true;
|
|
146
|
-
} catch (err) {
|
|
147
|
-
console.error("❌ Error removing from Redis set:", err);
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
const isMemberOfRedisSet = async (key, value) => {
|
|
153
|
-
try {
|
|
154
|
-
return await client.sIsMember(key, value);
|
|
155
|
-
} catch (err) {
|
|
156
|
-
console.error("❌ Error checking membership in Redis set:", err);
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
// ✅ Graceful Shutdown
|
|
161
|
+
/**
|
|
162
|
+
* ✅ Graceful Shutdown Handling
|
|
163
|
+
*/
|
|
162
164
|
const closeClients = async () => {
|
|
163
165
|
if (client.isOpen) await client.quit();
|
|
164
166
|
if (publisher.isOpen) await publisher.quit();
|
|
@@ -182,13 +184,12 @@ module.exports = {
|
|
|
182
184
|
client,
|
|
183
185
|
publisher,
|
|
184
186
|
subscriber,
|
|
185
|
-
connectRedis,
|
|
186
187
|
setRedisData,
|
|
187
|
-
getRedisDataTime,
|
|
188
188
|
getRedisData,
|
|
189
189
|
deleteRedisData,
|
|
190
190
|
publishToChannel,
|
|
191
191
|
subscribeToChannel,
|
|
192
|
+
connectRedis,
|
|
192
193
|
addDataToRedisSet,
|
|
193
194
|
removeDataFromRedisSet,
|
|
194
195
|
isMemberOfRedisSet,
|
|
@@ -31,42 +31,29 @@ exports.checkPermission = async (req, res, next, values) => {
|
|
|
31
31
|
const accessToken = token.split(" ")[1];
|
|
32
32
|
const body = getBodyFromDecodeToken(accessToken);
|
|
33
33
|
if (body) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
// isVerified: body.isVerified,
|
|
58
|
-
// role: body.role,
|
|
59
|
-
// isMember: body.isMember,
|
|
60
|
-
// uuid: body.uuid,
|
|
61
|
-
// };
|
|
62
|
-
// req.currentModulePermission = moduleObj;
|
|
63
|
-
// return next();
|
|
64
|
-
// } else {
|
|
65
|
-
// return res.status(HttpStatusCode.UNAUTHORIZED).json({
|
|
66
|
-
// code: HttpStatusCode.UNAUTHORIZED,
|
|
67
|
-
// message: GenericMessages.PERMISSION_DENIED,
|
|
68
|
-
// });
|
|
69
|
-
// }
|
|
34
|
+
const { module, action } = values;
|
|
35
|
+
const moduleObj = getModule(body, module);
|
|
36
|
+
if (moduleObj && moduleObj.includes(action)) {
|
|
37
|
+
req.user = {
|
|
38
|
+
id: body.id,
|
|
39
|
+
type: body.type,
|
|
40
|
+
email: body.email,
|
|
41
|
+
firstName: body.firstName,
|
|
42
|
+
lastName: body.lastName,
|
|
43
|
+
suspended: body.suspended,
|
|
44
|
+
isVerified: body.isVerified,
|
|
45
|
+
role: body.role,
|
|
46
|
+
isMember: body.isMember,
|
|
47
|
+
uuid: body.uuid,
|
|
48
|
+
};
|
|
49
|
+
req.currentModulePermission = moduleObj;
|
|
50
|
+
return next();
|
|
51
|
+
} else {
|
|
52
|
+
return res.status(HttpStatusCode.UNAUTHORIZED).json({
|
|
53
|
+
code: HttpStatusCode.UNAUTHORIZED,
|
|
54
|
+
message: GenericMessages.PERMISSION_DENIED,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
70
57
|
}
|
|
71
58
|
return res.status(HttpStatusCode.UNAUTHORIZED).json({
|
|
72
59
|
code: HttpStatusCode.UNAUTHORIZED,
|
package/models/ActivityLogs.js
CHANGED
package/models/AgentActivity.js
CHANGED
|
@@ -47,6 +47,8 @@ const activitySchema = new mongoose.Schema({
|
|
|
47
47
|
remarks: { type: String, required: false },
|
|
48
48
|
avgAccuracy: { type: Number, required: false, default: 10 },
|
|
49
49
|
sender: { type: String, required: "" },
|
|
50
|
+
members: [],
|
|
51
|
+
closedBy: {},
|
|
50
52
|
});
|
|
51
53
|
|
|
52
54
|
const totalActivitySchema = new mongoose.Schema({
|
|
@@ -164,9 +166,7 @@ const findOneAndUpdateAgentActivity = async (
|
|
|
164
166
|
);
|
|
165
167
|
|
|
166
168
|
if (bsonSize <= 1000000) {
|
|
167
|
-
return await AgentActivity.findOneAndUpdate(findQuery, updateQuery
|
|
168
|
-
new: true,
|
|
169
|
-
});
|
|
169
|
+
return await AgentActivity.findOneAndUpdate(findQuery, updateQuery);
|
|
170
170
|
} else {
|
|
171
171
|
const { breaks, activities, totalActivities, ...restData } =
|
|
172
172
|
agentActivityForActivitiesUpdated.toObject();
|
|
@@ -177,8 +177,7 @@ const findOneAndUpdateAgentActivity = async (
|
|
|
177
177
|
|
|
178
178
|
const agentActivityRecord = await AgentActivity.findOneAndUpdate(
|
|
179
179
|
{ ...findQuery, _id: newAgentActivity._id },
|
|
180
|
-
updateQuery
|
|
181
|
-
{ new: true }
|
|
180
|
+
updateQuery
|
|
182
181
|
);
|
|
183
182
|
|
|
184
183
|
return agentActivityRecord;
|
package/models/Card.js
CHANGED
|
@@ -91,20 +91,7 @@ const cardSchema = new mongoose.Schema(
|
|
|
91
91
|
},
|
|
92
92
|
fieldType: {
|
|
93
93
|
type: String,
|
|
94
|
-
enum:
|
|
95
|
-
"text",
|
|
96
|
-
"autocomplete",
|
|
97
|
-
"radio",
|
|
98
|
-
"text area",
|
|
99
|
-
"number",
|
|
100
|
-
"date",
|
|
101
|
-
"time",
|
|
102
|
-
"email",
|
|
103
|
-
"range",
|
|
104
|
-
"url",
|
|
105
|
-
"colour",
|
|
106
|
-
"file",
|
|
107
|
-
],
|
|
94
|
+
enum: DYNAMIC_FIELD_TYPES,
|
|
108
95
|
},
|
|
109
96
|
fieldValueId: {
|
|
110
97
|
type: mongoose.Schema.Types.Mixed,
|
|
@@ -120,42 +107,6 @@ const cardSchema = new mongoose.Schema(
|
|
|
120
107
|
},
|
|
121
108
|
},
|
|
122
109
|
],
|
|
123
|
-
assignId: {
|
|
124
|
-
type: mongoose.Schema.Types.Mixed,
|
|
125
|
-
default: null,
|
|
126
|
-
},
|
|
127
|
-
mergedTickets: {
|
|
128
|
-
type: [
|
|
129
|
-
{
|
|
130
|
-
id: { type: String, required: false },
|
|
131
|
-
ticketId: { type: String, required: false },
|
|
132
|
-
},
|
|
133
|
-
],
|
|
134
|
-
default: [],
|
|
135
|
-
},
|
|
136
|
-
mergedInto: {
|
|
137
|
-
type: {
|
|
138
|
-
id: { type: String, required: false, default: "" },
|
|
139
|
-
ticketId: { type: String, required: false, default: "" },
|
|
140
|
-
},
|
|
141
|
-
default: null,
|
|
142
|
-
},
|
|
143
|
-
customerName: {
|
|
144
|
-
type: String,
|
|
145
|
-
default: "",
|
|
146
|
-
},
|
|
147
|
-
customerEmail: {
|
|
148
|
-
type: String,
|
|
149
|
-
default: "",
|
|
150
|
-
},
|
|
151
|
-
phoneNo: {
|
|
152
|
-
type: String,
|
|
153
|
-
default: "",
|
|
154
|
-
},
|
|
155
|
-
body: {
|
|
156
|
-
type: mongoose.Schema.Types.Mixed,
|
|
157
|
-
default: {},
|
|
158
|
-
},
|
|
159
110
|
},
|
|
160
111
|
{ timestamps: true, toJSON: { virtuals: true }, toObject: { virtuals: true } }
|
|
161
112
|
);
|
package/models/Chatbot.js
CHANGED
package/models/Column.js
CHANGED
|
@@ -14,12 +14,6 @@ const columnSchema = new mongoose.Schema(
|
|
|
14
14
|
type: Boolean,
|
|
15
15
|
default: false,
|
|
16
16
|
},
|
|
17
|
-
type: {
|
|
18
|
-
type: String,
|
|
19
|
-
enum: ["open", "processing", "hold", "closed"],
|
|
20
|
-
required: true,
|
|
21
|
-
default: "open",
|
|
22
|
-
},
|
|
23
17
|
workspaceId: { type: String, default: "" },
|
|
24
18
|
},
|
|
25
19
|
{ timestamps: true, toJSON: { virtuals: true }, toObject: { virtuals: true } }
|
package/models/Conversation.js
CHANGED
|
@@ -10,14 +10,6 @@ const draftSchema = new mongoose.Schema({
|
|
|
10
10
|
createdBy: { type: Schema.Types.ObjectId, ref: "User" },
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
const activitySchema = new mongoose.Schema({
|
|
14
|
-
action: { type: String, default: null },
|
|
15
|
-
previousAssignee: { type: Schema.Types.ObjectId, ref: "User", default: null },
|
|
16
|
-
newAssignee: { type: Schema.Types.ObjectId, ref: "User", default: null },
|
|
17
|
-
timestamp: { type: Date, default: Date.now },
|
|
18
|
-
performedBy: { type: Schema.Types.ObjectId, ref: "User", default: null },
|
|
19
|
-
});
|
|
20
|
-
|
|
21
13
|
const conversationSchema = new mongoose.Schema(
|
|
22
14
|
{
|
|
23
15
|
platformType: {
|
|
@@ -84,44 +76,12 @@ const conversationSchema = new mongoose.Schema(
|
|
|
84
76
|
draft: [draftSchema],
|
|
85
77
|
isWebchatTicket: { type: Boolean, default: false },
|
|
86
78
|
webchatComplaintType: { type: String, default: null },
|
|
87
|
-
isWebchatAutoReply: { type: Boolean, default: false },
|
|
88
|
-
|
|
89
79
|
isComposed: { type: Boolean, default: false },
|
|
90
|
-
userMessageTime: { type: String, default: "" },
|
|
91
80
|
utilityMessage: [],
|
|
92
81
|
orderId: [],
|
|
93
82
|
isFetch: { type: Boolean, default: true },
|
|
94
|
-
isAwaitingFeedback: { type: Boolean, default: true },
|
|
95
|
-
activities: [activitySchema],
|
|
96
83
|
},
|
|
97
84
|
{ timestamps: true, toJSON: { virtuals: true }, toObject: { virtuals: true } }
|
|
98
85
|
);
|
|
99
86
|
|
|
100
|
-
conversationSchema.index({ workspaceId: 1, isSpam: 1 });
|
|
101
|
-
conversationSchema.index({ workspaceId: 1, isSpam: 1, conversationStatus: 1 });
|
|
102
|
-
conversationSchema.index({
|
|
103
|
-
workspaceId: 1,
|
|
104
|
-
isSpam: 1,
|
|
105
|
-
platformId: 1,
|
|
106
|
-
});
|
|
107
|
-
conversationSchema.index({
|
|
108
|
-
workspaceId: 1,
|
|
109
|
-
isSpam: 1,
|
|
110
|
-
platformId: 1,
|
|
111
|
-
conversationStatus: 1,
|
|
112
|
-
});
|
|
113
|
-
conversationSchema.index({
|
|
114
|
-
workspaceId: 1,
|
|
115
|
-
isSpam: 1,
|
|
116
|
-
platformId: 1,
|
|
117
|
-
conversationType: 1,
|
|
118
|
-
});
|
|
119
|
-
conversationSchema.index({
|
|
120
|
-
workspaceId: 1,
|
|
121
|
-
isSpam: 1,
|
|
122
|
-
platformId: 1,
|
|
123
|
-
conversationType: 1,
|
|
124
|
-
conversationStatus: 1,
|
|
125
|
-
});
|
|
126
|
-
|
|
127
87
|
module.exports = mongoose.model("Conversation", conversationSchema);
|