Skip to content

Commit 32e68b4

Browse files
authored
Merge pull request #1165 from Real-Dev-Squad/feat/event-join-peer-api
2 parents 9d8dc64 + 4a29e71 commit 32e68b4

File tree

5 files changed

+277
-15
lines changed

5 files changed

+277
-15
lines changed

controllers/events.js

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
/* eslint-disable camelcase */
21
const { GET_ALL_EVENTS_LIMIT_MIN, UNWANTED_PROPERTIES_FROM_100MS } = require("../constants/events");
2+
const { INTERNAL_SERVER_ERROR } = require("../constants/errorMessages");
3+
34
const { EventTokenService, EventAPIService } = require("../services");
4-
const { removeUnwantedProperties } = require("../utils/events");
55
const eventQuery = require("../models/events");
6+
67
const logger = require("../utils/logger");
8+
const { removeUnwantedProperties } = require("../utils/events");
79

810
const tokenService = new EventTokenService();
911
const apiService = new EventAPIService(tokenService);
@@ -100,7 +102,7 @@ const joinEvent = async (req, res) => {
100102
});
101103
} catch (error) {
102104
logger.error({ error });
103-
return res.status(500).send("Internal Server Error");
105+
return res.boom.badImplementation(INTERNAL_SERVER_ERROR);
104106
}
105107
};
106108

@@ -193,11 +195,77 @@ const endActiveEvent = async (req, res) => {
193195
}
194196
};
195197

198+
/**
199+
* Adds a peer to an event.
200+
*
201+
* @async
202+
* @function
203+
* @param {Object} req - The Express request object.
204+
* @param {Object} res - The Express response object.
205+
* @returns {Promise<Object>} The JSON response with the added peer data and a success message.
206+
* @throws {Object} The JSON response with an error message if an error occurred while adding the peer.
207+
*/
208+
const addPeerToEvent = async (req, res) => {
209+
try {
210+
const data = await eventQuery.addPeerToEvent({
211+
peerId: req.body.peerId,
212+
name: req.body.name,
213+
role: req.body.role,
214+
joinedAt: req.body.joinedAt,
215+
eventId: req.params.id,
216+
});
217+
return res.status(200).json({
218+
data,
219+
message: `Selected Participant is added to the event.`,
220+
});
221+
} catch (error) {
222+
logger.error({ error });
223+
return res.status(500).json({
224+
error: error.code,
225+
message: "You can't add selected Participant. Please ask Admin or Host for help.",
226+
});
227+
}
228+
};
229+
230+
/**
231+
* Kicks out a peer from an event.
232+
*
233+
* @async
234+
* @function
235+
* @param {Object} req - The Express request object.
236+
* @param {Object} res - The Express response object.
237+
* @returns {Promise<Object>} The JSON response with a success message if the peer is successfully kicked out.
238+
* @throws {Object} The JSON response with an error message if an error occurred while kicking out the peer.
239+
*/
240+
const kickoutPeer = async (req, res) => {
241+
const { id } = req.params;
242+
const payload = {
243+
peer_id: req.body.peerId,
244+
reason: req.body.reason,
245+
};
246+
247+
try {
248+
await apiService.post(`/active-rooms/${id}/remove-peers`, payload);
249+
await eventQuery.kickoutPeer({ eventId: id, peerId: payload.peer_id, reason: req.body.reason });
250+
return res.status(200).json({
251+
message: `Selected Participant is removed from event.`,
252+
});
253+
} catch (error) {
254+
logger.error({ error });
255+
return res.status(500).json({
256+
error: error.code,
257+
message: "You can't remove selected Participant from Remove, Please ask Admin or Host for help.",
258+
});
259+
}
260+
};
261+
196262
module.exports = {
197263
createEvent,
198264
getAllEvents,
199265
joinEvent,
200266
getEventById,
201267
updateEvent,
202268
endActiveEvent,
269+
addPeerToEvent,
270+
kickoutPeer,
203271
};

middlewares/validators/events.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,57 @@ const endActiveEvent = async (req, res, next) => {
100100
}
101101
};
102102

103+
const addPeerToEvent = async (req, res, next) => {
104+
const { id } = req.params;
105+
const { peerId, name, role, joinedAt } = req.body;
106+
107+
const schema = joi.object({
108+
peerId: joi.string().required(),
109+
name: joi.string().required(),
110+
id: joi.string().required(),
111+
role: joi.string().required(),
112+
joinedAt: joi.date().required(),
113+
});
114+
115+
const validationOptions = { abortEarly: false };
116+
117+
try {
118+
await schema.validateAsync({ peerId, name, id, role, joinedAt }, validationOptions);
119+
next();
120+
} catch (error) {
121+
logger.error(`Error while adding a peer to the event: ${error}`);
122+
res.boom.badRequest(error.details[0].message);
123+
}
124+
};
125+
126+
const kickoutPeer = async (req, res, next) => {
127+
const { id } = req.params;
128+
const { peerId, reason } = req.body;
129+
130+
const schema = joi.object({
131+
id: joi.string().required(),
132+
peerId: joi.string().required(),
133+
reason: joi.string().required(),
134+
});
135+
136+
const validationOptions = { abortEarly: false };
137+
138+
try {
139+
await schema.validateAsync({ id, peerId, reason }, validationOptions);
140+
next();
141+
} catch (error) {
142+
logger.error(`We encountered some error while removing selected Participant from event: ${error}`);
143+
res.boom.badRequest(error.details[0].message);
144+
}
145+
};
146+
103147
module.exports = {
104148
createEvent,
105149
getAllEvents,
106150
joinEvent,
107151
getEventById,
108152
updateEvent,
109153
endActiveEvent,
154+
addPeerToEvent,
155+
kickoutPeer,
110156
};

