← Back to Projects

Task Management Platform

ReactTypeScriptNode.jsExpressPostgreSQLJWT

Overview

Task Management is a full-stack web application that lets authenticated users create, view, update, and delete personal tasks, with completion tracking and protected routing so each user only ever sees their own data.

Description

Task Management is a single-user-per-account to-do application backed by a REST API and a relational database. Users register and log in with a username and password; the server issues a JWT that the client stores in localStorage and attaches to every subsequent request. All task endpoints are protected by an authentication middleware that validates the token before any database query runs. The frontend is a React SPA with TypeScript; the backend is Express with a PostgreSQL database accessed via node-postgres.

What it is and what it does

On the backend, two routers handle all traffic. The auth router exposes POST /auth/register and POST /auth/login: registration hashes the password with bcrypt (10 salt rounds) and inserts a new user row, then signs and returns a JWT; login fetches the matching user, compares the submitted password against the stored hash, and returns a token on success. The tasks router sits behind the authenticate middleware, which extracts the Bearer token, verifies it with jsonwebtoken, and attaches the decoded payload (userId, username) to req.user so that every query is automatically scoped to the requesting user. The four task endpoints cover full CRUD: GET /tasks returns all rows for the current user; POST /tasks inserts a new task; PUT /tasks/:id uses COALESCE so only supplied fields are overwritten; DELETE /tasks/:id removes a task and returns 404 if it does not belong to the user.

On the frontend, an AuthContext wraps the entire app and exposes login, register, logout, and the current token. PrivateRoute checks for a token and redirects to /login if none is present. HomePage fetches the task list on mount and passes handlers down to three child components: TaskForm (create), TaskList (display, toggle, delete, open edit modal), and TaskUpdate (inline edit modal). Toggling a checkbox calls PUT /tasks/:id with only is_complete and updates local state immediately.

Capabilities

  • Per-user data isolation enforced at the query level; queries always filter by user_id
  • JWT authentication with 1-hour expiry; bcrypt password hashing with configurable salt rounds
  • Full CRUD on tasks: create, read, update (partial via COALESCE), delete, and toggle completion
  • Completion toggled directly from the list without opening the edit modal
  • Edit modal pre-populates all existing fields and allows partial or full updates
  • Protected SPA routing that redirects unauthenticated users to login

Implementation

Auth: bcrypt hashes passwords at registration; jsonwebtoken signs tokens scoped to userId and username. The Express authenticate middleware is applied at the router level so all task routes are covered by a single declaration.

Database: Two tables — users (id, username, password, created_at) and tasks (id, title, description, is_complete, user_id, created_at, updated_at) — managed via knex migrations. All queries use parameterised statements through node-postgres.

Frontend: React Router v6 handles three routes (/login, /register, /). AuthContext provides auth state and actions to the whole tree. HomePage owns task state and derives all handler functions passed as props to the display components.

Tech & Tools

React · TypeScript · Node.js · Express · PostgreSQL · JWT · bcrypt · Axios · Knex

Highlights

  • Per-user data isolation enforced at the query level
  • JWT-based stateless authentication with bcrypt password hashing
  • Full CRUD on tasks: create, read, update (partial), delete, and toggle completion
  • Protected SPA routing that redirects unauthenticated users to login

More Projects