powr-sdk-api 2.1.0 → 2.2.1

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.
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+
3
+ const express = require("express");
4
+ const router = express.Router();
5
+ const multer = require('multer');
6
+ const path = require('path');
7
+ const {
8
+ getDb
9
+ } = require('../services/dbService');
10
+ const upload = multer({
11
+ storage: multer.memoryStorage(),
12
+ fileFilter: function (req, file, cb) {
13
+ if (file.mimetype === 'application/json' || path.extname(file.originalname).toLowerCase() === '.json') {
14
+ cb(null, true);
15
+ } else {
16
+ cb(new Error('Only JSON files are allowed!'), false);
17
+ }
18
+ },
19
+ limits: {
20
+ fileSize: 5 * 1024 * 1024
21
+ }
22
+ });
23
+
24
+ // GET all powrForm data based on projectId
25
+ router.get("/powrform", async (req, res) => {
26
+ const projectId = req.projectId;
27
+ try {
28
+ const db = await getDb();
29
+ const collection = db.collection("powrForm");
30
+ const forms = await collection.find({
31
+ projectId
32
+ }).toArray();
33
+ res.status(200).json({
34
+ success: true,
35
+ message: "Fetching powrForm data",
36
+ count: forms.length,
37
+ data: forms
38
+ });
39
+ } catch (error) {
40
+ res.status(500).json({
41
+ success: false,
42
+ message: "Internal server error",
43
+ error: error.message
44
+ });
45
+ }
46
+ });
47
+
48
+ // GET specific form by formName and projectId
49
+ router.get('/:formName', async (req, res) => {
50
+ try {
51
+ const {
52
+ formName
53
+ } = req.params;
54
+ const projectId = req.projectId;
55
+ if (!projectId) {
56
+ return res.status(400).json({
57
+ success: false,
58
+ message: 'projectId is required'
59
+ });
60
+ }
61
+ const db = await getDb();
62
+ const collection = db.collection("powrForm");
63
+ const formData = await collection.findOne({
64
+ formName,
65
+ projectId
66
+ });
67
+ if (!formData) {
68
+ return res.status(404).json({
69
+ success: false,
70
+ message: 'Form not found'
71
+ });
72
+ }
73
+ res.status(200).json({
74
+ success: true,
75
+ message: "Form fetched successfully",
76
+ data: formData
77
+ });
78
+ } catch (error) {
79
+ res.status(500).json({
80
+ success: false,
81
+ message: 'Error fetching form',
82
+ error: error.message
83
+ });
84
+ }
85
+ });
86
+
87
+ // POST /studentform
88
+ router.post('/studentform', async (req, res) => {
89
+ try {
90
+ const formData = req.body;
91
+ const projectId = req.projectId;
92
+ const {
93
+ whatsapp,
94
+ formName,
95
+ email,
96
+ ...otherFormFields
97
+ } = formData;
98
+ const db = await getDb();
99
+ const studentsFormCollection = db.collection('studentsForm');
100
+ const existingForm = await studentsFormCollection.findOne({
101
+ whatsapp: whatsapp,
102
+ projectId: projectId,
103
+ email: email,
104
+ formName: formName
105
+ });
106
+ if (existingForm) {
107
+ return res.status(409).json({
108
+ message: 'You have already submitted this form. Only one submission per form type is allowed.',
109
+ existingFormId: existingForm._id,
110
+ submittedAt: existingForm.submittedAt
111
+ });
112
+ }
113
+ const studentFormData = {
114
+ whatsapp: whatsapp,
115
+ formName: formName,
116
+ projectId: projectId,
117
+ email: email,
118
+ ...otherFormFields,
119
+ submittedAt: new Date()
120
+ };
121
+ const formResult = await studentsFormCollection.insertOne(studentFormData);
122
+ res.status(201).json({
123
+ success: true,
124
+ message: 'Student form submitted successfully',
125
+ submittedFormId: formResult.insertedId,
126
+ data: studentFormData
127
+ });
128
+ } catch (error) {
129
+ res.status(500).json({
130
+ success: false,
131
+ message: 'Error submitting student form',
132
+ error: error.message
133
+ });
134
+ }
135
+ });
136
+
137
+ //get form
138
+ router.get('/getCount/:formName', async (req, res) => {
139
+ try {
140
+ const {
141
+ formName
142
+ } = req.params;
143
+ const {
144
+ projectId
145
+ } = req.query;
146
+ const studentsFormCollection = getDb().collection('studentsForm');
147
+
148
+ // Build query object
149
+ let query = {
150
+ formName
151
+ };
152
+ if (projectId) {
153
+ query.projectId = projectId;
154
+ }
155
+ const submissions = await studentsFormCollection.find(query).toArray();
156
+ res.status(200).json({
157
+ success: true,
158
+ message: 'Submission count retrieved successfully',
159
+ formName: formName,
160
+ projectId: projectId,
161
+ count: submissions.length,
162
+ data: submissions
163
+ });
164
+ } catch (error) {
165
+ res.status(500).json({
166
+ success: false,
167
+ message: 'Error counting form submissions',
168
+ error: error.message
169
+ });
170
+ }
171
+ });
172
+
173
+ // POST /create-form - Upload JSON file and store form data
174
+ router.post('/create-form', upload.single('jsonFile'), async (req, res) => {
175
+ try {
176
+ const {
177
+ projectId
178
+ } = req.query;
179
+ if (!projectId) {
180
+ return res.status(400).json({
181
+ success: false,
182
+ message: 'projectId is required as query parameter'
183
+ });
184
+ }
185
+ if (!req.file) {
186
+ return res.status(400).json({
187
+ success: false,
188
+ message: 'JSON file is required'
189
+ });
190
+ }
191
+ let formData;
192
+ try {
193
+ const fileContent = req.file.buffer.toString('utf8');
194
+ formData = JSON.parse(fileContent);
195
+ } catch (parseError) {
196
+ return res.status(400).json({
197
+ success: false,
198
+ message: 'Invalid JSON file format',
199
+ error: parseError.message
200
+ });
201
+ }
202
+ if (!formData.formName) {
203
+ return res.status(400).json({
204
+ success: false,
205
+ message: 'formName is required in JSON data'
206
+ });
207
+ }
208
+ const powrFormCollection = getDb().collection('powrForm');
209
+ const existingForm = await powrFormCollection.findOne({
210
+ formName: formData.formName,
211
+ projectId: projectId
212
+ });
213
+ if (existingForm) {
214
+ return res.status(409).json({
215
+ success: false,
216
+ message: 'Form with this name already exists for this project',
217
+ existingFormId: existingForm._id
218
+ });
219
+ }
220
+ const finalFormData = {
221
+ ...formData,
222
+ projectId: projectId,
223
+ createdAt: new Date()
224
+ };
225
+ const result = await powrFormCollection.insertOne(finalFormData);
226
+ res.status(201).json({
227
+ success: true,
228
+ message: 'Form created and stored successfully',
229
+ formId: result.insertedId,
230
+ formName: formData.formName,
231
+ projectId: projectId,
232
+ data: finalFormData
233
+ });
234
+ } catch (error) {
235
+ res.status(500).json({
236
+ success: false,
237
+ message: 'Error creating form',
238
+ error: error.message
239
+ });
240
+ }
241
+ });
242
+ module.exports = router;
@@ -1,75 +1,53 @@
1
1
  "use strict";
