opencodeiiita / grepit-backend Goto Github PK
View Code? Open in Web Editor NEWQuiz-hosting application to create quizzes, extensively utilising websockets.
Home Page: https://grep-it-api.onrender.com/
License: MIT License
Quiz-hosting application to create quizzes, extensively utilising websockets.
Home Page: https://grep-it-api.onrender.com/
License: MIT License
Small fixes;
/api/v1/room/user/disconnect
/api/v1/room/user/delete
route to /api/v1/room/user/remove
for better semantics (explains the action of one person, here the room creator, removing someone and not deleting them).As the last question's timer runs out, the leaderboard shines forth, showcasing the champions of the quizventure.
The leaderboard should send the data in a descending (higher to lower) order of points of the Users in that room. The data sent should include:
After the last question in that room, send an additional event called quiz over
, with the leaderboard as the data. The clients will then listen to this event, and display the leaderboard accordingly.
At the Registration Station, users create their quiz identities by choosing a username and providing an email and a password.
In this task, you are required to write necessary controllers (in src/controllers/userAuth.controllers.js) receiving the necessary Form Input (username, email, and password). Encrypt the password using bcrypt, using 10 salt rounds. The controller should be run on the /api/v1/auth/register route, which should be modified in the src/routes/v1/userAuth.routes.js
Having made secure the identity of the user, add them to the realm of the users, by adding them to the User model, displaying a success message and giving the user an entry to the Realm of Quizventure!
NOTE: The DATABASE_URL for the database hosted on PlanetScale is available in the #grepit-backend channel on discord. Use this value and add it in your .env file. Please do not commit the URL, or your PR will not be merged (for security reasons)
The creator is tired of maintaining his fellowmates and serving as the sole knowledge-able person in that room. He wishes to transfer the ownership to another person in that room. Also when the user leaves, randomly assign another user in that room as the creator, making necessary changes elsewhere in the models (like setting the isCreator for that user to false, and isCreator for that random user to true).
Handle both these cases: one, when the owner manually chooses who to give the ownership (/api/v1/room/transferOwner
), and another when the owner leaves the room (controller already exists, /api/v1/room/disconnect
). The second controller should be modified to randomly assign another User as the creator.
With active renovation going on in the Quizventure realms, the Mayor has decided to rebuild all the homes of the knowledge-seekers that reside in the realms. That, is a lot of effort!
But what are the changes?
Well, in v2, since we're not going to be deleting rooms, and giving the User the option to view their past results, we had to craft some new Schemas (called Quiz
, and Result
) (see #47 and #50 for more details).
However, in v1, we had a temporary nature of rooms, and so we didn't really store a Quiz as such (but now, we're going to store the result of each User for each Quiz)
Hence, the following changes are required:
questions[]
field and using Quiz instead in the room
model, etc.)Since we're gonna have to change the main schema of our codebase (Room
), this would require changes in certain controllers and socket-event handlers as well. These changes should be done in accordance with the new schema changes.
Since this is quite a big task, it is kept open-for-all. All the PRs that help in some contribution towards these codebase changes will earn points (depends on how big of a contribution you make to the changes.)
**NOTE: Before starting work after updating the schema, please get the schema confirmed once with me. A good schema will be allowed to be pushed, and other's will have to pull that (npx prisma db pull
) and continue work on that **
Minimum points for each good PR: 5
Maximum points: 50
With most of the logic part done for the sockets, the Mayor of the Quizventure has demanded thy workers to enlist the socket events used throughout the project, and explain briefly the use of each socket event.
It is also required to enlist the events that we've assumed would be emitted by the client, apart from the events that would be emitted by the server.
The client-side socket events can be obtained from the html
files in the sockets-test/
folder. The server-side socket events can be obtained by reading the backend code. It is important to provide a brief as to what each event is for, and how it's handled.
The documentation should be done in a SOCKET_EVENTS.md
file.
With the Result
record being successfully created for each user in that room when a new quiz starts, it's time to actually make use of it.
Once the last question of that quiz is displayed, we have to update the record of that User using suitable information. These changes should be made in the startQuiz
controller, and should update the points of all the Users connected to that room in their respective Result
record created.
The points
can be obtained from the User
model's points
attribute, as every answer to a question is handled by sockets to update the points in real-time.
You are required to attach screenshots of this, showing that the points are actually getting updated in the DB when the quiz ends (by emulating the quiz through the template HTML files.) If you are not able to emulate the quiz due to changes required in any other controllers, please let me know.
Make the PR to the v2
branch.
๐ข The quiz will be starting shortly
๐ข Congrats, @johndoe for finishing on top of the leaderboard!
We require such a way for the creator to announce to all other users about certain events. Craft a controller to allow the creator to make announcements, which should be handled using sockets and emitted to all the other connected sockets of that room. Assume that the sockets are joined in a socket-room named by the code
of that room.
Unleash the controller on the /api/v1/room/announce
endpoint! Update the API_ENDPOINTS.md
file accordingly!
An incredible number of users are joining my room!!!
Where's the privacy???
Let's solve this by giving an option to the room-creator to make the room invite-only.
Just like an open room, an invite-only room will also have a code associated to it. Others can use this code to join this room. But here's the difference. In an open room, the attempting user will directly be added to the room. But in an invite-only room, the creator must accept/reject the pending users in the waiting list.
This would require the addition of
pending
field (default should be an empty array of Users)isInviteOnly
field (bool, default false)Now, the addUserToRoom
controller should be modified. When the room is NOT inviteOnly, the normal behaviour is expected: anyone can join the room.
But if the room is inviteOnly, any user attempting to join the room will first be placed in the pending list.
Another controller should be created (under /api/v1/room/user/pending
, which accepts a query param of either accept
or reject
, and another query param which is the userId
of the user to accept/reject). Based on the query param, the pending user will either be moved to the Users
list of that room, or removed from the Pending list. Note that this action can only be done by the room's creator.
Do not include sockets for now, as it would be upgraded once the main sockets implementation for Room Creation/Joining is implemented in #20.
It is necessary to upgrade the schema for this task, so get the schema confirmed once before running npx prisma db push
. It is also required to update the API_ENDPOINTS.md
file as part of this task
HO HO HO! The user has now stepped into this mystical realm which feels surreal. A bunch of similar people wandering about in this realm, each requiring their own privacy.
This is where we'll be allowing the users to create a Room.
Well, but how do you know who created the room? Middlewares! Create an appropriate userAuth.middleware.js
, that will verify and extract a JWT sent from the frontend in a header "authorization". Use the extracted JWT to get the userId, and set the req.user object to contain the name, userId. This would allow you to identify the logged in user and secure routes that require authentication
Also, this would mean that the user that creates the room may (intuitively) gain extra privileges in that room, which may be discussed later. Hence, an isCreator field is required to know whether a user is a creator of that room or not. Consider updating the Prisma schema by adding a isCreator field in the User model, set to False by default. Do not create a migration. Get the schema verified, and if done well, can be pushed directly by running npx prisma db push
A Create Room button on the frontend, when clicked, will generate a random string that will serve as a code for that room. The frontend will pass this code as a query parameter, to the /api/v1/room/create
route in the src/routes/v1/room.routes.js
file, allowing the underlying services running the realm to capture this request and consequently create a room in the database, ensuring all relations are satisfied and the necessary fields are correctly filled (the User can be obtained from req.user)
Currently, there is a "test" user in the DB, with a "test" password. Create a new room by the user "test", and upload a screenshot of the received JSON Response. Update the routes wherever required, and ensure that the room/create
route is protected and lets only authenticated users create rooms.
Please make sure that errors are handled everywhere promptly.
Users step through the grand Gateway, entering the heart of the quiz realm as they successfully log in.
Task: Implement user-login functionality, by adding suitable controllers in src/controllers/userAuth.controllers.js. Pave a route (not so literally) for allowing the user to get through the Gateway (/api/v1/auth/login), mesmerizing them as they enter this beautiful and otherworldly (quite literally) realm of Quizzes.
The user will provide their username and password, which should match appropriately with their record in the database. Proper error-handling must be ensured.
Ensure that you verify the encrypted password stored in the database, and if successfully verified, should return a 200 status code with a "Successfully logged in" message. Craft a similar failure message.
With the successful completion of the first two weeks and the amazing progress we've had, it's time to scale things up: allowing the storing of Room Results. We may not be able to integrate this part into GrepIt-Frontend within the duration of OpenCode '23, but we can still have a working backend!
As knowledge-seekers gain more knowledge and progress their way through the Realms of Quizventure, they see that their success rates have grown exponentially. Being the boastful seekers they are, they wish to share their results with others.
This would mean that we have to store the User's results for each quiz, in a room. Ofcourse, this would require ALOT of changes in the schema as well.
We would have a results
array for each User, which would store the past results of the quizzes.
How would each result look like?
Each result
would contain atleast the following:
1. User
2. questions[] (would contain the Questions for a specific Quiz in that Room)
3. options[] (would contain the Options marked by the User)
4. score (for these set of questions, basically score for a particular quiz in a room)
5. Room
The logic behind this schema is: We're storing the Options marked by the User, so that we can display in the frontend the set of correctly answered Questions and incorrectly answered Questions (since each Option has a isCorrect boolean field). We also have to store the Questions, to display those questions which aren't answered by the User.
We would also be required to remove the onDelete: Cascade
attributes for Option
and Question
models.
The workflow would be as follows: when a new quiz is started by the creator, a new result record is created for all the Users in that room, and this record be updated in the results
array for that User. The result record would contain the Questions for that quiz.
Since this requires quite a lot of changes in the schema and the controllers in V2, if you've got any other optimised database design, feel free to recommend them.
Note: Make the PR to the v2 branch of this repo. Good Luck!
In order to establish a robust foundation for the quiz-hosting application, the initial step is to define the Prisma schemas for the core database models. These models, namely User, Room, Question, and Option, form the backbone of the application's data architecture.
The goal of this issue is to create precise and comprehensive Prisma schemas that accurately represent the structure of the User, Room, Question, and Option entities within the database given the attributes of each model. Prisma schemas act as a bridge between the application code and the database, facilitating seamless communication and interaction.
Each attribute in each model may have some description of what it's purpose is. Some fields may not have a DataType defined, because it may be obvious or intuitive.
These models should be created in the prisma/schema.prisma file. Once the schemas seem right, you will be told to migrate the schema. Once the migration is successful, you will receive 30 points
This is a First-Come-First-Serve issue. For more details, read the Participant's Rulebook uploaded on Discord.
Happy contributing!
Hola! We're back with another small issue, sorry for the delay :(. The mentors were busy with an event organised by the Mayor of the Quizventure!
To make all the controllers uniform across the project, and make the URLs more elegant, we require migrating from the usage of roomId
to roomCode
in those controllers which are getting the roomId
as a query param instead of the roomCode.
If it wasn't obvious, you are also to make necessary changes to the controllers and make sure they work as before. This shouldn't be a problem, as the roomCode, like the roomId, is unique.
Empowered by the quest for user autonomy, wizards unveil the Room Personalization Ritual. With the need of an updated schema and a magical controller, room creators can now add names and optional descriptions to their realms (rooms). They have the ability to shape the identity of their quiz room, making it uniquely theirs.
Identify the necessary changes that need to be made in the schema. Get the changes verified by either @VatsalBhuva11 or @bhupesh98 , before npx prisma db push
.
Some unknown entity joined your personalized room? Gotta remove them! The creator should have the option to remove a User from the room. The controller for it may have the userId
obtained as a query parameter
to the api/v1/room/user/delete
route. Update the routes wherever necessary, ensuring they make logical sense as to which file they're placed in (make it modular). The controller can be writen in the src/controllers/room.controllers.js
file.
For testing, create a new room (from a 'test2' account), give it a name of test2
, description of test2
, create and add multiple users to this room using npx prisma studio
, and using the test2
account, delete some users from the room. Attach suitable screenshots.
Ensure that authentication middleware is used wherever required.
JWT
when the user is signed in and send that token also as part of the response (so that you can use it for further requests) (in userAuth.controllers.js
), with the payload data including:
- id : userId of the logged in User
- isCreator: false by default, since when a User is logged in, there's no room created by that User
- name: name of the User
Update the userAuth.middleware.js
file to ensure that the req.user
object contains the fields mentioned above (i.e., make changes to the req.user = data.user
line based on the changes in the above point).
Also, create a .env
variable called JWT_SECRET
, and assign it a random valid string. Use this variable instead of the 'grepit-backend' secret used. Add the variable in .env.example
file as well.
Update the room.controller.js
file to ensure that when a User creates a room successfully, the req.user
object for that user reflects the change by setting the isCreator
field to true
.
If I may have missed out on some other related changes, please feel free to get them cleared. Since there may be changes required in other parts of the file as well, this issue is marked as competitive. Multiple PRs may be submitted, and the one that accounts for all the changes will be accepted.
Users embark on a journey through the grand Gateway, venturing into the heart of the quiz realm as they successfully log in.
Task:
Implement a controller to add multiple-choice questions (single correct) to the quiz realm. Create this controller in src/controllers/question.controllers.js. Establish a route to guide users in submitting their captivating questions (/api/v1/questions/add).
Details:
Controller:
Create a controller function, let's call it addMultipleChoiceQuestion, responsible for adding multiple-choice questions to the database.
Route:
Configure a route in src/routes/questions.routes.js to handle the user's request for adding questions. The route should be accessible through a POST request to /api/v1/questions/add.
Request Body:
Design the expected request body for adding a question. It should include the following fields:
question: The text of the question.
options: An array of option objects, each containing:
option: The text of the option.
isCorrect: A boolean indicating whether this option is correct.
Validation:
Validate the incoming request body to ensure it adheres to the expected structure. Provide meaningful error messages for any validation failures.
Database Interaction:
Interact with the database models (Question, Option) to store the new question and its options. Ensure proper association between questions and options. Make sure that number of options can be dynamic.
Response:
Respond with appropriate status codes and messages. This message will be displayed to the user as an alert so send appropriate message.
Claim this Issue and I would be happy if you give our repo a star.
We will be going to implement cool things like web-sockets so, stay tuned till then.
Ping me on discord if there's any confusion or require some resources
Users will enter the immersive world of our upgraded system, traversing the technological landscape as they seamlessly transition from the traditional HTTP server to the dynamic realm of WebSockets. The primary objective is to introduce a room creation feature, complete with a unique code or URL for user interaction. Additionally, users entering the system without the 'schedule' query parameter should receive a personalized message informing them of its absence.
Task:
Upgrade the current HTTP server to leverage WebSockets for enhanced real-time communication. Implement a controller to facilitate room creation, generating a unique code or URL for user access. Provide a tailored message for users entering without the 'schedule' query parameter.
Details:
Controller:
Modify a controller function, perhaps named createRoom, responsible for orchestrating the creation of rooms using WebSockets. Ensure seamless integration within the existing codebase.
Unique Code/invite URL:
Generate a unique code or invite URL for each created room, ensuring its exclusivity. This identifier will serve as the entry point for users to join the room.
User Entry Without 'schedule' Query Param:
Implement logic to handle user entry without the 'schedule' query parameter. Craft a user-friendly message explaining the necessity of the 'schedule' parameter and guide users on its inclusion.
Response:
Craft appropriate responses for successful room creation, invalid parameters, and missing 'schedule' query parameter. Ensure clear communication with users through meaningful status codes and messages.
Database Interaction:
Modify the database interactions to accommodate room-related data. Ensure proper storage and retrieval of room information.
Claim this Issue and don't forget to give our repository a star! Exciting enhancements, including the integration of WebSockets, are on the horizon. Stay tuned for future updates. If you encounter any confusion or need additional resources, feel free to ping me on Discord.
PS: This task requires time and learning websockets extensively, so it is recommended to read the whole thing and discuss with @bhupesh98 or @VatsalBhuva11 regarding any confusion here before claiming the task. A PR for this task is not expected very soon.
In V2, we'd allow the knowledge-seekers to learn from their mistakes.
This task requires you to modify the appropriate controllers handling room deletion, such that the rooms do not get deleted when the room becomes empty. Instead, add a new field to the Room
Schema, called isClosed (default: false)
. When the room gets empty, set the isClosed to true.
The use of this field is that, users cannot join rooms having isClosed
set to true, requiring a modification in the controller handling the joinRoom
functionality.
The deleteRoom
controller should also be modified such that the room does not get deleted from the DB; instead it just disconnects every connected User from that room (including the creator), and set the isClosed option to true.
Make necessary changes in the disconnectUserFromRoom
, removeUserFromRoom
and any other controllers to stay in sync with this logic, making comments wherever necessary.
Note: make a PR to the v2
branch of this repo.
Welp! The Frontend seeks the help of the Almighty Backend! ๐คฒ
This requires us to craft necessary controllers and routes that fetches common data from the database and sends them as a response to the frontend.
This is a competitive task, which requires you to craft as many LOGICAL and NECESSARY controllers that may be required by the Frontend. You are also required to comment the use-case beside each controller, appropriately add the routes in the respective routes files, and update the API_ENDPOINTS.md
file.
An example controller would be to fetch all the users in a room and sending over that data.
This task requires you to analyse all the controllers written so far, and see where and how would the frontend be able to send the data required by the backend, and craft controllers for the same. After-all, the frontend will display data obtained from the frontend, and send back that very same data! So the key is to analyse the controllers.
The judging criteria would be on the basis of the highest number of valid, logical, and useful controllers written in a PR. You will only be allowed to make ONE COMMIT in the PR.
If two PRs are found equally point-worthy, the PR which is made earlier will win the higher number of points. Although only the 15 point PR will be merged, the rest will still be awarded points as part of their effort!
The best 5 PRs will be awarded points, in the order: 15, 10, 5, 5, 5
With everything set up for the quizventure, it's time to put the knowledge of our users to a test!
Craft a controller (on /api/v1/room/start
), such that when the creator clicks on the start
button on the frontend, the quiz starts, with each question being displayed to each connected User one-by-one. The order of the questions displayed should be random, but the same question to be displayed for each user (as this is easier to implement). If possible (not necessary though), implement a way to display random questions to every user. This may be hard to code efficiently, so you may be awarded an additional 3 points if you're able to convince us with an efficient method for this (again, note that randomizing questions for each user is not necessary. It's an optional task.)
Once the timer for a question runs out, the client will emit a socket event answer question
, with the optionId
and questionId
of the question chosen, the userId
, and the roomCode
as the data sent for that event. This event should be handled appropriately on the backend, and if the answer chosen by the socket is correct, add 10 points
for that user in the room.
Based on whether the answer chosen was correct or wrong, the server should emit an appropriate event answer response
, containing the required data (correct/wrong, userId, roomCode) for displaying a correct or wrong on the frontend depending on the answer.
After 1 second of the question timer running out, the next question should be displayed for the User by the server emitting a socket event display question
, sending appropriate data for the event. And the cycle continues.
If anything is required to be changed as part of the task, feel free to discuss it out with either @VatsalBhuva11 or @bhupesh98 , and we shall help you out. Good luck.
Note: It is required to attach a video as part of the PR, of the testing of these sockets. You may use the admin.html
and user.html
files as reference for this.
With the new schema set for the v2 branch (get the DB URL for v2 from #announcements in GrepIt-Backend channel in discord) and active renovation going on in the Quizventure realms, we are faced with some critical issues which will be handled individually. The main changes in the schema involve a new Quiz
Schema and Result
Schema. With the creation of each new quiz in a room, we will create a new record for that Quiz and add it to the corresponding Room's record, so that the Users can view their results later.
This task requires you to pull the latest changes from the v2
branch of GrepIt-Backend, and make changes to:
create a new room.routes.js
file in routes/v2
, add the /startQuiz
route to this, and update the v2-main.js
file accordingly.
attach screenshots in your PR which shows the working of the updated controller. You are to show that a new Quiz record is created when a quiz is started, and a new Result record was created for each user who participated in a Quiz. accordingly update the API_ENDPOINTS.md
file (do not remove the response of the v1's startQuiz
. add the response of the new controller, and mention that it is of v2.
The quiz is over and the leaderboard displayed.
While some are satisfied with their skills, some are upset of not getting the podium positions.
They discuss in a chat-room
, available only when the quiz ends.
Set-up a feature where the connected sockets are able to chat through a chat-room just for that particular room. The messages of all the users in the room must be stored in the room
model, which requires the construction of another field (in the Room model) and model for messages
.
Ensure relevant naming of the socket events. When a client emits the send message
event, the message should be captured on the server, and stored in the relevant room's messages field. Assume that the necessary data is available in the event's data. The messages array (each message should contain sender's name
, sender's Id
, and message
) should then be emitted back to all the users of that room, for displaying on all the clients pages. Name the event appropriately.
Since this task requires schema.prisma
to be changed, please get the messages
schema verified once before running npx prisma db push
.
Some fields in the messages schema would be: sender (User), room (Room), message (String). Add/remove any field if necessary, but do discuss it out with us once.
NOTE: we would require a video demo for this task demonstrating the chat-room. Without the video, your PR will not get merged. Make use of the admin.html
and user.html
files for this, modifying them as required.
Alas! The knowledge pool has exhausted in the Realm, and the creator decides to vanish the room, banishing all the existing members!
Forge a controller, on the /api/v1/room/delete
route, to delete a room and ensuring that the related questions and options are also deleted (or have we already handled that in the schema?)
It is also required to handle the sockets appropriately. Deleting a room requires disconnecting all the sockets associated with that room. Assume that the sockets exist in a socket-room having the name as the code
of that room. Update the related models as required whenever a room is deleted, ensuring data integrity.
The other connected users in that room would automatically get disconnected from the room by this action, so would we require a socket event
to be emitted for handling this, to make necessary changes in the client-side for each socket? Let us know your approach either in discord, or pinging us here (@VatsalBhuva11 and @bhupesh98 ).
Develop the pathway for adventurers to join the realm using room codes.
Note
This controller function is broken down in parts as it requires socket.io library, more issues will be posted as soon as it is complete.
src/controllers/room.controllers.js
.
We'll be implementing websockets using socket.io library where actual room will be created for seamless interaction.
Stay tuned, the task will be posted soon.
Claim this Issue to work on this!
I will be super happy ๐ if you give our repo a โญ.
In case of further clarification ping @GrepIt-Backend on our discord channel.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.