Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

submission #93

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
280 changes: 184 additions & 96 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,119 +1,207 @@
# Full-Stack Coding Challenge
# **Full-Stack Coding Challenge: Task Management App**

**Deadline**: Sunday, Feb 23th 11:59 pm PST
## **Deadline**: Sunday, Feb 23th 11:59 pm PST

---

## Overview
## **🚀 Overview**

Create a “Task Management” application with **React + TypeScript** (frontend), **Node.js** (or **Nest.js**) (backend), and **PostgreSQL** (database). The application should:
This is a **Task Management** application built with **React + TypeScript** (frontend), **Node.js** (backend), and **PostgreSQL** (database).
It allows users to:

1. **Register** (sign up) and **Log in** (sign in) users.
2. After logging in, allow users to:
- **View a list of tasks**.
- **Create a new task**.
- **Update an existing task** (e.g., mark complete, edit).
- **Delete a task**.
1. **Register** (sign up) and **Log in** (sign in).
2. **Manage Tasks** (CRUD operations):
- View a list of tasks.
- Create a new task.
- Update an existing task (e.g., mark as complete, edit).
- Delete a task.

Focus on **correctness**, **functionality**, and **code clarity** rather than visual design.
This challenge is intended to be completed within ~3 hours, so keep solutions minimal yet functional.
💡 **Focus on correctness, functionality, and code clarity** rather than visual design.

---

## Requirements

### 1. Authentication

- **User Model**:
- `id`: Primary key
- `username`: Unique string
- `password`: Hashed string
- **Endpoints**:
- `POST /auth/register` – Create a new user
- `POST /auth/login` – Login user, return a token (e.g., JWT)
- **Secure the Tasks Routes**: Only authenticated users can perform task operations.
- **Password Hashing**: Use `bcrypt` or another hashing library to store passwords securely.
- **Token Verification**: Verify the token (JWT) on each request to protected routes.

### 2. Backend (Node.js or Nest.js)

- **Tasks CRUD**:
- `GET /tasks` – Retrieve a list of tasks (optionally filtered by user).
- `POST /tasks` – Create a new task.
- `PUT /tasks/:id` – Update a task (e.g., mark as complete, edit text).
- `DELETE /tasks/:id` – Delete a task.
- **Task Model**:
- `id`: Primary key
- `title`: string
- `description`: string (optional)
- `isComplete`: boolean (default `false`)
- _(Optional)_ `userId` to link tasks to the user who created them
- **Database**: PostgreSQL
- Provide instructions/migrations to set up:
- `users` table (with hashed passwords)
- `tasks` table
- **Setup**:
- `npm install` to install dependencies
- `npm run start` (or `npm run dev`) to run the server
- Document any environment variables (e.g., database connection string, JWT secret)

### 3. Frontend (React + TypeScript)

- **Login / Register**:
- Simple forms for **Register** and **Login**.
- Store JWT (e.g., in `localStorage`) upon successful login.
- If not authenticated, the user should not see the tasks page.
- **Tasks Page**:
- Fetch tasks from `GET /tasks` (including auth token in headers).
- Display the list of tasks.
- Form to create a new task (`POST /tasks`).
- Buttons/fields to update a task (`PUT /tasks/:id`).
- Button to delete a task (`DELETE /tasks/:id`).
- **Navigation**:
- Show `Login`/`Register` if not authenticated.
- Show `Logout` if authenticated.
- **Setup**:
- `npm install` then `npm start` (or `npm run dev`) to run.
- Document how to point the frontend at the backend (e.g., `.env` file, base URL).
## **1️⃣ Authentication**

### **User Model**
- `id`: Primary key
- `username`: Unique string
- `password`: Hashed string

### **Endpoints**
| HTTP Method | Endpoint | Description |
|------------|-------------------|-------------|
| `POST` | `/auth/register` | Create a new user |
| `POST` | `/auth/login` | Login user, return a JWT token |

### **Security Features**
- **JWT Authentication** → Secure task routes (only authenticated users can manage tasks).
- **Password Hashing** → Uses `bcrypt` for secure password storage.
- **Token Verification** → Middleware checks JWT for all protected routes.

---

## Deliverables
## **2️⃣ Backend (Node.js + PostgreSQL)**

### **Task Model**
- `id`: Primary key
- `title`: string
- `description`: string (optional)
- `isComplete`: boolean (default `false`)
- `userId`: Foreign key linking the task to its owner

### **Task CRUD API**
| HTTP Method | Endpoint | Description |
|------------|-----------------|-------------|
| `GET` | `/tasks` | Retrieve all tasks (filtered by user) |
| `POST` | `/tasks` | Create a new task |
| `PUT` | `/tasks/:id` | Update a task (mark complete, edit title/desc) |
| `DELETE` | `/tasks/:id` | Delete a task |

### **Database Setup (PostgreSQL)**

#### **Step 1: Install PostgreSQL (If Not Installed)**
```bash
sudo apt update && sudo apt install postgresql postgresql-contrib
```

#### **Step 2: Create the Database**
Start PostgreSQL:
```bash
psql postgres
```
Then, create the database:
```sql
CREATE DATABASE taskmanager;
```

#### **Step 3: Create Tables**
Switch to the database:
```sql
\c taskmanager;
```
Run the following queries:

#### **Users Table**
```sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL
);
```

#### **Tasks Table**
```sql
CREATE TABLE tasks (
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
description TEXT,
isComplete BOOLEAN DEFAULT false,
userId INTEGER REFERENCES users(id) ON DELETE CASCADE
);
```

