Skip to content

Commit b1f4491

Browse files
committed
Implementation of REST API for projects routes and some events, posts routes
1 parent d05feae commit b1f4491

File tree

14 files changed

+410
-13
lines changed

14 files changed

+410
-13
lines changed

app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const eventRouter = require('./app/routes/event')
1313
const shortUrlRouter = require('./app/routes/urlShortner')
1414
const organizationRouter = require('./app/routes/organisation')
1515
const commentRouter = require('./app/routes/comment')
16+
const projectRouter = require('./app/routes/project')
1617

1718
const app = express()
1819

@@ -34,6 +35,7 @@ app.use('/org', organizationRouter)
3435
app.use('/event', eventRouter)
3536
app.use('/shortUrl', shortUrlRouter)
3637
app.use('/comment', commentRouter)
38+
app.use('/project', projectRouter)
3739

3840
// catch 404 and forward to error handler
3941
app.use(function (req, res, next) {

app/controllers/event.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module.exports = {
55
createEvent: async (req, res, next) => {
66
const event = new Event(req.body)
77
try {
8+
event.createdBy = req.user._id
89
await event.save()
910
res.status(HttpStatus.CREATED).json({ event: event })
1011
} catch (error) {
@@ -131,5 +132,22 @@ module.exports = {
131132
} catch (error) {
132133
HANDLER.handleError(res, next)
133134
}
135+
},
136+
getAllEventByUser: async (req, res, next) => {
137+
const pagination = req.query.pagination ? req.query.pagination : 10
138+
const currentPage = req.query.page ? req.query.page : 1
139+
try {
140+
const events = await Event.find({ createdBy: req.user._id })
141+
.skip((currentPage - 1) * pagination)
142+
.limit(pagination)
143+
.populate('createdBy', '_id name.firstName name.lastName')
144+
.exec()
145+
if (events.length === 0) {
146+
return res.status(HttpStatus.OK).json({ msg: 'No events posted by user!' })
147+
}
148+
return res.status(HttpStatus.OK).json({ events })
149+
} catch (error) {
150+
HANDLER.handleError(res, error)
151+
}
134152
}
135153
}

app/controllers/post.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,5 +133,23 @@ module.exports = {
133133
} catch (error) {
134134
HANDLER.handleError(res, error)
135135
}
136+
},
137+
getPostByUser: async (req, res, next) => {
138+
const pagination = req.query.pagination ? parseInt(req.query.pagination) : 10
139+
const currentPage = req.query.page ? parseInt(req.query.page) : 1
140+
try {
141+
const posts = await PostModel.find({ userId: req.user._id })
142+
.skip((currentPage - 1) * pagination)
143+
.limit(pagination)
144+
.populate('comments', ['content', 'votes'])
145+
.sort({ updatedAt: -1 })
146+
.exec()
147+
if (posts.length === 0) {
148+
return res.status(HttpStatus.OK).json({ msg: 'No posts found!' })
149+
}
150+
return res.status(HttpStatus.OK).json({ posts })
151+
} catch (error) {
152+
HANDLER.handleError(res, error)
153+
}
136154
}
137155
}

app/controllers/project.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
const Project = require('../models/Project')
2+
const HANDLER = require('../utils/response-helper')
3+
const HttpStatus = require('http-status-codes')
4+
5+
module.exports = {
6+
createProject: async (req, res, next) => {
7+
try {
8+
const project = await new Project(req.body)
9+
project.createdBy = req.user._id
10+
await project.save()
11+
return res.status(HttpStatus.CREATED).json({ project })
12+
} catch (error) {
13+
HANDLER.handleError(res, error)
14+
}
15+
},
16+
getAllProjects: async (req, res, next) => {
17+
const pagination = req.query.pagination ? parseInt(req.query.pagination) : 10
18+
const page = req.query.page ? parseInt(req.query.page) : 1
19+
try {
20+
const projects = await Project.find({})
21+
.skip((page - 1) * pagination)
22+
.limit(pagination)
23+
.populate('createdBy', '_id name.firstName name.lastName email')
24+
.sort({ updatedAt: -1 })
25+
.exec()
26+
return res.status(HttpStatus.OK).json({ projects })
27+
} catch (error) {
28+
HANDLER.handleError(res, error)
29+
}
30+
},
31+
getProjectById: async (req, res, next) => {
32+
const { id } = req.params
33+
try {
34+
const project = await Project.findById(id)
35+
.populate('createdBy', '_id name.firstName name.lastName email')
36+
.lean()
37+
.exec()
38+
if (!project) {
39+
return res.status(HttpStatus.OK).json({ msg: 'Post doesn\'t exists!' })
40+
}
41+
return res.status(HttpStatus.OK).json({ project })
42+
} catch (error) {
43+
HANDLER.handleError(res, error)
44+
}
45+
},
46+
updateProject: async (req, res, next) => {
47+
const { id } = req.params
48+
const updates = Object.keys(req.body)
49+
const allowedUpdates = [
50+
'projectName',
51+
'description',
52+
'imgUrl',
53+
'img',
54+
'version',
55+
'links',
56+
'contributors',
57+
'maintainers'
58+
]
59+
const isValidOperation = updates.every((update) => {
60+
return allowedUpdates.includes(update)
61+
})
62+
try {
63+
const project = await Project.findById(id)
64+
.populate('createdBy', '_id name.firstName name.lastName email')
65+
.exec()
66+
if (!project) {
67+
return res.status(HttpStatus.NOT_FOUND).json({ msg: 'No such project exits!' })
68+
}
69+
if (!isValidOperation) {
70+
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'Invalid update!' })
71+
}
72+
updates.forEach((update) => {
73+
project[update] = req.body[update]
74+
})
75+
await project.save()
76+
return res.status(HttpStatus.OK).json({ project })
77+
} catch (error) {
78+
HANDLER.handleError(res, error)
79+
}
80+
},
81+
deleteProject: async (req, res, next) => {
82+
const { id } = req.params
83+
try {
84+
const project = await Project.findById(id)
85+
if (!project) {
86+
return res.status(HttpStatus.NOT_FOUND).json({ msg: 'No such project exits!' })
87+
}
88+
// check if admin or user who created this project
89+
if (project.createdBy === req.user._id.toString() || req.user.isAdmin === true) {
90+
await Project.findByIdAndRemove(id)
91+
return res.status(HttpStatus.OK).json({ msg: 'Project deleted!' })
92+
}
93+
} catch (error) {
94+
HANDLER.handleError(res, error)
95+
}
96+
},
97+
projectCreatedByUser: async (req, res, next) => {
98+
const pagination = req.query.pagination ? parseInt(req.query.pagination) : 10
99+
const currentPage = req.query.page ? parseInt(req.query.page) : 1
100+
try {
101+
const { id } = req.user
102+
const projects = await Project.find({ createdBy: id })
103+
.skip((currentPage - 1) * pagination)
104+
.limit(pagination)
105+
.populate('createdBy', '_id name.firstName name.lastName email')
106+
.sort({ updatedAt: -1 })
107+
.exec()
108+
if (projects.length === 0) {
109+
return res.status(HttpStatus.OK).json({ msg: 'No projects created by user yet!' })
110+
}
111+
return res.status(HttpStatus.OK).json({ projects })
112+
} catch (error) {
113+
HANDLER.handleError(res, error)
114+
}
115+
}
116+
}

