Skip to content

Commit cf102eb

Browse files
Merge pull request #124 from sumitd94/develop
Add logic to fetch & create tasks
2 parents 2859e7a + 9f9ce31 commit cf102eb

File tree

7 files changed

+561
-0
lines changed

7 files changed

+561
-0
lines changed

controllers/tasksController.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
const tasks = require('../models/tasks')
2+
/**
3+
* Creates new task
4+
*
5+
* @param req {Object} - Express request object
6+
* @param req.body {Object} - Task object
7+
* @param res {Object} - Express response object
8+
*/
9+
const addNewTask = async (req, res) => {
10+
try {
11+
const task = await tasks.updateTask(req.body)
12+
return res.json({
13+
message: 'Task created successfully!',
14+
task: task.taskDetails,
15+
id: task.taskId
16+
})
17+
} catch (err) {
18+
logger.error(`Error while creating new task: ${err}`)
19+
return res.boom.badImplementation('An internal server error occurred')
20+
}
21+
}
22+
/**
23+
* Fetches all the tasks
24+
*
25+
* @param req {Object} - Express request object
26+
* @param res {Object} - Express response object
27+
*/
28+
const fetchTasks = async (req, res) => {
29+
try {
30+
const allTasks = await tasks.fetchTasks()
31+
return res.json({
32+
message: 'Tasks returned successfully!',
33+
tasks: allTasks.length > 0 ? allTasks : []
34+
})
35+
} catch (err) {
36+
logger.error(`Error while fetching tasks ${err}`)
37+
return res.boom.badImplementation('An internal server error occurred')
38+
}
39+
}
40+
41+
/**
42+
* Updates the task
43+
*
44+
* @param req {Object} - Express request object
45+
* @param res {Object} - Express response object
46+
*/
47+
const updateTask = async (req, res) => {
48+
try {
49+
const task = await tasks.fetchTask(req.params.id)
50+
if (!task.taskData) {
51+
return res.boom.notFound('Task not found')
52+
}
53+
54+
await tasks.updateTask(req.body, req.params.id)
55+
return res.status(204).send()
56+
} catch (err) {
57+
logger.error(`Error while updating user: ${err}`)
58+
return res.boom.badImplementation('An internal server error occurred')
59+
}
60+
}
61+
62+
module.exports = {
63+
addNewTask,
64+
fetchTasks,
65+
updateTask
66+
}

middlewares/validators/tasks.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
const joi = require('joi')
2+
3+
const createTask = async (req, res, next) => {
4+
const schema = joi.object().keys({
5+
title: joi.string().required(),
6+
purpose: joi.string().required(),
7+
featureUrl: joi.string().optional(),
8+
type: joi.string().required(),
9+
links: joi.array().items(joi.string()),
10+
endsOn: joi.string(),
11+
startedOn: joi.string().required(),
12+
status: joi.string().required(),
13+
ownerId: joi.string().required(),
14+
percentCompleted: joi.number().optional(),
15+
dependsOn: joi.array().items(joi.string()),
16+
participants: joi.array().items(joi.string()),
17+
completionAward: joi.object().keys({
18+
gold: joi.number(),
19+
silver: joi.number(),
20+
bronze: joi.number()
21+
}).optional(),
22+
lossRate: joi.object().keys({
23+
gold: joi.number(),
24+
silver: joi.number(),
25+
bronze: joi.number()
26+
}).optional(),
27+
isNoteworthy: joi.bool().optional()
28+
})
29+
30+
try {
31+
await schema.validateAsync(req.body)
32+
next()
33+
} catch (error) {
34+
logger.error(`Error validating createTask payload : ${error}`)
35+
res.boom.badRequest(error.details[0].message)
36+
}
37+
}
38+
39+
const updateTask = async (req, res, next) => {
40+
const schema = joi.object().keys({
41+
title: joi.string().optional(),
42+
purpose: joi.string().optional(),
43+
featureUrl: joi.string().optional(),
44+
type: joi.string().optional(),
45+
links: joi.array().items(joi.string()),
46+
endsOn: joi.string().optional(),
47+
startedOn: joi.string().optional(),
48+
status: joi.string().optional(),
49+
ownerId: joi.string().optional(),
50+
percentCompleted: joi.number().optional(),
51+
dependsOn: joi.array().items(joi.string()),
52+
participants: joi.array().items(joi.string()),
53+
completionAward: joi.object().keys({
54+
gold: joi.number(),
55+
silver: joi.number(),
56+
bronze: joi.number()
57+
}).optional(),
58+
lossRate: joi.object().keys({
59+
gold: joi.number(),
60+
silver: joi.number(),
61+
bronze: joi.number()
62+
}).optional(),
63+
isNoteworthy: joi.bool().optional()
64+
})
65+
66+
try {
67+
await schema.validateAsync(req.body)
68+
next()
69+
} catch (error) {
70+
logger.error(`Error validating updateTask payload : ${error}`)
71+
res.boom.badRequest(error.details[0].message)
72+
}
73+
}
74+
75+
module.exports = {
76+
createTask,
77+
updateTask
78+
}