models/events.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
const Firestore = require("@google-cloud/firestore");
12
const firestore = require("../utils/firestore");
23
const logger = require("../utils/logger");
34

45
const eventModel = firestore.collection("events");
6+
const peerModel = firestore.collection("peers");
57

68
/**
79
* Creates a new event document in Firestore and returns the data for the created document.
@@ -66,8 +68,112 @@ const endActiveEvent = async ({ id, reason, lock }) => {
6668
}
6769
};
6870

71+
/**
72+
* Adds a peer to an event in the Firestore database.
73+
* @async
74+
* @function
75+
* @param {Object} peerData - The data of the peer to be added.
76+
* @param {string} peerData.name - The name of the peer.
77+
* @param {string} peerData.eventId - The unique identifier of the event the peer is being added to.
78+
* @param {string} peerData.role - The role of the peer in the event.
79+
* @param {Date} peerData.joinedAt - The timestamp indicating when the peer joined the event.
80+
* @returns {Promise<Object>} The data of the added peer.
81+
* @throws {Error} If an error occurs while adding the peer to the event.
82+
*/
83+
84+
const addPeerToEvent = async (peerData) => {
85+
try {
86+
const batch = firestore.batch();
87+
88+
const peerRef = peerModel.doc(peerData.peerId);
89+
const peerDocSnapshot = await peerRef.get();
90+
91+
if (!peerDocSnapshot.exists) {
92+
// If the peer document doesn't exist, create a new one
93+
const peerDocData = {
94+
peerId: peerData.peerId,
95+
name: peerData.name,
96+
joinedEvents: [
97+
{
98+
event_id: peerData.eventId,
99+
role: peerData.role,
100+
joined_at: peerData.joinedAt,
101+
},
102+
],
103+
};
104+
batch.set(peerRef, peerDocData);
105+
} else {
106+
// If the peer document exists, update the joinedEvents array
107+
batch.update(peerRef, {
108+
joinedEvents: Firestore.FieldValue.arrayUnion({
109+
event_id: peerData.eventId,
110+
role: peerData.role,
111+
joined_at: peerData.joinedAt,
112+
}),
113+
});
114+
}
115+
116+
const eventRef = eventModel.doc(peerData.eventId);
117+
batch.update(eventRef, {
118+
peers: Firestore.FieldValue.arrayUnion(peerRef.id),
119+
});
120+
121+
await batch.commit();
122+
123+
const updatedPeerSnapshot = await peerRef.get();
124+
return updatedPeerSnapshot.data();
125+
} catch (error) {
126+
logger.error("Error in adding peer to the event", error);
127+
throw error;
128+
}
129+
};
130+
131+
/**
132+
* Removes a peer from an event and marks them as kicked out in the Firestore database.
133+
* @async
134+
* @function
135+
* @param {Object} params - The parameters for kicking out the peer.
136+
* @param {string} params.eventId - The unique identifier of the event from which the peer is being kicked out.
137+
* @param {string} params.peerId - The unique identifier of the peer being kicked out.
138+
* @param {string} params.reason - The reason for kicking out the peer from the event.
139+
* @returns {Promise<Object>} The updated data of the kicked-out peer.
140+
* @throws {Error} If the peer is not found or is not part of the specified event.
141+
*/
142+
const kickoutPeer = async ({ eventId, peerId, reason }) => {
143+
try {
144+
const peerRef = peerModel.doc(peerId);
145+
const peerSnapshot = await peerRef.get();
146+
147+
if (!peerSnapshot.exists) {
148+
throw new Error("Participant not found");
149+
}
150+
151+
const peerData = peerSnapshot.data();
152+
const joinedEvents = peerData.joinedEvents;
153+
154+
const eventIndex = joinedEvents.findIndex((event) => event.event_id === eventId);
155+
if (eventIndex === -1) {
156+
throw new Error("Participant is not part of the specified event");
157+
}
158+
159+
const updatedJoinedEvents = joinedEvents.map((event, index) =>
160+
index === eventIndex ? { ...event, left_at: new Date(), reason: reason, isKickedout: true } : event
161+
);
162+
163+
await peerRef.update({ joinedEvents: updatedJoinedEvents });
164+
165+
const updatedPeerSnapshot = await peerRef.get();
166+
return updatedPeerSnapshot.data();
167+
} catch (error) {
168+
logger.error("Error in removing peer from the event.", error);
169+
throw error;
170+
}
171+
};
172+
69173
module.exports = {
70174
createEvent,
71175
updateEvent,
72176
endActiveEvent,
177+
addPeerToEvent,
178+
kickoutPeer,
73179
};

routes/events.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ router.post("/join", eventsValidator.joinEvent, events.joinEvent);
1010
router.get("/:id", eventsValidator.getEventById, events.getEventById);
1111
router.patch("/", authenticate, eventsValidator.updateEvent, events.updateEvent);
1212
router.patch("/end", authenticate, eventsValidator.endActiveEvent, events.endActiveEvent);
13+
router.post("/:id/peers", authenticate, eventsValidator.addPeerToEvent, events.addPeerToEvent);
14+
router.patch("/:id/peers/kickout", authenticate, eventsValidator.kickoutPeer, events.kickoutPeer);
1315

1416
module.exports = router;

0 commit comments

Comments
 (0)