app/controllers/user.js

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const User = require('../models/User')
22
const jwt = require('jsonwebtoken')
33
const HttpStatus = require('http-status-codes')
44
const emailController = require('./email')
5+
const HANDLER = require('../utils/response-helper')
56

67
module.exports = {
78
createUser: async (req, res, next) => {
@@ -150,5 +151,139 @@ module.exports = {
150151
return res.status(HttpStatus.OK).json({ success: true, msg: 'Redirect user to register in client side!' })
151152
}
152153
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'Invalid token!' })
154+
},
155+
156+
// ADD TO THE FOLLOWINGS LIST
157+
addFollowing: async (req, res, next) => {
158+
const { followId } = req.body
159+
try {
160+
if (followId === req.user._id) {
161+
return res.status(HttpStatus.OK).json({ msg: 'You can not follow yourself!' })
162+
}
163+
const user = await User.findById(req.user.id)
164+
if (!user) {
165+
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'No such user exists!' })
166+
}
167+
user.followings.unshift(followId)
168+
await user.save()
169+
next()
170+
} catch (error) {
171+
HANDLER.handleError(res, error)
172+
}
173+
},
174+
175+
// ADD TO FOLLOWERS LIST
176+
addFollower: async (req, res, next) => {
177+
const { followId } = req.body
178+
try {
179+
const user = await User.findById(followId)
180+
.populate('followings', ['name.firstName', 'name.lastName', 'email'])
181+
.populate('followers', ['name.firstName', 'name.lastName', 'email'])
182+
.exec()
183+
if (!user) {
184+
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'No such user exists!' })
185+
}
186+
// add to the followers list
187+
user.followers.unshift(req.user.id)
188+
await user.save()
189+
return res.status(HttpStatus.OK).json({ user })
190+
} catch (error) {
191+
HANDLER.handleError(res, error)
192+
}
193+
},
194+
195+
// REMOVE FROM FOLLOWINGS LIST
196+
removeFollowing: async (req, res, next) => {
197+
const { followId } = req.body
198+
try {
199+
const user = await User.findById(req.user._id)
200+
if (!user) {
201+
return res.status(HttpStatus.OK).json({ msg: 'No such user exists!' })
202+
}
203+
// check if followId is in following list or not
204+
const followingIdArray = user.followings.map(followingId => followingId._id)
205+
const isFollowingIdIndex = followingIdArray.indexOf(followId)
206+
if (isFollowingIdIndex === -1) {
207+
return res.status(HttpStatus.OK).json({ msg: 'You haven\'t followed the user!' })
208+
} else {
209+
// remove from followings list
210+
user.followings.splice(isFollowingIdIndex, 1)
211+
await user.save()
212+
}
213+
next()
214+
} catch (error) {
215+
HANDLER.handleError(res, error)
216+
}
217+
},
218+
219+
// REMOVE FROM FOLLOWERS LIST
220+
removeFollower: async (req, res, next) => {
221+
const { followId } = req.body
222+
try {
223+
const user = await User.findById(followId)
224+
.populate('followings', ['name.firstName', 'name.lastName', 'email'])
225+
.populate('followers', ['name.firstName', 'name.lastName', 'email'])
226+
.exec()
227+
if (!user) {
228+
return res.status(HttpStatus.NOT_FOUND).json({ msg: 'No such user exists!' })
229+
}
230+
const followersIdArray = user.followers.map((follower) => follower._id)
231+
const isFollowingIndex = followersIdArray.indexOf(req.user._id)
232+
if (isFollowingIndex === -1) {
233+
return res.status(HttpStatus.OK).json({ msg: 'User is not following!' })
234+
}
235+
user.followers.splice(isFollowingIndex, 1)
236+
await user.save()
237+
return res.status(HttpStatus.OK).json({ user })
238+
} catch (error) {
239+
HANDLER.handleError(res, error)
240+
}
241+
},
242+
blockUser: async (req, res, next) => {
243+
const { id } = req.params
244+
try {
245+
const user = await User.findById(req.user._id)
246+
.populate('blocked', ['name.firstName', 'name.lastName', 'email'])
247+
.exec()
248+
if (!user) {
249+
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'Invalid request!' })
250+
}
251+
// check if admin
252+
if (user.isAdmin === true) {
253+
user.blocked.unshift(id)
254+
await user.save()
255+
return res.status(HttpStatus.OK).json({ user })
256+
}
257+
// else not permitted
258+
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'You don\'t have permission!' })
259+
} catch (error) {
260+
HANDLER.handleError(res, error)
261+
}
262+
},
263+
unBlockUser: async (req, res, next) => {
264+
const { id } = req.params
265+
try {
266+
const user = await User.findById(req.user._id)
267+
.populate('blocked', ['name.firstName', 'name.lastName', 'email'])
268+
.exec()
269+
if (!user) {
270+
return res.status(HttpStatus.NOT_FOUND).json({ msg: 'No such user exists!' })
271+
}
272+
// if admin
273+
if (user.isAdmin === true) {
274+
const blockedIds = user.blocked.map(item => item._id)
275+
const unblockIndex = blockedIds.indexOf(id)
276+
console.log('UnblockIndex ', unblockIndex)
277+
if (unblockIndex !== -1) {
278+
user.blocked.splice(unblockIndex, 1)
279+
await user.save()
280+
return res.status(HttpStatus.OK).json({ user })
281+
}
282+
return res.status(HttpStatus.NOT_FOUND).json({ msg: 'No such user exist!' })
283+
}
284+
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'You don\'t have permission!' })
285+
} catch (error) {
286+
HANDLER.handleError(res, error)
287+
}
153288
}
154289
}

