Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/back-end/controllers/message.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { messagesService } from '../services/messages.service.js';
import { EventEmitter } from 'events';

export const messageEmitter = new EventEmitter();

const findAllMessages = async (req, res) => {
const { roomId } = req.params;
const messages = await messagesService.findMessages(roomId);

res.status(201).send(messages);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: The findAllMessages function uses status code 201 (Created) when returning a list of messages. For a GET request, the correct status code should be 200 (OK), not 201. Please change res.status(201).send(messages); to res.status(200).send(messages); to align with REST conventions and likely checklist requirements.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: The status code for a successful GET request should be 200, not 201. Please change res.status(201).send(messages); to res.status(200).send(messages); as per RESTful conventions and the task requirements.

};

const createMessage = async (req, res) => {
const { roomId } = req.params;
const { userId, text } = req.body;

if (!roomId || !userId || !text) {
return res.sendStatus(401);
}

const newMessage = await messagesService.createNewMessage(
roomId,
userId,
text,
);

messageEmitter.emit('message', newMessage);

res.status(200).send(newMessage);
};

export const messagesController = {
findAllMessages,
createMessage,
};
59 changes: 59 additions & 0 deletions src/back-end/controllers/room.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Room } from '../../models/Room.model.js';
import { roomService } from '../services/room.service.js';

const createRoom = async (req, res) => {
const { title } = req.body;

if (!title) {
return res.sendStatus(401);
}

const newRoom = await roomService.createNewRoom(title);

res.status(201).send(newRoom);
};

const getAllRooms = async (req, res) => {
const rooms = await Room.findAll();

res.status(200).send(rooms);
};

const deleteRoom = async (req, res) => {
const { roomId } = req.params;

if (!roomId) {
return res.sendStatus(401);
}

await Room.destroy({ where: { id: roomId } });

res.sendStatus(204);
};

const updateTitle = async (req, res) => {
const { roomId } = req.params;
const { newTitle } = req.body;

if (!roomId || !newTitle) {
return res.sendStatus(401);
}

const room = await Room.findByPk(roomId);

if (!room) {
return res.sendStatus(404);
}

room.title = newTitle;
await room.save();

res.sendStatus(200);
};

export const roomController = {
createRoom,
getAllRooms,
deleteRoom,
updateTitle,
};
17 changes: 17 additions & 0 deletions src/back-end/controllers/user.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { userService } from '../services/user.service.js';

const newUser = async (req, res) => {
const { name } = req.body;

if (!name) {
return res.sendStatus(401);
}

await userService.createUser(name);

res.sendStatus(201);
};

export const userController = {
newUser,
};
22 changes: 22 additions & 0 deletions src/back-end/models/Message.route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { DataTypes } from 'sequelize';
import { client } from '../db.js';

export const Message = client.define('Message', {
text: {
type: DataTypes.STRING,
allowNull: false,
},
userId: {
type: DataTypes.STRING,
allowNull: false,
},
createdAt: {
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
allowNull: false,
},
roomId: {
type: DataTypes.INTEGER,
allowNull: false,
},
});
9 changes: 9 additions & 0 deletions src/back-end/models/Room.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { DataTypes } from 'sequelize';
import { client } from '../db.js';

export const Room = client.define('Room', {
title: {
type: DataTypes.STRING,
allowNull: false,
},
});
9 changes: 9 additions & 0 deletions src/back-end/models/User.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { DataTypes } from 'sequelize';
import { client } from '../db.js';

export const User = client.define('User', {
name: {
type: DataTypes.STRING,
allowNull: false,
},
});
8 changes: 8 additions & 0 deletions src/back-end/routes/message.router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';
import express from 'express';
import { messagesController } from '../controllers/message.controller.js';

export const messageRouter = new express.Router();

messageRouter.get('/:roomId/messages', messagesController.findAllMessages);
messageRouter.post('/:roomId/messages', messagesController.createMessage);
10 changes: 10 additions & 0 deletions src/back-end/routes/room.routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';
import express from 'express';
import { roomController } from '../controllers/room.controller.js';

