Skip to content

Commit 07e1513

Browse files
authored
Merge pull request #48 from CS3219-AY2425S1/hist
Hist
2 parents fbeb72e + 2ec174b commit 07e1513

23 files changed

+15257
-3165
lines changed

Backend/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
QuestionService/.env
22
user-service/.env
33
MatchingService/.env
4+
HistoryService/.env
45
QuestionService/insert_questions_script.py
56

67
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
@@ -10,6 +11,7 @@ QuestionService/node_modules
1011
user-service/node_modules
1112
MatchingService/node_modules
1213
CollabService/node_modules
14+
HistoryService/node_modules
1315
/.pnp
1416
.pnp.js
1517

Backend/CollabService/utils/roomManager.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ function manageRoom(ws, roomId, userId, type) {
1212
// userIds -> track users in room
1313
// matchedUserIds -> check authorized users
1414
if (!rooms[roomId]) {
15-
rooms[roomId] = { sockets: [], userIds: [], matchedUserIds: []};
15+
rooms[roomId] = { sockets: [], userIds: [], matchedUserIds: [], startTime: new Date().toISOString()};
1616
}
1717

18+
// Broadcast start time to the newly joined user
19+
broadcastRoomStartTime(ws, roomId);
20+
1821
console.log(`BEFORE room Info: userIds[${rooms[roomId].userIds}] || matchedusers[${rooms[roomId].matchedUserIds}]`)
1922

2023
const numOfMatchedUsers = rooms[roomId].matchedUserIds.length
@@ -114,6 +117,16 @@ function manageRoom(ws, roomId, userId, type) {
114117
}
115118
})
116119
}
120+
121+
122+
function broadcastRoomStartTime(ws, roomId) {
123+
const startTime = rooms[roomId].startTime;
124+
125+
ws.send(JSON.stringify({
126+
type: 'roomStartTime',
127+
startTime: startTime
128+
}));
129+
}
117130
}
118131

119132
function getRoom(roomId) {

Backend/CollabService/websocket/roomManagerSocket.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ function setupWebSocket(server) {
1313
switch (data.type) {
1414
case 'joinRoom':
1515
// add user into room with roomId
16-
manageRoom(ws, data.roomId, data.userId, "join");
16+
manageRoom(ws, data.roomId, data.username, "join");
1717
break;
1818
case 'leaveRoom':
1919
// remove user from room with roomId
20-
manageRoom(ws, data.roomId, data.userId, "leave");
20+
manageRoom(ws, data.roomId, data.username, "leave");
2121
break;
2222
case 'requestUserList':
2323
const users = getUsersInRoom(data.roomId);

Backend/HistoryService/Dockerfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM node:20
2+
3+
WORKDIR /app
4+
5+
COPY package*.json ./
6+
RUN npm install
7+
8+
COPY . .
9+
10+
EXPOSE 3005
11+
CMD ["npm", "start"]

Backend/HistoryService/app.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const express = require('express')
2+
const mongoose = require('mongoose')
3+
const cors = require('cors')
4+
const dotenv = require("dotenv")
5+
const historyRouter = require("./controllers/histories")
6+
7+
dotenv.config()
8+
9+
const app = express()
10+
app.use(cors())
11+
app.use(express.json())
12+
13+
const mongoURI = `mongodb+srv://${process.env.DB_USERNAME}:${process.env.DB_PASSWORD}@cs3219.rrxz3.mongodb.net/History-DB?retryWrites=true&w=majority&appName=CS3219`
14+
mongoose.connect(mongoURI)
15+
.then(() => console.log('MongoDB connected'))
16+
.catch(err => console.error('MongoDB connection error:', err));
17+
18+
app.use('/api/histories', historyRouter)
19+
20+
app.get("/", (req, res, next) => {
21+
console.log("Sending Greetings!");
22+
res.json({
23+
message: "Hello World from history-service",
24+
});
25+
});
26+
27+
// Handle When No Route Match Is Found
28+
app.use((req, res, next) => {
29+
const error = new Error("Route Not Found");
30+
error.status = 404;
31+
next(error);
32+
});
33+
34+
app.use((error, req, res, next) => {
35+
res.status(error.status || 500);
36+
res.json({
37+
error: {
38+
message: error.message,
39+
},
40+
});
41+
});
42+
43+
module.exports = app
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const historyRouter = require('express').Router();
2+
const HistoryModel = require('../models/Histories');
3+
4+
// Assuming Express.js
5+
historyRouter.get('/user/:userId', async (req, res) => {
6+
const { userId } = req.params;
7+
try {
8+
const attempts = await HistoryModel.find({ user: userId }); // Fetch by user object ID
9+
res.json(attempts);
10+
} catch (error) {
11+
res.status(500).json({ error: 'Failed to fetch attempt history' });
12+
}
13+
});
14+
15+
16+
// Post a new history entry when a user exits a session
17+
historyRouter.post("/", async (req, res) => {
18+
const { user, matchedUsername, questionTitle, startTime, duration, code } = req.body;
19+
20+
try {
21+
const newHistory = new HistoryModel({
22+
user,
23+
matchedUsername,
24+
questionTitle,
25+
startTime,
26+
duration,
27+
code
28+
});
29+
30+
await newHistory.save();
31+
res.status(201).json(newHistory);
32+
} catch (error) {
33+
res.status(500).json({ error: error.message });
34+
}
35+
});
36+
37+
module.exports = historyRouter;

Backend/HistoryService/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const app = require('./app')
2+
3+
// Change the port number to listen to a different port but remember to change the port number in frontend too!
4+
app.listen(3005, () => {
5+
console.log("Server is Running")
6+
})
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const mongoose = require('mongoose');
2+
3+
const HistorySchema = new mongoose.Schema({
4+
user: {
5+
type: mongoose.Schema.Types.ObjectId,
6+
ref: 'User',
7+
required: true // The user for whom this history entry is being created
8+
},
9+
matchedUsername: {
10+
type: String,
11+
required: true
12+
},
13+
questionTitle: {
14+
type: String,
15+
required: true
16+
},
17+
startTime: {
18+
type: Date, // Time when the session started
19+
default: Date.now
20+
},
21+
duration: {
22+
type: Number, // Duration in minutes for the individual user
23+
required: true
24+
},
25+
code: {
26+
type: Number, // Store the code as binary file
27+
required: true
28+
}
29+
});
30+
31+
// Create the History model
32+
const HistoryModel = mongoose.model('History', HistorySchema, 'History');
33+
module.exports = HistoryModel;

0 commit comments

Comments
 (0)