powr-sdk-api 2.3.7 → 2.4.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/dist/config.js CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  const config = {
4
4
  mongoUri: process.env.POWR_DB_URI,
5
- projectId: process.env.PROJECT_ID,
6
- jwtToken: process.env.JWT_TOKEN,
7
- storageBucket: process.env.STORAGE_BUCKET
5
+ jwtToken: process.env.JWT_TOKEN
8
6
  };
9
7
  module.exports = config;
package/dist/index.js CHANGED
@@ -7,36 +7,20 @@ const {
7
7
  const {
8
8
  requestHandler
9
9
  } = require("./middleware/request");
10
- const {
11
- validateAuth,
12
- generateToken
13
- } = require("./middleware/auth");
14
10
  const {
15
11
  notFoundHandler
16
12
  } = require("./middleware/notfound");
17
13
  const {
18
14
  createSwaggerSpec
19
15
  } = require("./swagger");
20
- const {
21
- cloudLogger
22
- } = require("./logger");
23
16
  const {
24
17
  createPowrRoutes
25
18
  } = require("./routes");
26
- const {
27
- generateJWTToken,
28
- verifyToken
29
- } = require("./middleware/jwtToken");
30
19
  module.exports = {
31
20
  errorCatcher,
32
21
  errorHandler,
33
22
  requestHandler,
34
- cloudLogger,
35
23
  createSwaggerSpec,
36
- generateToken,
37
- validateAuth,
38
24
  notFoundHandler,
39
- createPowrRoutes,
40
- generateJWTToken,
41
- verifyToken
25
+ createPowrRoutes
42
26
  };
@@ -1,9 +1,6 @@
1
1
  "use strict";
2
2
 
3
3
  const jwt = require('jsonwebtoken');
4
- const {
5
- ObjectId
6
- } = require('mongodb');
7
4
  const config = require('../config');
8
5
  const generateJWTToken = (user, profile = null) => {
9
6
  return jwt.sign({
@@ -29,6 +26,12 @@ const verifyToken = async (req, res, next) => {
29
26
 
30
27
  // Extract token (remove 'Bearer ' if present)
31
28
  const token = authHeader.startsWith("Bearer ") ? authHeader.slice(7) : authHeader;
29
+ if (!token) {
30
+ return res.status(401).json({
31
+ success: false,
32
+ message: 'No token provided'
33
+ });
34
+ }
32
35
 
33
36
  // Verify JWT token
34
37
  const decoded = jwt.verify(token, config.jwtToken);
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+
3
+ const config = require('../config');
4
+
5
+ /**
6
+ * Middleware to inject projectId into requests
7
+ * @param {Object} options - Configuration options
8
+ * @param {boolean} options.isCentralService - Whether this is a central service (like powr-base-cloud)
9
+ * @returns {Function} Express middleware function
10
+ */
11
+ const injectProjectId = (options = {}) => {
12
+ const isCentralService = options.isCentralService || false;
13
+ return (req, res, next) => {
14
+ try {
15
+ if (isCentralService) {
16
+ // For central services, get projectId from request
17
+ const projectId = req.query.projectId || req.body.projectId;
18
+ if (!projectId) {
19
+ return res.status(400).json({
20
+ success: false,
21
+ message: 'projectId is required for central services'
22
+ });
23
+ }
24
+ req.projectId = projectId;
25
+ } else {
26
+ // For individual APIs, use config.projectId
27
+ req.projectId = config.projectId;
28
+ }
29
+ next();
30
+ } catch (error) {
31
+ console.error('❌ ProjectId injection error:', error.message);
32
+ return res.status(500).json({
33
+ success: false,
34
+ message: 'Configuration error',
35
+ error: error.message
36
+ });
37
+ }
38
+ };
39
+ };
40
+ module.exports = {
41
+ injectProjectId
42
+ };
@@ -4,14 +4,13 @@ const express = require("express");
4
4
  const router = express.Router();
5
5
  const {
6
6
  getDb
7
- } = require("../services/dbService");
7
+ } = require("../services/mongo");
8
8
  const {
9
9
  ObjectId
10
10
  } = require("mongodb");
11
11
  const bcrypt = require("bcrypt");
12
12
  const {
13
- generateJWTToken,
14
- verifyToken
13
+ generateJWTToken
15
14
  } = require("../middleware/jwtToken");
16
15
  const {
17
16
  config
@@ -23,9 +22,10 @@ router.post("/register", async (req, res) => {
23
22
  fullName,
24
23
  username,
25
24
  phoneOrEmail,
26
- password,
27
- projectId
25
+ password
28
26
  } = req.body;
27
+ const projectId = req.projectId; // Use middleware-injected projectId
28
+
29
29
  try {
30
30
  if (!(username || phoneOrEmail)) {
31
31
  return res.status(400).json({
@@ -45,14 +45,6 @@ router.post("/register", async (req, res) => {
45
45
  message: "Full name is required"
46
46
  });
47
47
  }
48
-
49
- // if (!projectId) {
50
- // return res.status(400).json({
51
- // success: false,
52
- // message: "Project ID is required"
53
- // });
54
- // }
55
-
56
48
  let q = username ? {
57
49
  username: username
58
50
  } : {
@@ -109,9 +101,10 @@ router.post("/login", async (req, res) => {
109
101
  const {
110
102
  username,
111
103
  phoneOrEmail,
112
- password,
113
- projectId
104
+ password
114
105
  } = req.body;
106
+ const projectId = req.projectId; // Use middleware-injected projectId
107
+
115
108
  try {
116
109
  if (!(username || phoneOrEmail)) {
117
110
  return res.status(400).json({
@@ -185,13 +178,31 @@ router.post("/login", async (req, res) => {
185
178
  const token = generateJWTToken(user, profile);
186
179
  const {
187
180
  password: _,
181
+ _id,
188
182
  ...userWithoutPassword
189
183
  } = user;
184
+ let mergedUser = {
185
+ ...userWithoutPassword,
186
+ powrId: user._id
187
+ };
188
+ if (profile) {
189
+ const {
190
+ _id,
191
+ userId,
192
+ projectId,
193
+ createdAt,
194
+ updatedAt,
195
+ ...profileData
196
+ } = profile;
197
+ mergedUser = {
198
+ ...mergedUser,
199
+ ...profileData
200
+ };
201
+ }
190
202
  return res.status(200).json({
191
203
  success: true,
192
204
  message: "Login successful",
193
- user: userWithoutPassword,
194
- profile: profile,
205
+ user: mergedUser,
195
206
  token: token
196
207
  });
197
208
  } catch (error) {
@@ -1,16 +1,12 @@
1
1
  "use strict";
2
2
 
3
3
  const express = require('express');
4
+ const router = express.Router();
4
5
  const multer = require('multer');
5
6
  // const { uploadToGCS, bucket } = require('../uploadToGCS')
6
- const {
7
- bucket,
8
- uploadToGCS,
9
- bucketName
10
- } = require('../uploadToGCS.js');
7
+ // const { bucket, uploadToGCS, bucketName } = require('../uploadToGCS.js')
11
8
  // const uploadToGCS = require('../uploadToGCS.js')
12
9
 
13
- const router = express.Router();
14
10
  const upload = multer();
15
11
  router.post('/', upload.single('file'), async (req, res) => {
16
12
  try {
@@ -20,11 +16,13 @@ router.post('/', upload.single('file'), async (req, res) => {
20
16
  message: 'No file uploaded'
21
17
  });
22
18
  }
23
- const url = await uploadToGCS(req.file);
19
+
20
+ // const url = await uploadToGCS(req.file);
21
+
24
22
  return res.status(200).json({
25
23
  status: 'success',
26
- message: 'File uploaded successfully',
27
- url
24
+ message: 'File uploaded successfully'
25
+ // url,
28
26
  });
29
27
  } catch (err) {
30
28
  console.error('Error uploading file:', err);
@@ -37,12 +35,13 @@ router.post('/', upload.single('file'), async (req, res) => {
37
35
  });
38
36
  router.get('/', async (req, res) => {
39
37
  try {
40
- const [files] = await bucket.getFiles();
41
- const bucketName = bucket.name;
42
- const imageUrls = files.map(file => `https://storage.googleapis.com/${bucketName}/${file.name}`);
38
+ // const [files] = await bucket.getFiles();
39
+ // const bucketName = bucket.name;
40
+ // const imageUrls = files.map(file => `https://storage.googleapis.com/${bucketName}/${file.name}`);
41
+
43
42
  return res.status(200).json({
44
- message: 'Images fetched successfully',
45
- images: imageUrls
43
+ message: 'Images fetched successfully'
44
+ // images: imageUrls,
46
45
  });
47
46
  } catch (err) {
48
47
  console.error('Error listing files from GCS:', err);
@@ -6,7 +6,7 @@ const multer = require('multer');
6
6
  const path = require('path');
7
7
  const {
8
8
  getDb
9
- } = require('../services/dbService');
9
+ } = require("../services/mongo");
10
10
  const upload = multer({
11
11
  storage: multer.memoryStorage(),
12
12
  fileFilter: function (req, file, cb) {
@@ -239,4 +239,52 @@ router.post('/create-form', upload.single('jsonFile'), async (req, res) => {
239
239
  });
240
240
  }
241
241
  });
242
+
243
+ // Get form submissions
244
+ router.get("/submissions", async (req, res) => {
245
+ const projectId = req.projectId; // Use middleware-injected projectId
246
+
247
+ try {
248
+ const db = await getDb();
249
+ const submissions = await db.collection("formSubmissions").find({
250
+ projectId
251
+ }).toArray();
252
+ return res.json({
253
+ success: true,
254
+ data: submissions
255
+ });
256
+ } catch (error) {
257
+ console.error("Error fetching form submissions:", error);
258
+ return res.status(500).json({
259
+ success: false,
260
+ message: "Failed to fetch form submissions."
261
+ });
262
+ }
263
+ });
264
+
265
+ // Get form submissions by form ID
266
+ router.get("/submissions/:formId", async (req, res) => {
267
+ const {
268
+ formId
269
+ } = req.params;
270
+ const projectId = req.projectId; // Use middleware-injected projectId
271
+
272
+ try {
273
+ const db = await getDb();
274
+ const submissions = await db.collection("formSubmissions").find({
275
+ formId,
276
+ projectId
277
+ }).toArray();
278
+ return res.json({
279
+ success: true,
280
+ data: submissions
281
+ });
282
+ } catch (error) {
283
+ console.error("Error fetching form submissions:", error);
284
+ return res.status(500).json({
285
+ success: false,
286
+ message: "Failed to fetch form submissions."
287
+ });
288
+ }
289
+ });
242
290
  module.exports = router;
@@ -1,10 +1,13 @@
1
1
  "use strict";
2
2
 
3
3
  const express = require('express');
4
+ const {
5
+ injectProjectId
6
+ } = require('../middleware/projectId');
4
7
 
5
8
  // Import all route modules
6
9
  const commentsRoutes = require('./comments');
7
- // const filesRoutes = require('./files'); // Commented out for now
10
+ const filesRoutes = require('./files');
8
11
  const formsRoutes = require('./forms');
9
12
  const invoiceRoutes = require('./invoice');
10
13
  const likesRoutes = require('./likes');
@@ -14,34 +17,16 @@ const usersRoutes = require('./users');
14
17
  const waitlistsRoutes = require('./waitlists');
15
18
  const activitiesRoutes = require('./activities');
16
19
  const authRoutes = require('./auth');
17
- const blogsRoutes = require('./blogs');
18
20
  const slidesRoutes = require('./slides');
19
21
  const notificationsRoutes = require('./notifications');
20
- const createPowrRoutes = () => {
22
+ const profilesRoutes = require('./profiles');
23
+ const createPowrRoutes = (options = {}) => {
21
24
  const router = express.Router();
22
25
 
23
- // Middleware to inject projectId into all requests
24
- router.use((req, res, next) => {
25
- try {
26
- const {
27
- getConfig
28
- } = require('../config');
29
- const config = getConfig();
30
- req.projectId = config.projectId;
31
- } catch (error) {
32
- console.error('❌ Config error:', error.message);
33
- return res.status(500).json({
34
- success: false,
35
- message: 'Configuration error',
36
- error: error.message
37
- });
38
- }
39
- next();
40
- });
41
-
42
- // Mount all route modules
26
+ // Use the dedicated projectId injection middleware
27
+ router.use(injectProjectId(options));
43
28
  router.use('/comments', commentsRoutes);
44
- // router.use('/files', filesRoutes); // Commented out for now
29
+ router.use('/files', filesRoutes);
45
30
  router.use('/forms', formsRoutes);
46
31
  router.use('/invoice', invoiceRoutes);
47
32
  router.use('/likes', likesRoutes);
@@ -51,9 +36,9 @@ const createPowrRoutes = () => {
51
36
  router.use('/waitlists', waitlistsRoutes);
52
37
  router.use('/activities', activitiesRoutes);
53
38
  router.use('/auth', authRoutes);
54
- router.use('/blogs', blogsRoutes);
55
39
  router.use('/slides', slidesRoutes);
56
40
  router.use('/notifications', notificationsRoutes);
41
+ router.use('/profiles', profilesRoutes);
57
42
  return router;
58
43
  };
59
44
  module.exports = {
@@ -5,11 +5,6 @@ const router = express.Router();
5
5
  const {
6
6
  getDb
7
7
  } = require("../services/mongo");
8
- const data = [{
9
- age: 12
10
- }, {
11
- age: 45
12
- }];
13
8
  router.get("/:route", async (req, res) => {
14
9
  const {
15
10
  route
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ const express = require("express");
4
+ const router = express.Router();
5
+ const {
6
+ getDb
7
+ } = require("../services/mongo");
8
+
9
+ // Get all users for a project
10
+ router.get("/", async (req, res) => {
11
+ try {
12
+ const {
13
+ projectId
14
+ } = req.query;
15
+ const profiles = await getDb().collection("profiles").find({
16
+ projectId: projectId
17
+ }).toArray();
18
+ if (profiles.length === 0) {
19
+ return res.status(200).json({
20
+ success: true,
21
+ users: []
22
+ });
23
+ }
24
+
25
+ // Get core user data for all profiles
26
+ const userIds = profiles.map(profile => profile.userId);
27
+ const users = await getDb().collection("users").find({
28
+ _id: {
29
+ $in: userIds
30
+ }
31
+ }).toArray();
32
+
33
+ // Create a map for quick lookup
34
+ const usersMap = users.reduce((acc, user) => {
35
+ const {
36
+ password,
37
+ ...userWithoutPassword
38
+ } = user;
39
+ acc[user._id.toString()] = userWithoutPassword;
40
+ return acc;
41
+ }, {});
42
+
43
+ // Merge user and profile data
44
+ const usersWithProfiles = profiles.map(profile => ({
45
+ ...usersMap[profile.userId.toString()],
46
+ ...profile
47
+ }));
48
+ return res.status(200).json({
49
+ success: true,
50
+ users: usersWithProfiles
51
+ });
52
+ } catch (error) {
53
+ console.error("Error fetching project users:", error);
54
+ return res.status(500).json({
55
+ success: false,
56
+ message: "Failed to fetch project users"
57
+ });
58
+ }
59
+ });
60
+ module.exports = router;
@@ -4,7 +4,7 @@ const express = require("express");
4
4
  const router = express.Router();
5
5
  const {
6
6
  getDb
7
- } = require("../services/dbService");
7
+ } = require("../services/mongo");
8
8
 
9
9
  // Get all routes entries
10
10
  router.get('/', async (req, res) => {
@@ -8,167 +8,223 @@ const {
8
8
  const {
9
9
  ObjectId
10
10
  } = require("mongodb");
11
- router.post("/", async (req, res) => {
11
+ const {
12
+ verifyToken
13
+ } = require("../middleware/jwtToken");
14
+
15
+ // Create User
16
+ router.post("/", verifyToken, async (req, res) => {
12
17
  const {
13
- projectId,
14
18
  phoneNumber,
15
19
  email,
16
20
  ...userData
17
21
  } = req.body;
18
- if (!phoneNumber && !email) {
19
- return res.status(400).json({
20
- success: false,
21
- message: "phoneNumber or email is required."
22
- });
23
- }
24
- const user = {
25
- projectId,
26
- phoneNumber,
27
- email,
28
- ...userData,
29
- createdAt: new Date()
30
- };
22
+ const projectId = req.projectId; // Use middleware-injected projectId
23
+
31
24
  try {
32
- const usersCollection = getDb().collection("users");
33
- if (phoneNumber) {
34
- const existingByPhone = await usersCollection.findOne({
35
- projectId,
25
+ // Check if user already exists
26
+ const existingUser = await getDb().collection("users").findOne({
27
+ $or: [{
36
28
  phoneNumber
37
- });
38
- if (existingByPhone) {
39
- return res.status(409).json({
40
- success: false,
41
- message: "Phone number already exists."
42
- });
43
- }
44
- }
45
- if (email) {
46
- const existingByEmail = await usersCollection.findOne({
47
- projectId,
29
+ }, {
48
30
  email
31
+ }]
32
+ });
33
+ if (existingUser) {
34
+ return res.status(400).json({
35
+ success: false,
36
+ message: "User with this phone number or email already exists"
49
37
  });
50
- if (existingByEmail) {
51
- return res.status(409).json({
52
- success: false,
53
- message: "Email already exists."
54
- });
55
- }
56
38
  }
57
- const result = await getDb().collection("users").insertOne(user);
58
- return res.status(200).json({
39
+ const newUser = {
40
+ ...userData,
41
+ phoneNumber,
42
+ email,
43
+ createdAt: new Date(),
44
+ updatedAt: new Date()
45
+ };
46
+ const result = await getDb().collection("users").insertOne(newUser);
47
+
48
+ // Create profile for this project
49
+ const newProfile = {
50
+ userId: result.insertedId,
51
+ projectId: projectId,
52
+ access: userData.access || 1,
53
+ createdAt: new Date(),
54
+ updatedAt: new Date()
55
+ };
56
+ await getDb().collection("profiles").insertOne(newProfile);
57
+ return res.status(201).json({
59
58
  success: true,
60
- message: "User created successfully.",
59
+ message: "User created successfully",
61
60
  userId: result.insertedId
62
61
  });
63
62
  } catch (error) {
64
63
  console.error("Error creating user:", error);
65
64
  return res.status(500).json({
66
65
  success: false,
67
- message: "Internal server error."
66
+ message: "Failed to create user."
68
67
  });
69
68
  }
70
69
  });
71
- router.get("/", async (req, res) => {
70
+
71
+ // Get All Users
72
+ router.get("/", verifyToken, async (req, res) => {
72
73
  const {
73
- projectId,
74
74
  _id,
75
75
  phoneNumber,
76
76
  email
77
77
  } = req.query;
78
- if (!_id && !phoneNumber && !email) {
79
- return res.status(400).json({
80
- success: false,
81
- message: "no filters provided.",
82
- users: []
83
- });
84
- }
85
- const filter = {
86
- projectId
87
- };
88
- if (_id) {
89
- try {
90
- filter._id = new ObjectId(_id);
91
- } catch (e) {
92
- return res.status(400).json({
93
- success: false,
94
- message: "Invalid _id format."
95
- });
96
- }
97
- }
98
- if (phoneNumber) {
99
- filter.phoneNumber = phoneNumber;
100
- }
101
- if (email) {
102
- filter.email = email;
103
- }
78
+ const projectId = req.projectId; // Use middleware-injected projectId
79
+
104
80
  try {
105
- const users = await getDb().collection("users").find(filter).toArray();
106
- return res.status(200).json({
81
+ let query = {};
82
+
83
+ // Add filters if provided
84
+ if (_id) {
85
+ query._id = new ObjectId(_id);
86
+ }
87
+ if (phoneNumber) {
88
+ query.phoneNumber = phoneNumber;
89
+ }
90
+ if (email) {
91
+ query.email = email;
92
+ }
93
+ const users = await getDb().collection("users").find(query).toArray();
94
+
95
+ // Get profiles for this project
96
+ const userIds = users.map(user => user._id);
97
+ const profiles = await getDb().collection("profiles").find({
98
+ userId: {
99
+ $in: userIds
100
+ },
101
+ projectId: projectId
102
+ }).toArray();
103
+
104
+ // Merge user data with profile data
105
+ const usersWithProfiles = users.map(user => {
106
+ const profile = profiles.find(p => p.userId.toString() === user._id.toString());
107
+ return {
108
+ ...user,
109
+ access: profile ? profile.access : 1,
110
+ projectId: projectId
111
+ };
112
+ });
113
+ return res.json({
107
114
  success: true,
108
- message: "Users fetched successfully.",
109
- users
115
+ data: usersWithProfiles
110
116
  });
111
117
  } catch (error) {
112
118
  console.error("Error fetching users:", error);
113
119
  return res.status(500).json({
114
120
  success: false,
115
- message: "Internal server error."
121
+ message: "Failed to fetch users."
116
122
  });
117
123
  }
118
124
  });
119
- router.post("/getOrCreate", async (req, res) => {
125
+
126
+ // Update User
127
+ router.put("/:id", verifyToken, async (req, res) => {
128
+ const {
129
+ id
130
+ } = req.params;
120
131
  const {
121
- projectId,
122
132
  phoneNumber,
123
133
  email,
124
134
  ...userData
125
135
  } = req.body;
126
- if (!phoneNumber && !email) {
127
- return res.status(400).json({
128
- success: false,
129
- message: "phoneNumber or email is required."
130
- });
131
- }
132
- const user = {
133
- projectId,
134
- phoneNumber,
135
- email,
136
- ...userData,
137
- createdAt: new Date()
138
- };
136
+ const projectId = req.projectId; // Use middleware-injected projectId
137
+
139
138
  try {
140
- const usersCollection = getDb().collection("users");
141
- let existingUser = null;
142
- if (phoneNumber) {
143
- existingUser = await usersCollection.findOne({
144
- projectId,
145
- phoneNumber
139
+ // Check if user exists
140
+ const existingUser = await getDb().collection("users").findOne({
141
+ _id: new ObjectId(id)
142
+ });
143
+ if (!existingUser) {
144
+ return res.status(404).json({
145
+ success: false,
146
+ message: "User not found"
146
147
  });
147
148
  }
148
- if (!existingUser && email) {
149
- existingUser = await usersCollection.findOne({
150
- projectId,
151
- email
149
+
150
+ // Update user
151
+ const updateData = {
152
+ ...userData,
153
+ phoneNumber,
154
+ email,
155
+ updatedAt: new Date()
156
+ };
157
+ await getDb().collection("users").updateOne({
158
+ _id: new ObjectId(id)
159
+ }, {
160
+ $set: updateData
161
+ });
162
+
163
+ // Update profile if access level is provided
164
+ if (userData.access !== undefined) {
165
+ await getDb().collection("profiles").updateOne({
166
+ userId: new ObjectId(id),
167
+ projectId: projectId
168
+ }, {
169
+ $set: {
170
+ access: userData.access,
171
+ updatedAt: new Date()
172
+ }
173
+ }, {
174
+ upsert: true
152
175
  });
153
176
  }
154
- if (existingUser) {
155
- return res.status(200).json({
156
- success: true,
157
- message: "User already exists.",
158
- userId: existingUser._id
177
+ return res.json({
178
+ success: true,
179
+ message: "User updated successfully"
180
+ });
181
+ } catch (error) {
182
+ console.error("Error updating user:", error);
183
+ return res.status(500).json({
184
+ success: false,
185
+ message: "Failed to update user."
186
+ });
187
+ }
188
+ });
189
+
190
+ // Delete User
191
+ router.delete("/:id", verifyToken, async (req, res) => {
192
+ const {
193
+ id
194
+ } = req.params;
195
+ const projectId = req.projectId; // Use middleware-injected projectId
196
+
197
+ try {
198
+ // Check if user exists
199
+ const existingUser = await getDb().collection("users").findOne({
200
+ _id: new ObjectId(id)
201
+ });
202
+ if (!existingUser) {
203
+ return res.status(404).json({
204
+ success: false,
205
+ message: "User not found"
159
206
  });
160
207
  }
161
- const result = await usersCollection.insertOne(user);
162
- return res.status(200).json({
208
+
209
+ // Delete user
210
+ await getDb().collection("users").deleteOne({
211
+ _id: new ObjectId(id)
212
+ });
213
+
214
+ // Delete profile for this project
215
+ await getDb().collection("profiles").deleteOne({
216
+ userId: new ObjectId(id),
217
+ projectId: projectId
218
+ });
219
+ return res.json({
163
220
  success: true,
164
- message: "User created successfully.",
165
- userId: result.insertedId
221
+ message: "User deleted successfully"
166
222
  });
167
223
  } catch (error) {
168
- console.error("Error creating or fetching user:", error);
224
+ console.error("Error deleting user:", error);
169
225
  return res.status(500).json({
170
226
  success: false,
171
- message: "Internal server error."
227
+ message: "Failed to delete user."
172
228
  });
173
229
  }
174
230
  });
@@ -5,47 +5,47 @@ const router = express.Router();
5
5
  const {
6
6
  getDb
7
7
  } = require("../services/mongo");
8
+ const {
9
+ ObjectId
10
+ } = require("mongodb");
11
+
12
+ // Get all waitlists
13
+ router.get("/", async (req, res) => {
14
+ const projectId = req.projectId; // Use middleware-injected projectId
8
15
 
9
- // Get waitlist entries
10
- router.get('/', async (req, res) => {
11
- const {
12
- projectId
13
- } = req.query;
14
16
  try {
15
- const query = {
17
+ const waitlists = await getDb().collection("waitlists").find({
16
18
  projectId
17
- };
18
- console.log("Filter.....:", query);
19
- const waitlistData = await getDb().collection("waitlists").find(query).toArray();
20
- if (!waitlistData || waitlistData.length === 0) {
21
- console.log("Data not found.");
22
- return res.status(200).json({
23
- success: true,
24
- entries: []
25
- });
26
- }
27
- const sortedData = waitlistData.sort((a, b) => new Date(b === null || b === void 0 ? void 0 : b.createdAt) - new Date(a === null || a === void 0 ? void 0 : a.createdAt));
28
- console.log("Waitlist entries retrieved and sorted:", sortedData);
29
- return res.status(200).json({
19
+ }).toArray();
20
+ return res.json({
30
21
  success: true,
31
- entries: sortedData
22
+ data: waitlists
32
23
  });
33
24
  } catch (error) {
34
- console.error("Error retrieving waitlist entries:", error);
25
+ console.error("Error fetching waitlists:", error);
35
26
  return res.status(500).json({
36
27
  success: false,
37
- message: "Failed to retrieve waitlist entries."
28
+ message: "Failed to fetch waitlists."
38
29
  });
39
30
  }
40
31
  });
41
32
 
42
- // Original POST endpoint for adding to waitlist
33
+ // Add email to waitlist
43
34
  router.post("/", async (req, res) => {
44
35
  const {
45
- projectId,
46
36
  email
47
37
  } = req.body;
38
+ const projectId = req.projectId; // Use middleware-injected projectId
39
+
48
40
  try {
41
+ if (!email) {
42
+ return res.status(400).json({
43
+ success: false,
44
+ message: "Email is required"
45
+ });
46
+ }
47
+
48
+ // Check if email already exists in waitlist
49
49
  const existingEntry = await getDb().collection("waitlists").findOne({
50
50
  projectId,
51
51
  email
@@ -53,41 +53,56 @@ router.post("/", async (req, res) => {
53
53
  if (existingEntry) {
54
54
  return res.status(400).json({
55
55
  success: false,
56
- message: "You are already in the waitlist "
56
+ message: "Email already exists in waitlist"
57
57
  });
58
58
  }
59
+ const newEntry = {
60
+ projectId,
61
+ email,
62
+ createdAt: new Date()
63
+ };
64
+ const result = await getDb().collection("waitlists").insertOne(newEntry);
65
+ return res.status(201).json({
66
+ success: true,
67
+ message: "Email added to waitlist successfully",
68
+ id: result.insertedId
69
+ });
59
70
  } catch (error) {
60
- console.error("Error checking waitlist:", error);
71
+ console.error("Error adding to waitlist:", error);
61
72
  return res.status(500).json({
62
73
  success: false,
63
- message: "Failed to check waitlist due to a server error."
74
+ message: "Failed to add to waitlist."
64
75
  });
65
76
  }
66
- const waitListData = {
67
- projectId,
68
- email,
69
- createdAt: new Date()
70
- };
77
+ });
78
+
79
+ // Remove email from waitlist
80
+ router.delete("/:id", async (req, res) => {
81
+ const {
82
+ id
83
+ } = req.params;
84
+ const projectId = req.projectId; // Use middleware-injected projectId
85
+
71
86
  try {
72
- const result = await getDb().collection("waitlists").insertOne(waitListData);
73
- if (result && result.insertedId) {
74
- return res.status(200).json({
75
- success: true,
76
- message: "you are added in the waitist",
77
- userId: result.insertedId
78
- });
79
- } else {
80
- console.error("Insert operation failed. Result:", result);
81
- return res.status(500).json({
87
+ const result = await getDb().collection("waitlists").deleteOne({
88
+ _id: new ObjectId(id),
89
+ projectId
90
+ });
91
+ if (result.deletedCount === 0) {
92
+ return res.status(404).json({
82
93
  success: false,
83
- message: "user could not be added."
94
+ message: "Waitlist entry not found"
84
95
  });
85
96
  }
97
+ return res.json({
98
+ success: true,
99
+ message: "Email removed from waitlist successfully"
100
+ });
86
101
  } catch (error) {
87
- console.error("Error adding user:", error);
102
+ console.error("Error removing from waitlist:", error);
88
103
  return res.status(500).json({
89
104
  success: false,
90
- message: "Failed to add user due to a server error."
105
+ message: "Failed to remove from waitlist."
91
106
  });
92
107
  }
93
108
  });
@@ -3,38 +3,40 @@
3
3
  const {
4
4
  MongoClient
5
5
  } = require('mongodb');
6
-
7
- // Database service with lazy connection
8
- let client = null;
9
- let db = null;
10
- const getDb = async () => {
11
- // Return existing connection if available
12
- if (db) {
13
- return db;
14
- }
15
-
16
- // Connect only when first needed
6
+ const {
7
+ config
8
+ } = require('../config');
9
+ const mongoClient = new MongoClient(config.mongoUri, {
10
+ maxPoolSize: 10,
11
+ serverSelectionTimeoutMS: 5000,
12
+ socketTimeoutMS: 45000
13
+ });
14
+ let db;
15
+ async function connect() {
17
16
  try {
18
- const config = require('../config').getConfig();
19
- client = new MongoClient(config.mongoUri);
20
- await client.connect();
21
- db = client.db();
22
- console.log('✅ Connected to MongoDB via SDK (lazy connection)');
23
- return db;
17
+ await mongoClient.connect();
18
+ db = mongoClient.db();
19
+ console.log("Connected to MongoDB via SDK");
24
20
  } catch (error) {
25
- console.error('❌ MongoDB connection error:', error);
26
- throw error;
21
+ console.error("Failed to connect to MongoDB:", error);
22
+ process.exit(1);
27
23
  }
28
- };
24
+ }
25
+ function getDb() {
26
+ if (!db) {
27
+ throw new Error("Database not initialized. Call connectToMongo() first.");
28
+ }
29
+ return db;
30
+ }
29
31
  const closeConnection = async () => {
30
- if (client) {
31
- await client.close();
32
- client = null;
32
+ if (mongoClient) {
33
+ await mongoClient.close();
33
34
  db = null;
34
35
  console.log('✅ MongoDB connection closed');
35
36
  }
36
37
  };
37
38
  module.exports = {
39
+ connect,
38
40
  getDb,
39
41
  closeConnection
40
42
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "powr-sdk-api",
3
- "version": "2.3.7",
3
+ "version": "2.4.0",
4
4
  "description": "Shared API core library for PowrStack projects",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",