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.
- package/dist/routes/feeds.js +346 -0
- package/dist/routes/index.js +2 -0
- package/package.json +1 -1
|
@@ -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;
|
package/dist/routes/index.js
CHANGED
|
@@ -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
|
|