shuttlepro-shared 1.1.91 → 1.1.93

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/constants/index.js +0 -15
  2. package/index.js +0 -8
  3. package/models/Role.js +40 -0
  4. package/models/UserPermission.js +5 -0
  5. package/models/UserRole.js +10 -3
  6. package/models.js +3 -50
  7. package/package.json +2 -13
  8. package/common/repositories/descriptionTemplates.repository.js +0 -186
  9. package/common/repositories/index.js +0 -10
  10. package/common/repositories/integration.repository.js +0 -197
  11. package/common/repositories/shipper.repository.js +0 -77
  12. package/common/repositories/workspace.repository.js +0 -95
  13. package/config/bull.js +0 -78
  14. package/config/config.js +0 -14
  15. package/config/database.js +0 -7
  16. package/config/index.js +0 -13
  17. package/config/redis.js +0 -160
  18. package/config/socket.js +0 -172
  19. package/models/AgentActivity.js +0 -189
  20. package/models/Assignment.js +0 -23
  21. package/models/BusinessDistribution.js +0 -23
  22. package/models/Card.js +0 -144
  23. package/models/CardComments.js +0 -33
  24. package/models/Chatbot.js +0 -16
  25. package/models/Checkpoint.js +0 -50
  26. package/models/City.js +0 -17
  27. package/models/Column.js +0 -28
  28. package/models/Conversation.js +0 -84
  29. package/models/Customer.js +0 -35
  30. package/models/DescriptionTemplate.js +0 -22
  31. package/models/Integration.js +0 -53
  32. package/models/Label.js +0 -42
  33. package/models/Message.js +0 -47
  34. package/models/Order.js +0 -131
  35. package/models/OrderProduct.js +0 -37
  36. package/models/Profile.js +0 -127
  37. package/models/Report.js +0 -27
  38. package/models/Shipper.js +0 -52
  39. package/models/Status.js +0 -58
  40. package/models/StatusType.js +0 -10
  41. package/models/Step.js +0 -50
  42. package/models/Type.js +0 -25
  43. package/models/Workspace.js +0 -190
  44. package/utils/decorator-factory.js +0 -264
  45. package/utils/logger.js +0 -41