app/models/Event.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ const eventSchema = new Schema({
8484
required: true,
8585
default: Date.now()
8686
},
87+
createdBy: {
88+
type: Schema.Types.ObjectId,
89+
ref: 'User'
90+
},
8791
isOnline: {
8892
type: Boolean,
8993
default: false

app/models/Project.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,10 @@ const projectSchema = new Schema({
2222
type: String,
2323
required: true,
2424
trim: true,
25-
minlength: 10,
2625
validate (short) {
2726
if (validator.isEmpty(short)) {
2827
throw new Error('Short description for the project is required!')
2928
}
30-
if (!validator.isLength(short)) {
31-
throw new Error('Short description should be min 10 characters long!')
32-
}
3329
}
3430
},
3531
long: {
@@ -89,6 +85,10 @@ const projectSchema = new Schema({
8985
type: Schema.Types.ObjectId,
9086
ref: 'User'
9187
}],
88+
createdBy: {
89+
type: Schema.Types.ObjectId,
90+
ref: 'User'
91+
},
9292
createdAt: {
9393
type: Date,
9494
default: Date.now()

app/models/User.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,18 @@ const UserSchema = new mongoose.Schema({
136136
}
137137
}
138138
},
139+
followers: [{
140+
type: mongoose.Schema.Types.ObjectId,
141+
ref: 'User'
142+
}],
143+
followings: [{
144+
type: mongoose.Schema.Types.ObjectId,
145+
ref: 'User'
146+
}],
147+
blocked: [{
148+
type: mongoose.Schema.Types.ObjectId,
149+
ref: 'User'
150+
}],
139151
isAdmin: {
140152
type: Boolean,
141153
default: false

0 commit comments

Comments
 (0)