This project is a backend service for a real-time polling application, built as part of the Move37 Ventures Backend Developer Challenge. It features a RESTful API for managing users, polls, and votes, along with a WebSocket layer for broadcasting live poll results to all connected clients.
- Backend: Node.js, Express.js, TypeScript
- Database: PostgreSQL
- ORM: Prisma
- Real-time Communication: WebSockets (
wslibrary)
- RESTful API: Full CRUD functionality for Users, Polls, and Votes.
- Database Schema: A well-defined relational schema with one-to-many and many-to-many relationships.
- Live Updates: A WebSocket server pushes real-time vote count updates to clients subscribed to a specific poll.
- Scalable Structure: Organized into controllers, routes, and services for maintainability.
Before you begin, ensure you have the following installed on your local machine:
- Node.js (v18.x or later recommended)
- npm (comes with Node.js)
- PostgreSQL
- Postman (for testing the API and WebSockets)
Follow these steps to get your development environment set up.
1. Clone the repository:
git clone https://github.com/Rohan11203/real-time-polling
cd real-time-polling2. Install dependencies:
npm install3. Set up environment variables: Create a .env file in the root of the project by copying the example file:
cp .env.example .envNow, open the .env file and update the DATABASE_URL with your PostgreSQL connection string.
PORT=PORT
DATABASE_URL=YOUR_DATABASE_URL4. Run database migrations: This command will create the database (if it doesn't exist) and apply the schema defined in prisma/schema.prisma.
npx prisma migrate devIt will also run prisma generate to create the typed Prisma Client for your project.
To start the development server, run the following command:
npm run devThis guide will walk you through the entire application flow.
Create a new POST request in Postman.
- URL:
http://localhost:3000/api/users/create - Body:
raw>JSON - Content:
{ "name": "John Doe", "email": "john.doe@example.com", "password": "password123" } - Hit Send. You will get a response with the newly created user, including their id. Copy this id for the next step.
Create a new POST request.
-
URL:
http://localhost:3000/api/polls/create -
Body:
raw>JSON -
Content: (Paste the user
idyou copied intocreatorId){ "question": "Best Frontend ?", "creatorId": "cmfikd2xj0000kfzseoer8qxq", "options": ["NExt", "React", "Vue"] } -
**Hit Send. The response will contain the poll and its options. Copy the poll id and one of the pollOption ids for later steps. **
Now, let's listen for live updates for the poll you just created.
- In Postman, click the New button and select WebSocket Request.
- Enter the server URL:
ws://localhost:3000/ - Click Connect. You should see a "Connected" status message.
- In the message composer at the bottom, enter the following JSON message to subscribe to your poll's updates. (Paste the poll
idyou copied).{ "type": "SUBSCRIBE", "pollId": "paste-poll-id-here" } - Click Send. You will receive a confirmation message like
{"type":"SUBSCRIBED","pollId":"..."}.
Keep this WebSocket connection open.
Go back to your HTTP requests and create a new POST request.
- URL:
http://localhost:3000/api/polls/paste-poll-id-here/vote(Paste the poll id into the URL)) - Body:
raw>JSON - Content: (Paste the user
idand thepollOptionidyou copied).{ "pollOptionId": "paste-poll-option-id-here", "userId": "paste-user-id-here" } - Hit Send. You'll get a confirmation that the vote was cast.
Immediately after you cast the vote, switch back to your WebSocket Request tab in Postman. You will see a new message has arrived automatically in the "Messages" panel, showing the updated vote counts for your poll!
{
"type": "POLL_UPDATE",
"pollId": "...",
"results": [
{ "id": "...", "text": "JavaScript", "voteCount": 1 },
{ "id": "...", "text": "Python", "voteCount": 0 },
{ "id": "...", "text": "Rust", "voteCount": 0 }
]
}- You have successfully tested the entire real-time update flow!
| Method | Path | Description |
|---|---|---|
POST |
/api/users/create |
Creates a new user. |
POST |
/api/polls/create |
Creates a new poll with its options. |
POST |
/api/polls/:pollId/vote |
Submits a vote for a poll option. |
GET |
/api/polls/:pollId |
Retrieves a poll with vote counts. |