2
2
 
3
- // Main routes index for powr-sdk-api
4
- // This file exports all route handlers for easy integration
3
+ const express = require('express');
5
4
 
6
- const {
7
- createAdminRoutes
8
- } = require('./admin');
9
- const createRoutes = (app, options = {}) => {
5
+ // Import all route modules
6
+ const commentsRoutes = require('./comments');
7
+ // const filesRoutes = require('./files'); // Commented out for now
8
+ const formsRoutes = require('./forms');
9
+ const invoiceRoutes = require('./invoice');
10
+ const likesRoutes = require('./likes');
11
+ const plexxRoutes = require('./plexx');
12
+ const ratingsRoutes = require('./ratings');
13
+ const usersRoutes = require('./users');
14
+ const waitlistsRoutes = require('./waitlists');
15
+ const activitiesRoutes = require('./activities');
16
+ const authRoutes = require('./auth');
17
+ const blogsRoutes = require('./blogs');
18
+ const slidesRoutes = require('./slides');
19
+ const notificationsRoutes = require('./notifications');
20
+ const createPowrRoutes = () => {
21
+ // Get config from environment variables
10
22
  const {
11
- projectId,
12
- baseUrl = '/api',
13
- authMiddleware = null,
14
- logger = console,
15
- mongoUrl = process.env.MONGODB_URI || 'mongodb://localhost:27017/powrbase'
16
- } = options;
23
+ getConfig
24
+ } = require('../config');
25
+ const config = getConfig();
26
+ const router = express.Router();
17
27
 
18
- // Apply auth middleware if provided
19
- if (authMiddleware) {
20
- app.use(`${baseUrl}/admin`, authMiddleware);
21
- }
22
-
23
- // Initialize admin routes
24
- createAdminRoutes(app, {
25
- projectId,
26
- apiUrl: `${baseUrl}/admin`,
27
- authMiddleware,
28
- logger,
29
- mongoUrl
30
- });
31
-
32
- // Health check endpoint
33
- app.get(`${baseUrl}/health`, (req, res) => {
34
- res.json({
35
- success: true,
36
- message: 'API is running',
37
- projectId,
38
- timestamp: new Date().toISOString()
39
- });
28
+ // Middleware to inject projectId into all requests
29
+ router.use((req, res, next) => {
30
+ req.projectId = config.projectId;
31
+ next();
40
32
  });
41
33
 
42
- // Project info endpoint
43
- app.get(`${baseUrl}/info`, (req, res) => {
44
- res.json({
45
- success: true,
46
- projectId,
47
- version: '2.0.1',
48
- features: ['forms', 'waitlists', 'slides', 'invoices', 'notifications']
49
- });
50
- });
51
- logger.info('All routes initialized for project:', projectId);
52
- return app;
53
- };
54
-
55
- // Utility function to get available routes
56
- const getAvailableRoutes = () => {
57
- return {
58
- admin: {
59
- forms: ['GET', 'POST', 'PUT', 'DELETE'],
60
- waitlists: ['GET', 'POST'],
61
- slides: ['GET', 'POST', 'PUT', 'DELETE'],
62
- invoices: ['GET', 'POST', 'PUT'],
63
- notifications: ['GET', 'POST', 'PUT']
64
- },
65
- utility: {
66
- health: ['GET'],
67
- info: ['GET']
68
- }
69
- };
34
+ // Mount all route modules
35
+ router.use('/comments', commentsRoutes);
36
+ // router.use('/files', filesRoutes); // Commented out for now
37
+ router.use('/forms', formsRoutes);
38
+ router.use('/invoice', invoiceRoutes);
39
+ router.use('/likes', likesRoutes);
40
+ router.use('/plexx', plexxRoutes);
41
+ router.use('/ratings', ratingsRoutes);
42
+ router.use('/users', usersRoutes);
43
+ router.use('/waitlists', waitlistsRoutes);
44
+ router.use('/activities', activitiesRoutes);
45
+ router.use('/auth', authRoutes);
46
+ router.use('/blogs', blogsRoutes);
47
+ router.use('/slides', slidesRoutes);
48
+ router.use('/notifications', notificationsRoutes);
49
+ return router;
70
50
  };
71
51
  module.exports = {
72
- createRoutes,
73
- createAdminRoutes,
74
- getAvailableRoutes
52
+ createPowrRoutes
75
53
  };
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+
3
+ const express = require('express');
4
+ const router = express.Router();
5
+ const {
6
+ getDb
7
+ } = require("../services/mongo");
8
+ const {
9
+ ObjectId
10
+ } = require("mongodb");
11
+ router.get('/', async (req, res) => {
12
+ const {
13
+ projectId
14
+ } = req.query;
15
+ try {
16
+ const query = {
17
+ projectId
18
+ };
19
+ if (!projectId) {
20
+ return res.status(400).json({
21
+ success: false,
22
+ message: 'projectId is required.'
23
+ });
24
+ }
25
+ const invoiceData = await getDb().collection("invoices").find(query).toArray();
26
+ return res.status(200).json({
27
+ success: true,
28
+ invoices: invoiceData
29
+ });
30
+ } catch (error) {
31
+ console.error("Error retrieving invoices :", error);
32
+ return res.status(500).json({
33
+ success: false,
34
+ message: "Failed to retrieve invoices ."
35
+ });
36
+ }
37
+ });
38
+ router.get('/:invoiceId', async (req, res) => {
39
+ const {
40
+ invoiceId
41
+ } = req.params;
42
+ const {
43
+ projectId
44
+ } = req.query;
45
+ try {
46
+ if (!projectId) {
47
+ return res.status(400).json({
48
+ success: false,
49
+ message: 'projectId is required.'
50
+ });
51
+ }
52
+ const _id = new ObjectId(invoiceId);
53
+ const invoiceData = await getDb().collection("invoices").findOne({
54
+ _id,
55
+ projectId
56
+ });
57
+ return res.status(200).json({
58
+ success: true,
59
+ invoice: invoiceData
60
+ });
61
+ } catch (error) {
62
+ console.error("Error retrieving invoice :", error);
63
+ return res.status(500).json({
64
+ success: false,
65
+ message: "Failed to retrieve invoice."
66
+ });
67
+ }
68
+ });
69
+ router.post('/', async (req, res) => {
70
+ const {
71
+ projectId
72
+ } = req.query;
73
+ const {
74
+ invoiceNumber,
75
+ dateOfIssue,
76
+ paymentStatus,
77
+ customerInfo,
78
+ serviceSection,
79
+ paymentSection
80
+ } = req.body;
81
+ if (!projectId) {
82
+ return res.status(400).json({
83
+ success: false,
84
+ message: "projectId is required."
85
+ });
86
+ }
87
+ const invoice = {
88
+ invoiceNumber,
89
+ dateOfIssue,
90
+ paymentStatus,
91
+ customerInfo,
92
+ serviceSection,
93
+ paymentSection,
94
+ createdAt: new Date()
95
+ };
96
+ invoice.projectId = projectId;
97
+ try {
98
+ const result = await getDb().collection("invoices").insertOne(invoice);
99
+ if (result && result.insertedId) {
100
+ return res.status(201).json({
101
+ success: true,
102
+ message: "Invoice created successfully.",
103
+ invoiceId: result.insertedId,
104
+ invoice
105
+ });
106
+ } else {
107
+ return res.status(500).json({
108
+ success: false,
109
+ message: "Invoice could not be added."
110
+ });
111
+ }
112
+ } catch (error) {
113
+ console.error("Error adding invoice:", error);
114
+ return res.status(500).json({
115
+ success: false,
116
+ message: "Failed to add invoice due to a server error."
117
+ });
118
+ }
119
+ });
120
+ router.put('/:invoiceId', async (req, res) => {
121
+ const {
122
+ invoiceId
123
+ } = req.params;
124
+ const {
125
+ projectId
126
+ } = req.query;
127
+ if (!projectId) {
128
+ return res.status(400).json({
129
+ success: false,
130
+ message: "projectId is required."
131
+ });
132
+ }
133
+ let filter;
134
+ try {
135
+ filter = {
136
+ _id: new ObjectId(invoiceId),
137
+ projectId: projectId
138
+ };
139
+ } catch (e) {
140
+ return res.status(400).json({
141
+ success: false,
142
+ message: "Invalid invoiceId format."
143
+ });
144
+ }
145
+ const updateData = req.body;
146
+ try {
147
+ const result = await getDb().collection("invoices").updateOne(filter, {
148
+ $set: updateData
149
+ });
150
+ return res.status(200).json({
151
+ success: true,
152
+ message: "Invoice updated successfully.",
153
+ result: result
154
+ });
155
+ } catch (error) {
156
+ console.error("Error updating invoice:", error);
157
+ return res.status(500).json({
158
+ success: false,
159
+ message: "Failed to update invoice due to a server error."
160
+ });
161
+ }
162
+ });
163
+ module.exports = router;
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+
3
+ const express = require('express');
4
+ const router = express.Router();
5
+ const {
6
+ getDb
7
+ } = require("../services/mongo");
8
+ const {
9
+ ObjectId
10
+ } = require("mongodb");
11
+
12
+ // Like/Unlike endpoint
13
+ router.post('/', async (req, res) => {
14
+ const {
15
+ liked
16
+ } = req.body;
17
+ const {
18
+ userId,
19
+ projectId,
20
+ contentId
21
+ } = req.query;
22
+ if (!userId || typeof liked !== 'boolean' || !projectId) {
23
+ return res.status(400).json({
24
+ success: false,
25
+ message: 'userId and projectId are required in query, liked (boolean) is required in body.'
26
+ });
27
+ }
28
+ try {
29
+ const query = {
30
+ userId: new ObjectId(userId),
31
+ projectId
32
+ };
33
+ const setObj = {
34
+ liked
35
+ };
36
+ if (contentId) {
37
+ query.contentId = contentId;
38
+ setObj.contentId = contentId;
39
+ }
40
+ const response = await getDb().collection('likes').updateOne(query, {
41
+ $set: setObj
42
+ }, {
43
+ upsert: true
44
+ });
45
+ return res.status(200).json({
46
+ success: true,
47
+ message: liked ? 'Liked.' : 'Unliked.',
48
+ response
49
+ });
50
+ } catch (error) {
51
+ console.error('Error updating like status:', error);
52
+ return res.status(500).json({
53
+ success: false,
54
+ message: 'Failed to update like status.'
55
+ });
56
+ }
57
+ });
58
+ router.get('/', async (req, res) => {
59
+ const {
60
+ projectId,
61
+ contentId
62
+ } = req.query;
63
+ if (!projectId) {
64
+ return res.status(400).json({
65
+ success: false,
66
+ message: 'projectId is required in query.'
67
+ });
68
+ }
69
+ try {
70
+ const query = {
71
+ projectId
72
+ };
73
+ if (contentId) {
74
+ query.contentId = contentId;
75
+ }
76
+ const likes = await getDb().collection('likes').find(query).toArray();
77
+ const likesCount = likes.filter(like => like.liked === true).length;
78
+ const unlikesCount = likes.filter(like => like.liked === false).length;
79
+ return res.status(200).json({
80
+ success: true,
81
+ likes,
82
+ likesCount,
83
+ unlikesCount
84
+ });
85
+ } catch (error) {
86
+ console.error('Error fetching likes:', error);
87
+ return res.status(500).json({
88
+ success: false,
89
+ message: 'Failed to fetch likes.'
90
+ });
91
+ }
92
+ });
93
+ router.get('/:likeId', async (req, res) => {
94
+ const {
95
+ likeId
96
+ } = req.params;
97
+ const {
98
+ projectId,
99
+ contentId
100
+ } = req.query;
101
+ try {
102
+ const filter = {
103
+ userId: new ObjectId(likeId)
104
+ };
105
+ if (projectId) filter.projectId = projectId;
106
+ if (contentId) filter.contentId = contentId;
107
+ const like = await getDb().collection('likes').findOne(filter);
108
+ if (!like) {
109
+ return res.status(404).json({
110
+ success: false,
111
+ message: 'Like not found.'
112
+ });
113
+ }
114
+ return res.status(200).json({
115
+ success: true,
116
+ like
117
+ });
118
+ } catch (error) {
119
+ console.error('Error fetching like by id:', error);
120
+ return res.status(500).json({
121
+ success: false,
122
+ message: 'Failed to fetch like.'
123
+ });
124
+ }
125
+ });
126
+ module.exports = router;