Case study
Task Management App
A full-stack MERN task manager with a drag-and-drop board, team workspaces with roles and invites, recurring tasks, email reminders, and a calendar and statistics view.
The demo opens signed in with sample tasks and runs entirely in your browser, so it's always fast. The real app uses the Express API and MongoDB described below.
Role: Solo: frontend, backend, testing, and deployment
The problem
- I wanted one place for personal to-dos and small team projects, with the details a real team needs: who owns a task, what changed, and what's due.
- I also wanted to build and ship a complete MERN app end to end: API design, auth, file uploads, background jobs, tests, and separate frontend and backend deployments.
Quick tour (silent, sample data)
Screens (demo, sample data)
What it does
Drag-and-drop board
To Do, In Progress, and Done columns built with dnd-kit. Search, filter, and sort by priority, due date, or creation date.
Team workspaces
Create a workspace, invite people with a link, and give them owner, admin, or member roles. Tasks can be assigned to a member, and personal tasks stay separate.
Rich tasks
Labels, categories, priorities, subtasks, comments, and file attachments. Every change is written to a per-task history, so you can see who changed what.
Recurring tasks
Daily, weekly, or monthly tasks with an interval and an end date. A background job checks every hour and creates the next occurrence.
Email reminders
An hourly job finds tasks that are due soon or overdue and sends a formatted reminder email with Nodemailer.
Calendar, stats, export
A month calendar of due dates, a statistics view with Recharts (status and priority breakdowns, completion rate, overdue count), export and import, and dark mode.
Architecture
A request
React + TypeScript (Vercel)
Axios client adds the JWT to every request
Express REST API (Render)
Auth middleware verifies the token and loads the user
Routes for auth, tasks, and workspaces
Queries are scoped to the signed-in user or a workspace they belong to
MongoDB Atlas via Mongoose
User, Task, and Workspace models; attachments stored with Multer
Background jobs (every hour)
Recurring task scheduler
Creates the next copy of daily, weekly, and monthly tasks
Due-date notifier
Emails reminders for tasks due soon or overdue
Security decisions
Hashed passwords
Passwords are hashed with bcrypt before they're stored, and the password field is excluded from queries by default, so it never reaches API responses.
Token auth
Task and workspace routes require a signed JWT in the Authorization header; auth middleware verifies it and loads the user on every request.
Scoped data
Personal tasks are only returned to their owner, and workspace tasks only to that workspace's members. Owner and admin roles gate member management.
Demo without a server
The portfolio demo swaps the HTTP layer for an in-browser mock of the same API, so visitors never touch a real database and nothing they do is saved.
How it was built
- 133 automated tests with Jest and Supertest: unit tests for the auth middleware and user model, and integration tests for the auth, task, and workspace routes.
- Docker Compose runs the frontend, backend, and MongoDB together for local development.
- Frontend and backend deploy separately (Vercel and Render), with MongoDB Atlas as the database.
- A demo mode, switched on with one environment variable, answers every API call in the browser with sample data.