1. **Fork the Public Repository**: **Fork** this repo into your own GitHub account.
2. **Implement Your Solution** in the forked repository. Make sure you're README file has:
- Steps to set up the database (migrations, environment variables).
- How to run the backend.
- How to run the frontend.
- Any relevant notes on testing.
- Salary Expectations per month (Mandatory)
3. **Short Video Demo**: Provide a link (in a `.md` file in your forked repo) to a brief screen recording showing:
- Registering a user
- Logging in
- Creating, updating, and deleting tasks
4. **Deadline**: Submissions are due **Sunday, Feb 23th 11:59 pm PST**.
---

> **Note**: Please keep your solution minimal. The entire project is intended to be completed in around 3 hours. Focus on core features (registration, login, tasks CRUD) rather than polished UI or extra features.
## **3️⃣ Environment Variables (`.env`)**
Create a `.env` file inside the **backend/** folder:
```ini
DATABASE_URL=postgresql://your_username:your_password@localhost:5432/taskmanager
JWT_SECRET=your_secret_key
PORT=5001
```
💡 **Replace `your_username` and `your_password` with your actual PostgreSQL credentials.**

---

## Evaluation Criteria
## **4️⃣ How to Run the Backend**
#### **Step 1: Navigate to Backend Folder**
```bash
cd backend
```

#### **Step 2: Install Dependencies**
```bash
npm install
```

#### **Step 3: Start the Backend Server**
```bash
npm run dev
```
👉 **Server should start on:** `http://localhost:5001/`

---

1. **Functionality**
- Does registration and login work correctly (with password hashing)?
- Are tasks protected by authentication?
- Does the tasks CRUD flow work end-to-end?
## **5️⃣ How to Run the Frontend**
#### **Step 1: Navigate to Frontend Folder**
```bash
cd frontend
```

#### **Step 2: Install Dependencies**
```bash
npm install
```

#### **Step 3: Start the Frontend**
```bash
npm run dev
```
👉 **Frontend should open at:** `http://localhost:5173/`

---

## **6️⃣ Testing API (cURL Commands)**
Manually test API endpoints using **cURL**.

#### **User Registration**
```bash
curl -X POST http://localhost:5001/auth/register \
-H "Content-Type: application/json" \
-d '{"username": "testuser1", "password": "password123"}'
```

#### **User Login (Get JWT Token)**
```bash
curl -X POST http://localhost:5001/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "testuser1", "password": "password123"}'
```
👉 **Copy the token from the response.**

#### **Create a Task**
```bash
curl -X POST http://localhost:5001/tasks \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN_HERE" \
-d '{"title": "Finish Project", "description": "Work on the final project report"}'
```

#### **Get All Tasks**
```bash
curl -X GET http://localhost:5001/tasks \
-H "Authorization: Bearer YOUR_JWT_TOKEN_HERE"
```

#### **Update a Task**
```bash
curl -X PUT http://localhost:5001/tasks/1 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN_HERE" \
-d '{"title": "Updated Task", "description": "Updated task description", "isComplete": true}'
```

#### **Delete a Task**
```bash
curl -X DELETE http://localhost:5001/tasks/1 \
-H "Authorization: Bearer YOUR_JWT_TOKEN_HERE"
```

---

2. **Code Quality**
- Is the code structured logically and typed in TypeScript?
- Are variable/function names descriptive?
## **7️⃣ Salary Expectations**
💰 **Expected Salary:** **$7,500 per month**

3. **Clarity**
- Is the `README.md` (in your fork) clear and detailed about setup steps?
- Easy to run and test?

4. **Maintainability**
- Organized logic (controllers/services, etc.)
- Minimal hard-coded values

Good luck, and we look forward to your submission!
8 changes: 8 additions & 0 deletions backend/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
PORT=5001
DB_USER=vivekkrishnagiri
DB_PASSWORD=Zoro022504
DB_NAME=taskmanager
DB_HOST=localhost
DB_PORT=5432
JWT_SECRET=shortkey

20 changes: 20 additions & 0 deletions backend/middleware/authMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const jwt = require("jsonwebtoken");

const authMiddleware = (req, res, next) => {
const token = req.header("Authorization");

if (!token) {
return res.status(401).json({ message: "Access denied. No token provided." });
}

try {
const decoded = jwt.verify(token.replace("Bearer ", ""), process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
res.status(400).json({ message: "Invalid token" });
}
};

module.exports = authMiddleware;

49 changes: 49 additions & 0 deletions backend/models/taskModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const { Pool } = require("pg");

// Database Connection
const pool = new Pool({
user: process.env.DB_USER,
host: process.env.DB_HOST,
database: process.env.DB_NAME,
password: process.env.DB_PASSWORD,
port: process.env.DB_PORT,
});

// Create a Task
const createTask = async (title, description, userId) => {
const result = await pool.query(
"INSERT INTO tasks (title, description, userId) VALUES ($1, $2, $3) RETURNING *",
[title, description, userId]
);
return result.rows[0];
};

// Get All Tasks for a User
const getTasksByUser = async (userId) => {
const result = await pool.query(
"SELECT * FROM tasks WHERE userId = $1",
[userId]
);
return result.rows;
};

// Update Task
const updateTask = async (taskId, title, description, isComplete, userId) => {
const result = await pool.query(
"UPDATE tasks SET title = $1, description = $2, isComplete = $3 WHERE id = $4 AND userId = $5 RETURNING *",
[title, description, isComplete, taskId, userId]
);
return result.rows[0];
};

// Delete Task
const deleteTask = async (taskId, userId) => {
const result = await pool.query(
"DELETE FROM tasks WHERE id = $1 AND userId = $2 RETURNING *",
[taskId, userId]
);
return result.rows[0];
};

module.exports = { createTask, getTasksByUser, updateTask, deleteTask };

Loading