shuttlepro-shared 1.3.78 → 1.3.80

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.
@@ -1,5 +1,4 @@
1
1
  const { getRedisData, setRedisData } = require("../../config/redis");
2
- // const DescriptionTemplate = require("../../../models/DescriptionTemplate");
3
2
  const DescriptionTemplate = require("../../models/DescriptionTemplate");
4
3
 
5
4
  const CACHE_KEY_ALL = "description_templates_all";
@@ -0,0 +1,199 @@
1
+ const { getRedisData, setRedisData } = require("../../config/redis");
2
+ const Shop = require("../../models/Shop");
3
+
4
+ const CACHE_KEY_ALL = "shops_all";
5
+
6
+ /**
7
+ * Get all cached shops (across workspaces).
8
+ */
9
+ const getCachedAllShops = async () => {
10
+ let shops = await getRedisData(CACHE_KEY_ALL);
11
+ if (!shops) {
12
+ shops = await Shop.find({}).lean().exec();
13
+ await setRedisData(CACHE_KEY_ALL, shops);
14
+ }
15
+ return shops;
16
+ };
17
+
18
+ /**
19
+ * Refresh all cached shops.
20
+ */
21
+ const updateCachedAllShops = async () => {
22
+ const shops = await Shop.find({}).lean().exec();
23
+ await setRedisData(CACHE_KEY_ALL, shops);
24
+ };
25
+
26
+ /**
27
+ * Create a new shop.
28
+ */
29
+ const createShop = async (data) => {
30
+ const newShop = new Shop(data);
31
+ const savedShop = await newShop.save();
32
+ await updateCachedAllShops();
33
+ return savedShop;
34
+ };
35
+
36
+ /**
37
+ * Get shops by workspaceId from cache.
38
+ */
39
+ const findShopsByWorkspaceId = async (workspaceId) => {
40
+ const allShops = await getCachedAllShops();
41
+ return allShops.filter(
42
+ (shop) => shop.workspaceId?.toString() === workspaceId?.toString()
43
+ );
44
+ };
45
+
46
+ /**
47
+ * Get a shop by filter (with optional workspaceId and nested filters).
48
+ */
49
+ const findShopByFilter = async (
50
+ filter,
51
+ bodyFilter = {},
52
+ workspaceId = null
53
+ ) => {
54
+ const allShops = await getCachedAllShops();
55
+
56
+ const filteredShops = workspaceId
57
+ ? allShops.filter((shop) => shop.workspaceId === workspaceId)
58
+ : allShops;
59
+
60
+ return (
61
+ filteredShops.find(
62
+ (item) =>
63
+ Object.entries(filter).every(([key, value]) => item[key] === value) &&
64
+ Object.entries(bodyFilter).every(
65
+ ([key, value]) => item.body?.[key] === value
66
+ )
67
+ ) || null
68
+ );
69
+ };
70
+
71
+ /**
72
+ * Get all shops by filter (returns array).
73
+ */
74
+ const findAllShopsByFilter = async (
75
+ filter,
76
+ bodyFilter = {},
77
+ workspaceId = null
78
+ ) => {
79
+ const allShops = await getCachedAllShops();
80
+
81
+ const filteredShops = workspaceId
82
+ ? allShops.filter((shop) => shop.workspaceId === workspaceId)
83
+ : allShops;
84
+
85
+ return (
86
+ filteredShops.filter(
87
+ (item) =>
88
+ Object.entries(filter).every(([key, value]) => item[key] === value) &&
89
+ Object.entries(bodyFilter).every(
90
+ ([key, value]) => item.body?.[key] === value
91
+ )
92
+ ) || []
93
+ );
94
+ };
95
+
96
+ /**
97
+ * Create or update shop by filter.
98
+ */
99
+ const createOrUpdateShop = async (filter, data) => {
100
+ const shop = await Shop.findOneAndUpdate(filter, data, {
101
+ upsert: true,
102
+ new: true,
103
+ }).exec();
104
+ if (shop) await updateCachedAllShops();
105
+ return shop;
106
+ };
107
+
108
+ /**
109
+ * Update shop by ID.
110
+ */
111
+ const updateShopById = async (id, data) => {
112
+ const updatedShop = await Shop.findByIdAndUpdate(id, data, {
113
+ new: true,
114
+ }).exec();
115
+ if (updatedShop) await updateCachedAllShops();
116
+ return updatedShop;
117
+ };
118
+
119
+ /**
120
+ * Update shop by filter.
121
+ */
122
+ const updateShopByFilter = async (filter, data, workspaceId = null) => {
123
+ const queryFilter = workspaceId ? { ...filter, workspaceId } : filter;
124
+
125
+ const updatedShop = await Shop.findOneAndUpdate(queryFilter, data, {
126
+ new: true,
127
+ }).exec();
128
+
129
+ if (updatedShop) await updateCachedAllShops();
130
+ return updatedShop;
131
+ };
132
+
133
+ /**
134
+ * Update many shops.
135
+ */
136
+ const updateManyShops = async (filter, data, workspaceId = null) => {
137
+ const queryFilter = workspaceId ? { ...filter, workspaceId } : filter;
138
+
139
+ const updated = await Shop.updateMany(queryFilter, { $set: data }).exec();
140
+ if (updated.modifiedCount > 0) await updateCachedAllShops();
141
+ return updated;
142
+ };
143
+
144
+ /**
145
+ * Delete shop by ID.
146
+ */
147
+ const deleteShop = async (id) => {
148
+ const deletedShop = await Shop.findByIdAndDelete(id).exec();
149
+ if (deletedShop) await updateCachedAllShops();
150
+ return deletedShop;
151
+ };
152
+
153
+ /**
154
+ * Delete all shops for a workspace.
155
+ */
156
+ const deleteAllShopsByWorkspace = async (workspaceId) => {
157
+ await Shop.deleteMany({ workspaceId }).exec();
158
+ await updateCachedAllShops();
159
+ };
160
+
161
+ /**
162
+ * Find shop by ID (non-cached).
163
+ */
164
+ const findShopById = async (id) => {
165
+ return await Shop.findById(id).lean().exec();
166
+ };
167
+
168
+ /**
169
+ * Delete shops by filter.
170
+ */
171
+ const deleteShopsByFilter = async (filter) => {
172
+ await Shop.deleteMany(filter).exec();
173
+ await updateCachedAllShops();
174
+ };
175
+
176
+ /**
177
+ * Insert many shops at once.
178
+ */
179
+ const insertManyShops = async (shops) => {
180
+ const inserted = await Shop.insertMany(shops);
181
+ if (inserted?.length > 0) await updateCachedAllShops();
182
+ return inserted;
183
+ };
184
+
185
+ module.exports = {
186
+ createShop,
187
+ createOrUpdateShop,
188
+ findShopByFilter,
189
+ findShopsByWorkspaceId,
190
+ findAllShopsByFilter,
191
+ updateShopById,
192
+ updateShopByFilter,
193
+ updateManyShops,
194
+ deleteShop,
195
+ deleteAllShopsByWorkspace,
196
+ findShopById,
197
+ deleteShopsByFilter,
198
+ insertManyShops,
199
+ };
package/models/Chatbot.js CHANGED
@@ -23,6 +23,7 @@ const ChatbotSchema = new Schema(
23
23
  {
24
24
  name: { type: String, default: "" },
25
25
  systemPrompt: { type: String, default: "" },
26
+ language: { type: String, default: "English" },
26
27
  additionalPrompt: { type: String, default: "" },
27
28
  tools: [
28
29
  {
package/models/Product.js CHANGED
@@ -1,6 +1,10 @@
1
1
  const mongoose = require("mongoose");
2
2
  const { Schema } = mongoose;
3
3
  const axios = require("axios");
4
+ const {
5
+ updateEmbedding,
6
+ deleteEmbedding,
7
+ } = require("../utils/services/embedding-api.service");
4
8
  const NewProduct = require("./NewProduct"); // Make sure to import NewProduct model
5
9
 
6
10
  const categorySchema = new Schema({
@@ -182,6 +186,7 @@ const updateNewProduct = async (doc, next) => {
182
186
  newProductData,
183
187
  { upsert: true, new: true }
184
188
  );
189
+ await updateEmbedding(newProductData.id, newProductData.workspaceId);
185
190
  }
186
191
  } catch (error) {
187
192
  console.error("Error updating NewProduct:", error);
@@ -194,6 +199,7 @@ const deleteNewProduct = async (doc, next) => {
194
199
  try {
195
200
  if (doc) {
196
201
  await NewProduct.deleteOne({ id: doc._id });
202
+ await deleteEmbedding(doc._id);
197
203
  }
198
204
  } catch (error) {
199
205
  console.error("Error deleting from NewProduct:", error);
package/models/Shop.js ADDED
@@ -0,0 +1,44 @@
1
+ const mongoose = require("mongoose");
2
+
3
+ const ShopSchema = new mongoose.Schema(
4
+ {
5
+ name: {
6
+ type: String,
7
+ required: true,
8
+ },
9
+ description: {
10
+ type: String,
11
+ default: "",
12
+ },
13
+ contactEmail: {
14
+ type: String,
15
+ default: "",
16
+ lowercase: true,
17
+ },
18
+ coordinates: {
19
+ lat: { type: String, default: "" },
20
+ long: { type: String, default: "" },
21
+ },
22
+ phone: {
23
+ type: String,
24
+ default: "",
25
+ },
26
+ address: {
27
+ type: String,
28
+ default: "",
29
+ },
30
+ isActive: {
31
+ type: Boolean,
32
+ default: true,
33
+ },
34
+ workspaceId: {
35
+ type: String,
36
+ default: "",
37
+ },
38
+ },
39
+ { timestamps: true, toJSON: { virtuals: true }, toObject: { virtuals: true } }
40
+ );
41
+
42
+ const Shop = mongoose.model("Shop", ShopSchema);
43
+
44
+ module.exports = Shop;
package/models.js CHANGED
@@ -103,6 +103,7 @@ const Website = require("./models/Website");
103
103
  const WhatsappFlow = require("./models/WhatsappFlow");
104
104
  const Workflow = require("./models/Workflow");
105
105
  const Workspace = require("./models/Workspace");
106
+ const Shop = require("./models/Shop");
106
107
 
107
108
  module.exports = {
108
109
  Activity,
@@ -210,4 +211,5 @@ module.exports = {
210
211
  WhatsappFlow,
211
212
  Workflow,
212
213
  Workspace,
214
+ Shop,
213
215
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shuttlepro-shared",
3
- "version": "1.3.78",
3
+ "version": "1.3.80",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -16,6 +16,7 @@
16
16
  "@babel/plugin-proposal-decorators": "^7.22.5",
17
17
  "@babel/preset-env": "^7.22.5",
18
18
  "@babel/register": "^7.22.5",
19
+ "axios": "^0.21.1",
19
20
  "bull": "^4.10.4",
20
21
  "cors": "^2.8.5",
21
22
  "express": "^4.17.1",
@@ -0,0 +1,50 @@
1
+ const axios = require("axios");
2
+
3
+ const axiosInstance = axios.create({
4
+ timeout: 5000, // 5 seconds
5
+ });
6
+
7
+ const EMBEDDING_SERVICE_URL = process.env.EMBEDDING_SERVER_URL;
8
+
9
+ const updateEmbedding = async (productId, workspaceId) => {
10
+ if (!EMBEDDING_SERVICE_URL) {
11
+ console.warn("⚠️ EMBEDDING_SERVICE_URL not set. Skipping update call.");
12
+ return;
13
+ }
14
+
15
+ try {
16
+ await axiosInstance.post(
17
+ `${EMBEDDING_SERVICE_URL}/embedding/${workspaceId}/${productId}`
18
+ );
19
+ console.log(`✅ Updated embedding for productId: ${productId}`);
20
+ } catch (error) {
21
+ console.error(
22
+ `❌ Failed to update embedding for productId: ${productId}`,
23
+ error
24
+ );
25
+ }
26
+ };
27
+
28
+ const deleteEmbedding = async (productId) => {
29
+ if (!EMBEDDING_SERVICE_URL) {
30
+ console.warn("⚠️ EMBEDDING_SERVICE_URL not set. Skipping delete call.");
31
+ return;
32
+ }
33
+
34
+ try {
35
+ await axiosInstance.delete(
36
+ `${EMBEDDING_SERVICE_URL}/embedding/${productId}`
37
+ );
38
+ console.log(`✅ Deleted embedding for productId: ${productId}`);
39
+ } catch (error) {
40
+ console.error(
41
+ `❌ Failed to delete embedding for productId: ${productId}`,
42
+ error
43
+ );
44
+ }
45
+ };
46
+
47
+ module.exports = {
48
+ updateEmbedding,
49
+ deleteEmbedding,
50
+ };