powr-sdk-api 3.1.5 → 3.1.6

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,346 @@
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
+ // Create new post
13
+ router.post('/', async (req, res) => {
14
+ try {
15
+ const {
16
+ content,
17
+ media,
18
+ isPublic = true,
19
+ tags,
20
+ mentions
21
+ } = req.body;
22
+ const projectId = req.projectId;
23
+ const userId = req.user.id;
24
+ if (!content && (!media || media.length === 0)) {
25
+ return res.status(400).json({
26
+ success: false,
27
+ message: 'Content or media is required'
28
+ });
29
+ }
30
+ const db = await getDb();
31
+ const newPost = {
32
+ projectId,
33
+ authorId: new ObjectId(userId),
34
+ content: content || '',
35
+ media: media || [],
36
+ likesCount: 0,
37
+ commentsCount: 0,
38
+ isPublic,
39
+ tags: tags || [],
40
+ mentions: mentions ? mentions.map(id => new ObjectId(id)) : [],
41
+ createdAt: new Date(),
42
+ updatedAt: new Date()
43
+ };
44
+ const result = await db.collection('feeds').insertOne(newPost);
45
+
46
+ // Populate author info
47
+ const author = await db.collection('users').findOne({
48
+ _id: new ObjectId(userId)
49
+ }, {
50
+ projection: {
51
+ name: 1,
52
+ email: 1,
53
+ avatar: 1
54
+ }
55
+ });
56
+ const createdPost = {
57
+ ...newPost,
58
+ _id: result.insertedId,
59
+ author
60
+ };
61
+ return res.status(201).json({
62
+ success: true,
63
+ message: 'Post created successfully',
64
+ data: createdPost
65
+ });
66
+ } catch (error) {
67
+ console.error('Error creating post:', error);
68
+ return res.status(500).json({
69
+ success: false,
70
+ message: 'Failed to create post'
71
+ });
72
+ }
73
+ });
74
+
75
+ // Get feed with pagination and filters
76
+ router.get('/', async (req, res) => {
77
+ try {
78
+ const {
79
+ page = 1,
80
+ limit = 10,
81
+ userId,
82
+ tag,
83
+ search
84
+ } = req.query;
85
+ const projectId = req.projectId;
86
+ const skip = (parseInt(page) - 1) * parseInt(limit);
87
+ const query = {
88
+ projectId
89
+ };
90
+ if (userId) {
91
+ query.authorId = new ObjectId(userId);
92
+ }
93
+ if (tag) {
94
+ query.tags = {
95
+ $in: [tag]
96
+ };
97
+ }
98
+ if (search) {
99
+ query.$or = [{
100
+ content: {
101
+ $regex: search,
102
+ $options: 'i'
103
+ }
104
+ }, {
105
+ tags: {
106
+ $in: [new RegExp(search, 'i')]
107
+ }
108
+ }];
109
+ }
110
+ const db = await getDb();
111
+
112
+ // Get posts with author info
113
+ const posts = await db.collection('feeds').aggregate([{
114
+ $match: query
115
+ }, {
116
+ $sort: {
117
+ createdAt: -1
118
+ }
119
+ }, {
120
+ $skip: skip
121
+ }, {
122
+ $limit: parseInt(limit)
123
+ }, {
124
+ $lookup: {
125
+ from: 'users',
126
+ localField: 'authorId',
127
+ foreignField: '_id',
128
+ as: 'author'
129
+ }
130
+ }, {
131
+ $unwind: '$author'
132
+ }, {
133
+ $project: {
134
+ 'author.password': 0,
135
+ 'author.access': 0
136
+ }
137
+ }]).toArray();
138
+ const total = await db.collection('feeds').countDocuments(query);
139
+ return res.json({
140
+ success: true,
141
+ data: posts,
142
+ pagination: {
143
+ page: parseInt(page),
144
+ limit: parseInt(limit),
145
+ total,
146
+ pages: Math.ceil(total / parseInt(limit))
147
+ }
148
+ });
149
+ } catch (error) {
150
+ console.error('Error fetching feed:', error);
151
+ return res.status(500).json({
152
+ success: false,
153
+ message: 'Failed to fetch feed'
154
+ });
155
+ }
156
+ });
157
+
158
+ // Get single post
159
+ router.get('/:id', async (req, res) => {
160
+ try {
161
+ const {
162
+ id
163
+ } = req.params;
164
+ const projectId = req.projectId;
165
+ const db = await getDb();
166
+ const post = await db.collection('feeds').aggregate([{
167
+ $match: {
168
+ _id: new ObjectId(id),
169
+ projectId
170
+ }
171
+ }, {
172
+ $lookup: {
173
+ from: 'users',
174
+ localField: 'authorId',
175
+ foreignField: '_id',
176
+ as: 'author'
177
+ }
178
+ }, {
179
+ $unwind: '$author'
180
+ }, {
181
+ $project: {
182
+ 'author.password': 0,
183
+ 'author.access': 0
184
+ }
185
+ }]).next();
186
+ if (!post) {
187
+ return res.status(404).json({
188
+ success: false,
189
+ message: 'Post not found'
190
+ });
191
+ }
192
+ return res.json({
193
+ success: true,
194
+ data: post
195
+ });
196
+ } catch (error) {
197
+ console.error('Error fetching post:', error);
198
+ return res.status(500).json({
199
+ success: false,
200
+ message: 'Failed to fetch post'
201
+ });
202
+ }
203
+ });
204
+
205
+ // Update post
206
+ router.put('/:id', async (req, res) => {
207
+ try {
208
+ const {
209
+ id
210
+ } = req.params;
211
+ const {
212
+ content,
213
+ media,
214
+ isPublic,
215
+ tags,
216
+ mentions
217
+ } = req.body;
218
+ const projectId = req.projectId;
219
+ const userId = req.user.id;
220
+ const db = await getDb();
221
+ const post = await db.collection('feeds').findOne({
222
+ _id: new ObjectId(id),
223
+ projectId,
224
+ authorId: new ObjectId(userId)
225
+ });
226
+ if (!post) {
227
+ return res.status(404).json({
228
+ success: false,
229
+ message: 'Post not found or unauthorized'
230
+ });
231
+ }
232
+ const updateData = {
233
+ updatedAt: new Date()
234
+ };
235
+ if (content !== undefined) updateData.content = content;
236
+ if (media !== undefined) updateData.media = media;
237
+ if (isPublic !== undefined) updateData.isPublic = isPublic;
238
+ if (tags !== undefined) updateData.tags = tags;
239
+ if (mentions !== undefined) updateData.mentions = mentions.map(id => new ObjectId(id));
240
+ await db.collection('feeds').updateOne({
241
+ _id: new ObjectId(id)
242
+ }, {
243
+ $set: updateData
244
+ });
245
+ return res.json({
246
+ success: true,
247
+ message: 'Post updated successfully'
248
+ });
249
+ } catch (error) {
250
+ console.error('Error updating post:', error);
251
+ return res.status(500).json({
252
+ success: false,
253
+ message: 'Failed to update post'
254
+ });
255
+ }
256
+ });
257
+
258
+ // Delete post
259
+ router.delete('/:id', async (req, res) => {
260
+ try {
261
+ const {
262
+ id
263
+ } = req.params;
264
+ const projectId = req.projectId;
265
+ const userId = req.user.id;
266
+ const db = await getDb();
267
+ const post = await db.collection('feeds').findOne({
268
+ _id: new ObjectId(id),
269
+ projectId,
270
+ authorId: new ObjectId(userId)
271
+ });
272
+ if (!post) {
273
+ return res.status(404).json({
274
+ success: false,
275
+ message: 'Post not found or unauthorized'
276
+ });
277
+ }
278
+ await db.collection('feeds').deleteOne({
279
+ _id: new ObjectId(id)
280
+ });
281
+ return res.json({
282
+ success: true,
283
+ message: 'Post deleted successfully'
284
+ });
285
+ } catch (error) {
286
+ console.error('Error deleting post:', error);
287
+ return res.status(500).json({
288
+ success: false,
289
+ message: 'Failed to delete post'
290
+ });
291
+ }
292
+ });
293
+
294
+ // Like/unlike post
295
+ router.post('/:id/like', async (req, res) => {
296
+ try {
297
+ const {
298
+ id
299
+ } = req.params;
300
+ const {
301
+ liked
302
+ } = req.body;
303
+ const projectId = req.projectId;
304
+ const userId = req.user.id;
305
+ const db = await getDb();
306
+
307
+ // Update like count
308
+ const updateOperation = liked ? {
309
+ $inc: {
310
+ likesCount: 1
311
+ }
312
+ } : {
313
+ $inc: {
314
+ likesCount: -1
315
+ }
316
+ };
317
+ await db.collection('feeds').updateOne({
318
+ _id: new ObjectId(id),
319
+ projectId
320
+ }, updateOperation);
321
+
322
+ // Update user's like status
323
+ await db.collection('likes').updateOne({
324
+ userId: new ObjectId(userId),
325
+ contentId: id,
326
+ projectId
327
+ }, {
328
+ $set: {
329
+ liked
330
+ }
331
+ }, {
332
+ upsert: true
333
+ });
334
+ return res.json({
335
+ success: true,
336
+ message: liked ? 'Post liked' : 'Post unliked'
337
+ });
338
+ } catch (error) {
339
+ console.error('Error updating like:', error);
340
+ return res.status(500).json({
341
+ success: false,
342
+ message: 'Failed to update like'
343
+ });
344
+ }
345
+ });
346
+ module.exports = router;
@@ -25,6 +25,7 @@ const slidesRoutes = require('./slides');
25
25
  const notificationsRoutes = require('./notifications');
26
26
  const profilesRoutes = require('./profiles');
27
27
  const chatRoutes = require('./chat');
28
+ const feedsRoutes = require('./feeds');
28
29
 
29
30
  // Synchronous router creation
30
31
  const createPowrRoutes = (options = {}) => {
@@ -47,6 +48,7 @@ const createPowrRoutes = (options = {}) => {
47
48
  router.use('/notifications', verifyToken, notificationsRoutes);
48
49
  router.use('/profiles', verifyToken, profilesRoutes);
49
50
  router.use('/chat', verifyToken, chatRoutes);
51
+ router.use('/feeds', verifyToken, feedsRoutes);
50
52
  return router;
51
53
  };
52
54
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "powr-sdk-api",
3
- "version": "3.1.5",
3
+ "version": "3.1.6",
4
4
  "description": "Shared API core library for PowrStack projects",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",