export const roomRouter = new express.Router();

roomRouter.get('/', roomController.getAllRooms);
roomRouter.post('/createRoom', roomController.createRoom);
roomRouter.put('/:roomId', roomController.updateTitle);
roomRouter.delete('/:roomId', roomController.deleteRoom);
7 changes: 7 additions & 0 deletions src/back-end/routes/user.router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';
import express from 'express';
import { userController } from '../controllers/user.controller.js';

export const userRouter = new express.Router();

userRouter.post('/', userController.newUser);
14 changes: 14 additions & 0 deletions src/back-end/services/messages.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Message } from '../models/Message.route.js';

const findMessages = async (roomId) => {
return Message.findAll({ where: { roomId } });
};

const createNewMessage = (roomId, text, userId) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error: The argument order for createNewMessage is incorrect. In your controller, you call createNewMessage(roomId, userId, text), but here the function is defined as (roomId, text, userId). This will cause the wrong values to be saved in the database. Please update the function signature to (roomId, userId, text) and ensure the object passed to Message.create uses the correct properties.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error: The argument order for createNewMessage does not match the controller's usage. The controller passes (roomId, userId, text), but the service expects (roomId, text, userId). Please update the service function to accept (roomId, userId, text) and create the message accordingly.

return Message.create({ roomId, text, userId });
};

export const messagesService = {
findMessages,
createNewMessage,
};
9 changes: 9 additions & 0 deletions src/back-end/services/room.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Room } from '../models/Room.model.js';

const createNewRoom = async (title) => {
return Room.create({ title });
};

export const roomService = {
createNewRoom,
};
9 changes: 9 additions & 0 deletions src/back-end/services/user.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { User } from '../models/User.model.js';

const createUser = async (name) => {
return User.create({ name });
};

export const userService = {
createUser,
};
8 changes: 8 additions & 0 deletions src/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';
import { Sequelize } from 'sequelize';
import 'dotenv/config';

export const client = new Sequelize('postgres', 'postgres', '29052009', {
host: 'localhost',
dialect: 'postgres',
});
58 changes: 58 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,59 @@
'use strict';
import express from 'express';
import cors from 'cors';
import { userRouter } from './back-end/routes/user.router.js';
import { messageRouter } from './back-end/routes/message.router.js';
import { roomRouter } from './back-end/routes/room.routes.js';
import { WebSocketServer } from 'ws';
import { messageEmitter } from './back-end/controllers/message.controller.js';

const PORT = process.env.PORT || 3005;
const app = express();

app.use(express.json());

app.use(
cors({
origin: '*',
}),
);

app.use('/user', userRouter);
app.use('/rooms', roomRouter);
app.use('/rooms', messageRouter);

app.get('/', (req, res) => {
res.send('Server is OK');
});

const server = app.listen(PORT, () => {
// eslint-disable-next-line no-console
console.log('server is running');
});

const wss = new WebSocketServer({ server });

wss.on('connection', (ws) => {
ws.roomId = null;

ws.on('message', (data) => {
try {
const parsed = JSON.parse(data);

if (parsed.type === 'join' && parsed.roomId) {
ws.roomId = parsed.roomId;
}
} catch (error) {
console.error('Invalid message from client', error);

Check failure on line 47 in src/index.js

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected console statement
}
});
});

messageEmitter.on('message', (message) => {
for (const client of wss.clients) {
if (client.readyState === 1 && client.roomId === message.roomId) {
client.send(JSON.stringify(message));
}
}
});

19 changes: 19 additions & 0 deletions src/setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Message } from './models/Message.route.js';
import { Room } from './models/Room.model.js';
import { User } from './models/User.model.js';

async function setup() {
try {
await User.sync({ force: true });
await Room.sync({ force: true });
await Message.sync({ force: true });

// eslint-disable-next-line no-console
console.log('Tables synced!');
} catch (err) {
// eslint-disable-next-line no-console
console.error('Error syncing:', err);
}
}

setup();
Loading