models/tasks.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
const firestore = require('../utils/firestore')
2+
const tasksModel = firestore.collection('tasks')
3+
4+
/**
5+
* Adds and Updates tasks
6+
*
7+
* @param taskData { Object }: task data object to be stored in DB
8+
* @param taskId { string }: taskid which will be used to update the task in DB
9+
* @return {Promise<{taskId: string}>}
10+
*/
11+
const updateTask = async (taskData, taskId = null) => {
12+
try {
13+
if (taskId) {
14+
const task = await tasksModel.doc(taskId).get()
15+
await tasksModel.doc(taskId).set({
16+
...task.data(),
17+
...taskData
18+
})
19+
return { taskId }
20+
}
21+
const taskInfo = await tasksModel.add(taskData)
22+
const newlyCreatedTaskData = await fetchTask(taskInfo.id)
23+
return { taskId: taskInfo.id, taskDetails: newlyCreatedTaskData.taskData }
24+
} catch (err) {
25+
logger.error('Error in creating task', err)
26+
throw err
27+
}
28+
}
29+
30+
/**
31+
* Fetch all tasks
32+
*
33+
* @return {Promise<tasks|Array>}
34+
*/
35+
const fetchTasks = async () => {
36+
try {
37+
const tasksSnapshot = await tasksModel.get()
38+
const tasks = []
39+
tasksSnapshot.forEach((task) => {
40+
tasks.push({
41+
id: task.id,
42+
...task.data()
43+
})
44+
})
45+
return tasks
46+
} catch (err) {
47+
logger.error('error getting tasks', err)
48+
throw err
49+
}
50+
}
51+
52+
/**
53+
* Fetch a task
54+
* @param taskId { string }: taskid which will be used to fetch the task
55+
* @return {Promise<taskData|Object>}
56+
*/
57+
const fetchTask = async (taskId) => {
58+
try {
59+
const task = await tasksModel.doc(taskId).get()
60+
return { taskData: task.data() }
61+
} catch (err) {
62+
logger.error('Error retrieving task data', err)
63+
throw err
64+
}
65+
}
66+
67+
module.exports = {
68+
updateTask,
69+
fetchTasks,
70+
fetchTask
71+
}

routes/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ app.use('/healthcheck', require('./healthCheck.js'))
55
app.use('/auth', require('./auth.js'))
66
app.use('/users', require('./users.js'))
77
app.use('/members', require('./members.js'))
8+
app.use('/tasks', require('./tasks'))
89
app.use('/challenges', require('./challenges.js'))
910
app.use('/pullrequests', require('./pullrequests.js'))
1011

routes/tasks.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
const express = require('express')
2+
const router = express.Router()
3+
const tasksController = require('../controllers/tasksController')
4+
const { createTask, updateTask } = require('../middlewares/validators/tasks')
5+
6+
/**
7+
* @swagger
8+
* /tasks:
9+
* get:
10+
* summary: Used to get all the tasks
11+
* responses:
12+
* 200:
13+
* description: returns tasks
14+
* content:
15+
* application/json:
16+
* schema:
17+
* $ref: '#/components/schemas/tasks'
18+
* 500:
19+
* description: badImplementation
20+
* content:
21+
* application/json:
22+
* schema:
23+
* $ref: '#/components/schemas/errors/badImplementation'
24+
*/
25+
26+
router.get('/', tasksController.fetchTasks)
27+
28+
/**
29+
* @swagger
30+
* /tasks:
31+
* post:
32+
* summary: Used to create new task
33+
* requestBody:
34+
* description: Task data
35+
* content:
36+
* application/json:
37+
* schema:
38+
* $ref: '#/components/schemas/tasks'
39+
* responses:
40+
* 200:
41+
* description: returns newly created task
42+
* content:
43+
* application/json:
44+
* schema:
45+
* $ref: '#/components/schemas/tasks'
46+
* 500:
47+
* description: badImplementation
48+
* content:
49+
* application/json:
50+
* schema:
51+
* $ref: '#/components/schemas/errors/badImplementation'
52+
*/
53+
router.post('/', createTask, tasksController.addNewTask)
54+
55+
/**
56+
* @swagger
57+
* /tasks:
58+
* patch:
59+
* summary: Used to update task details
60+
* requestBody:
61+
* description: Task data to be updated
62+
* content:
63+
* application/json:
64+
* schema:
65+
* $ref: '#/components/schemas/tasks'
66+
* responses:
67+
* 204:
68+
* description: no content
69+
* 404:
70+
* description: notFound
71+
* content:
72+
* application/json:
73+
* schema:
74+
* $ref: '#/components/schemas/errors/notFound'
75+
* 500:
76+
* description: badImplementation
77+
* content:
78+
* application/json:
79+
* schema:
80+
* $ref: '#/components/schemas/errors/badImplementation'
81+
*/
82+
router.patch('/:id', updateTask, tasksController.updateTask)
83+
84+
module.exports = router

0 commit comments

Comments
 (0)