@@ -1,95 +0,0 @@
1
- const { getRedisData, setRedisData } = require("../../config/redis");
2
- const Workspace = require("../../models/Workspace");
3
-
4
- const CACHE_KEY_ALL = "workspaces_all";
5
-
6
- const getCachedWorkspaces = async () => {
7
- let workspaces = await getRedisData(CACHE_KEY_ALL);
8
- if (!workspaces) {
9
- workspaces = await Workspace.find().exec();
10
- await setRedisData(CACHE_KEY_ALL, JSON.stringify(workspaces));
11
- } else {
12
- workspaces = JSON.parse(workspaces);
13
- }
14
- return workspaces;
15
- };
16
-
17
- const updateCachedWorkspaces = async () => {
18
- const workspaces = await Workspace.find().exec();
19
- await setRedisData(CACHE_KEY_ALL, JSON.stringify(workspaces));
20
- };
21
-
22
- const createWorkspace = async (data) => {
23
- const newWorkspace = new Workspace(data);
24
- const savedWorkspace = await newWorkspace.save();
25
- await updateCachedWorkspaces();
26
- return savedWorkspace;
27
- };
28
-
29
- const findWorkspaceById = async (id, select = []) => {
30
- const workspaces = await getCachedWorkspaces();
31
- const workspace = workspaces.find((ws) => ws._id.toString() === id) || null;
32
-
33
- if (workspace && select.length > 0) {
34
- return select.reduce((result, field) => {
35
- if (workspace[field] !== undefined) {
36
- result[field] = workspace[field];
37
- }
38
- return result;
39
- }, {});
40
- }
41
-
42
- return workspace;
43
- };
44
-
45
- const findWorkspace = async (filter) => {
46
- const workspaces = await getCachedWorkspaces();
47
- return (
48
- workspaces.find((ws) =>
49
- Object.entries(filter).every(([key, value]) => ws[key] === value)
50
- ) || null
51
- );
52
- };
53
-
54
- const findWorkspaceByIdAndQueueTracking = async (id) => {
55
- const workspaces = await getCachedWorkspaces();
56
- return (
57
- workspaces.find((ws) => ws._id.toString() === id && ws.queueTracking) ||
58
- null
59
- );
60
- };
61
-
62
- const findAllWorkspaces = async (filter = {}) => {
63
- const workspaces = await getCachedWorkspaces();
64
- return workspaces.filter((ws) =>
65
- Object.entries(filter).every(([key, value]) => ws[key] === value)
66
- );
67
- };
68
-
69
- const updateWorkspace = async (id, data) => {
70
- const updatedWorkspace = await Workspace.findByIdAndUpdate(id, data, {
71
- new: true,
72
- }).exec();
73
- if (updatedWorkspace) {
74
- await updateCachedWorkspaces();
75
- }
76
- return updatedWorkspace;
77
- };
78
-
79
- const deleteWorkspace = async (id) => {
80
- const deletedWorkspace = await Workspace.findByIdAndDelete(id).exec();
81
- if (deletedWorkspace) {
82
- await updateCachedWorkspaces();
83
- }
84
- return deletedWorkspace;
85
- };
86
-
87
- module.exports = {
88
- createWorkspace,
89
- findWorkspaceById,
90
- findWorkspace,
91
- findWorkspaceByIdAndQueueTracking,
92
- findAllWorkspaces,
93
- updateWorkspace,
94
- deleteWorkspace,
95
- };
package/config/bull.js DELETED
@@ -1,78 +0,0 @@
1
- const Queue = require("bull");
2
- const config = require("./config");
3
-
4
- /**
5
- * Create a new queue.
6
- * @param {string} queueName - The name of the queue.
7
- * @param {Object} [redisConfig=config.redis] - Redis configuration.
8
- * @returns {Object} - A collection of queue-related functions.
9
- */
10
- const createQueue = (queueName, redisConfig = config.redis) => {
11
- const queue = new Queue(queueName, { redis: redisConfig });
12
-
13
- // Attach event listeners for logging
14
- queue.on("completed", (job) => console.log(`Job ${job.id} completed.`));
15
- queue.on("failed", (job, err) => console.error(`Job ${job.id} failed:`, err));
16
-
17
- /**
18
- * Add a job to the queue.
19
- * @param {Object} data - Data to be processed by the job.
20
- * @param {Object} [options] - Bull job options (e.g., delay, attempts).
21
- * @returns {Promise<Job>} - The created job.
22
- */
23
- const addJob = async (
24
- data,
25
- options = {
26
- attempts: 3,
27
- removeOnComplete: true,
28
- }
29
- ) => {
30
- return await queue.add(data, options);
31
- };
32
-
33
- /**
34
- * Process jobs in the queue.
35
- * @param {Function} processor - The function to process each job.
36
- */
37
- const processJobs = (processor) => {
38
- queue.process(processor);
39
- };
40
-
41
- /**
42
- * Close the queue connection.
43
- * @returns {Promise<void>}
44
- */
45
- const closeConnection = async () => {
46
- await queue.close();
47
- console.log(`Queue "${queue.name}" connection closed.`);
48
- };
49
-
50
- /**
51
- * Pause the queue.
52
- * @returns {Promise<void>}
53
- */
54
- const pauseQueue = async () => {
55
- await queue.pause();
56
- console.log(`Queue "${queue.name}" paused.`);
57
- };
58
-
59
- /**
60
- * Resume the queue.
61
- * @returns {Promise<void>}
62
- */
63
- const resumeQueue = async () => {
64
- await queue.resume();
65
- console.log(`Queue "${queue.name}" resumed.`);
66
- };
67
-
68
- // Return the functional interface
69
- return {
70
- addJob,
71
- processJobs,
72
- closeConnection,
73
- pauseQueue,
74
- resumeQueue,
75
- };
76
- };
77
-
78
- module.exports = { createQueue };
package/config/config.js DELETED
@@ -1,14 +0,0 @@
1
- const ALLOWED_URLS = process.env.ALLOWED_ORIGIN.split(",");
2
- const WEBHOOK_API_KEY = process.env.API_KEY || process.env.WEBHOOK_API_KEY;
3
- const mode = process.env.MODE || "production";
4
-
5
- const redis = {
6
- url: process.env.REDIS_URI,
7
- };
8
-
9
- module.exports = {
10
- WEBHOOK_API_KEY,
11
- ALLOWED_URLS,
12
- mode,
13
- redis,
14
- };
@@ -1,7 +0,0 @@
1
- /* eslint-disable no-undef */
2
- module.exports = {
3
- url:
4
- process.env.NODE_ENV === "test"
5
- ? process.env.TEST_DB_URL
6
- : process.env.DB_URL,
7
- };
package/config/index.js DELETED
@@ -1,13 +0,0 @@
1
- const bullConfig = require("./bull");
2
- const redisConfig = require("./redis");
3
- const config = require("./config");
4
- const databaseConfig = require("./database");
5
- const socketConfig = require("./socket");
6
-
7
- module.exports = {
8
- bullConfig,
9
- redisConfig,
10
- config,
11
- databaseConfig,
12
- socketConfig,
13
- };
package/config/redis.js DELETED
@@ -1,160 +0,0 @@
1
- const { createClient } = require("redis");
2
- require("dotenv").config();
3
-
4
- const REDIS_URL = process.env.REDIS_URL || "redis://localhost:6379";
5
-
6
- // ✅ Create main Redis client
7
- const client = createClient({
8
- url: REDIS_URL,
9
- socket: { reconnectStrategy: (retries) => Math.min(retries * 50, 1000) }, // Exponential backoff
10
- });
11
-
12
- // ✅ Create separate Pub/Sub clients
13
- const publisher = client.duplicate();
14
- const subscriber = client.duplicate();
15
-
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"));
21
-
22
- // ✅ Ensure Redis is connected before performing operations
23
- const connectRedis = async () => {
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);
31
- }
32
- }
33
- };
34
-
35
- /**
36
- * ✅ Publish Data to a Channel
37
- * @param {string} channel - The Redis Pub/Sub channel
38
- * @param {any} message - The message to send
39
- */
40
- const publishToChannel = async (channel, message) => {
41
- try {
42
- await connectRedis();
43
- await publisher.publish(channel, JSON.stringify(message));
44
- console.log(`📢 Message published to channel: ${channel}`);
45
- } catch (err) {
46
- console.error("❌ Error publishing message:", err);
47
- }
48
- };
49
-
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
- */
55
- const subscribeToChannel = async (channel, callback) => {
56
- try {
57
- await connectRedis();
58
- await subscriber.subscribe(channel, (message) => {
59
- console.log(`📥 Message received on channel: ${channel}`);
60
- callback(JSON.parse(message));
61
- });
62
- } catch (err) {
63
- console.error("❌ Error subscribing to channel:", err);
64
- }
65
- };
66
-
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
- */
74
- const setRedisData = async (
75
- key,
76
- value,
77
- field = null,
78
- expiryInSeconds = 3600
79
- ) => {
80
- try {
81
- await connectRedis();
82
- let result;
83
- if (field) {
84
- result = await client.hSet(key, field, JSON.stringify(value));
85
- } else {
86
- result = await client.set(key, JSON.stringify(value), {
87
- EX: expiryInSeconds,
88
- });
89
- }
90
- return result;
91
- } catch (err) {
92
- console.error("❌ Error setting Redis data:", err);
93
- return null;
94
- }
95
- };
96
-
97
- /**
98
- * ✅ Get Data from Redis (Supports String & Hash)
99
- * @param {string} key - The Redis key
100
- * @param {string|null} field - Optional field for Hash retrieval
101
- */
102
- const getRedisData = async (key, field = null) => {
103
- try {
104
- await connectRedis();
105
- let result = field ? await client.hGet(key, field) : await client.get(key);
106
- return result ? JSON.parse(result) : null;
107
- } catch (err) {
108
- console.error("❌ Error getting Redis data:", err);
109
- return null;
110
- }
111
- };
112
-
113
- /**
114
- * ✅ Delete Data from Redis (Supports String & Hash)
115
- * @param {string} key - The Redis key
116
- * @param {string|null} field - Optional field for Hash deletion
117
- */
118
- const deleteRedisData = async (key, field = null) => {
119
- try {
120
- await connectRedis();
121
- return field ? await client.hDel(key, field) : await client.del(key);
122
- } catch (err) {
123
- console.error("❌ Error deleting Redis data:", err);
124
- return null;
125
- }
126
- };
127
-
128
- /**
129
- * ✅ Graceful Shutdown Handling
130
- */
131
- const closeClients = async () => {
132
- if (client.isOpen) await client.quit();
133
- if (publisher.isOpen) await publisher.quit();
134
- if (subscriber.isOpen) await subscriber.quit();
135
- console.log("❗ Redis Clients Disconnected Gracefully");
136
- };
137
-
138
- // ✅ Ensure Redis disconnects properly on process exit
139
- process.on("exit", closeClients);
140
- process.on("SIGINT", async () => {
141
- await closeClients();
142
- process.exit();
143
- });
144
- process.on("SIGTERM", async () => {
145
- await closeClients();
146
- process.exit();
147
- });
148
-
149
- // ✅ Export Functions
150
- module.exports = {
151
- client,
152
- publisher,
153
- subscriber,
154
- setRedisData,
155
- getRedisData,
156
- deleteRedisData,
157
- publishToChannel,
158
- subscribeToChannel,
159
- connectRedis,
160
- };
package/config/socket.js DELETED
@@ -1,172 +0,0 @@
1
- const { Server } = require("socket.io");
2
- const { publisher, subscriber, connectRedis } = require("./redis");
3
- require("dotenv").config();
4
-
5
- let io;
6
- const namespaceSockets = {}; // Store different namespace sockets
7
-
8
- /**
9
- * Initialize Socket.IO server with namespaces
10
- * @param {http.Server} server - HTTP server instance
11
- * @param {string} namespaceParam - Socket namespace name (default: "conversation")
12
- * @param {string} redisChannel - Redis channel for this namespace (default: "socket_events")
13
- * @returns {SocketIO.Namespace} - The initialized namespace
14
- */
15
- const initializeSocket = async (
16
- server,
17
- namespaceParam = "conversation",
18
- redisChannel = "socket_events"
19
- ) => {
20
- // Initialize Socket.IO server if not already done
21
- if (!io) {
22
- io = new Server(server, {
23
- cors: {
24
- origin: "*",
25
- methods: ["GET", "POST"],
26
- },
27
- });
28
- console.log("✅ Socket.IO server initialized");
29
- }
30
-
31
- // Return existing namespace if already initialized
32
- if (namespaceSockets[namespaceParam]) {
33
- console.log(`📢 Using existing namespace: /${namespaceParam}`);
34
- return namespaceSockets[namespaceParam];
35
- }
36
-
37
- // Create and store new namespace
38
- const namespace = io.of(`/${namespaceParam}`);
39
- namespaceSockets[namespaceParam] = namespace;
40
- console.log(`🚀 Created new namespace: /${namespaceParam}`);
41
-
42
- // Ensure Redis is connected
43
- await connectRedis();
44
-
45
- // Create a unique Redis channel for this namespace
46
- const nsRedisChannel = `${redisChannel}_${namespaceParam}`;
47
-
48
- // Subscribe to Redis events for this namespace
49
- await subscriber.subscribe(nsRedisChannel, (messageStr) => {
50
- try {
51
- const message = JSON.parse(messageStr);
52
- const { workspaceId, event, data } = message;
53
-
54
- console.log(`📥 Redis message received on ${nsRedisChannel}:`, {
55
- workspaceId,
56
- event,
57
- });
58
-
59
- // Emit to specific workspace room in this namespace
60
- if (workspaceId) {
61
- namespace.to(workspaceId).emit(event, data);
62
- console.log(
63
- `📢 Event ${event} emitted to workspace ${workspaceId} in /${namespaceParam}`
64
- );
65
- } else {
66
- // Broadcast to all clients in this namespace if no workspaceId specified
67
- namespace.emit(event, data);
68
- console.log(
69
- `📢 Event ${event} broadcasted to all clients in /${namespaceParam}`
70
- );
71
- }
72
- } catch (err) {
73
- console.error(
74
- `❌ Error handling Redis message on ${nsRedisChannel}:`,
75
- err
76
- );
77
- }
78
- });
79
-
80
- // Handle new socket connections to this namespace
81
- namespace.on("connection", (socket) => {
82
- const { workspaceId } = socket.handshake.query;
83
-
84
- if (!workspaceId) {
85
- console.warn(`⚠️ Connection rejected: No workspaceId provided`);
86
- socket.disconnect(true);
87
- return;
88
- }
89
-
90
- console.log(
91
- `✅ Client connected: ${socket.id} (Workspace: ${workspaceId}) in /${namespaceParam}`
92
- );
93
-
94
- // Join workspace room
95
- socket.join(workspaceId);
96
-
97
- // Send connection confirmation to client
98
- socket.emit("connected", {
99
- status: "connected",
100
- socketId: socket.id,
101
- namespace: namespaceParam,
102
- workspaceId,
103
- });
104
-
105
- // Handle custom events from clients
106
- socket.on("client_event", (data) => {
107
- console.log(`📥 Client event from ${socket.id}:`, data);
108
- // You can process client events here
109
- });
110
-
111
- // Handle disconnect
112
- socket.on("disconnect", (reason) => {
113
- console.log(
114
- `❌ Client disconnected: ${socket.id} (Workspace: ${workspaceId}, Reason: ${reason})`
115
- );
116
- socket.leave(workspaceId);
117
- });
118
-
119
- // Handle errors
120
- socket.on("error", (error) => {
121
- console.error(`❌ Socket error for ${socket.id}:`, error);
122
- });
123
- });
124
-
125
- console.log(
126
- `✅ Namespace /${namespaceParam} initialized and listening on Redis channel: ${nsRedisChannel}`
127
- );
128
- return namespace;
129
- };
130
-
131
- /**
132
- * Send event to clients via Redis pub/sub
133
- * @param {object} params - Event parameters
134
- * @param {string} params.workspaceId - Target workspace ID
135
- * @param {string} params.event - Event name
136
- * @param {any} params.data - Event data payload
137
- * @param {string} [params.namespace="conversation"] - Target namespace
138
- * @param {string} [params.redisChannel="socket_events"] - Base Redis channel
139
- * @returns {Promise<void>}
140
- */
141
- const sendEventToServer = async ({
142
- workspaceId,
143
- event,
144
- data,
145
- namespace = "conversation",
146
- redisChannel = "socket_events",
147
- }) => {
148
- try {
149
- // Create namespace-specific Redis channel
150
- const nsRedisChannel = `${redisChannel}_${namespace}`;
151
-
152
- // Ensure Redis is connected
153
- await connectRedis();
154
-
155
- // Create message payload
156
- const message = JSON.stringify({ workspaceId, event, data });
157
-
158
- // Publish to Redis
159
- await publisher.publish(nsRedisChannel, message);
160
-
161
- console.log(
162
- `📢 Event published to Redis channel ${nsRedisChannel}: ${event} (Workspace: ${workspaceId})`
163
- );
164
-
165
- return true;
166
- } catch (err) {
167
- console.error("❌ Error publishing to Redis:", err);
168
- throw err;
169
- }
170
- };
171
-
172
- module.exports = { initializeSocket, sendEventToServer };