A straightforward task management app built with Node, Express, MongoDB, and Angular. Drag and drop your tasks around a kanban board, organize your work, and get stuff done.
- Kanban Board: Move tasks through workflow stages (To Do, Ready, In Progress, Ready for Review, Done, Not Done)
- Backlog View: Keep To Do, Ready, Not Done tasks separate
- Drag & Drop: Actually works like you'd expect
- Login/Signup: JWT auth, passwords are hashed
- Caching: Redis speeds things up
- Toast notifications: Let you know when something happened
- Modal dialogs: For creating, editing and deleting tasks
Backend: Node, Express, MongoDB, Redis, Bcrypt, JWT
Frontend: Angular (standalone components), RxJS, Angular CDK for drag-drop
DevOps: Docker
- Node.js 20+
- Docker (for MongoDB and Redis — or bring your own via local installs / MongoDB Atlas / Redis Cloud)
The backend connects to MongoDB and Redis on startup, so both must be running before npm run dev — otherwise you'll see repeated Redis error / MongoDB connection error messages. The easiest way is Docker (no database installs needed):
docker-compose up -d mongo redisOn first run Docker automatically downloads the MongoDB and Redis images, then starts them in the background on localhost:27017 and localhost:6379. Stop them later with docker-compose stop mongo redis.
-
Start the databases (see above, or use your own MongoDB/Redis)
-
Backend
cd backend npm install cp .env.example .env # Update .env with your MongoDB and Redis URLs, e.g.: # MONGO_URI=mongodb://localhost:27017/tasktracker # REDIS_URL=redis://localhost:6379 npm run dev
-
Frontend
cd frontend npm install ng serve -
Open
http://localhost:4200and create an account
- Docker
- Docker Compose
-
Build and run everything
docker-compose up --build
-
Wait for all services to start (takes about 30 seconds)
- MongoDB starts
- Redis starts
- Backend starts on http://localhost:5000
- Frontend starts on http://localhost:8080
-
Open
http://localhost:8080and create an account
docker-compose downdocker-compose logs -f backend
docker-compose logs -f frontendContainerization solves the "works on my machine" problem:
- Consistency: Backend, MongoDB, and Redis run in isolated containers. Same setup everywhere (your laptop, your friend's laptop, production server).
- No conflicts: Docker isolates Node, Python, databases from your system. You don't pollute your machine with random versions.
- Easy onboarding: New developer just runs
docker-compose up. No "install MongoDB here, Redis there, Node version X, etc." - Production-ready: Same Dockerfile that works locally also works on AWS, Heroku, DigitalOcean, etc. No "but it worked locally" surprises.
- Clean cleanup:
docker-compose downremoves everything. No leftover processes, ports, or data (unless you want to keep volumes).
Click "New Task", fill in the details, hit create. You'll get a notification when it's done.
Drag a card from one column to another. It updates the status immediately and syncs to the database.
Click edit to change a task or delete to remove it. You'll get a confirmation dialog for deletes.
Toggle between Kanban (full workflow) and Backlog (unstarted tasks).
| Method | Endpoint | What it does |
|---|---|---|
| POST | /api/auth/register |
Create account |
| POST | /api/auth/login |
Login |
| GET | /api/tasks |
Get all your tasks |
| POST | /api/tasks |
Create a task |
| PUT | /api/tasks/:id |
Update a task |
| DELETE | /api/tasks/:id |
Delete a task |
Users have a name, email, hashed password, and role.
Tasks have a title, description, status, priority, and belong to a user.
- Passwords get hashed with bcrypt
- JWT tokens expire after 7 days
- You can only see your own tasks
- All API requests are validated
Redis caching keeps things fast. Most task loads come from cache, not the database.
# Register
POST http://localhost:5000/api/auth/register
{
"name": "Your Name",
"email": "you@example.com",
"password": "password123"
}
# Login
POST http://localhost:5000/api/auth/login
{
"email": "you@example.com",
"password": "password123"
}
# Copy the token from the response
# Create a task
POST http://localhost:5000/api/tasks
Header: Authorization: Bearer YOUR_TOKEN
{
"title": "Fix something",
"description": "Details here",
"status": "to do",
"priority": "high"
}Backend:
backend/
├── src/
│ ├── config/
│ ├── controllers/
│ ├── middleware/
│ ├── models/
│ ├── routes/
│ └── utils/
├── Dockerfile
├── index.js
└── package.json
Frontend:
frontend/
├── src/app/
│ ├── components/
│ │ ├── delete-modal/
│ │ ├── task-modal/
│ │ └── toast/
│ ├── guards/
│ ├── interceptors/
│ ├── pages/
│ │ ├── login/
│ │ ├── register/
│ │ └── task-list/
│ ├── services/
│ ├── app.ts
│ ├── app.config.ts
│ ├── app.routes.ts
│ └── app.html
├── Dockerfile
├── nginx.conf
└── package.json
backend/Dockerfile: Builds a production Node image, installs dependencies, runs the app.
frontend/Dockerfile: Multi-stage build. First builds Angular, then serves it with Nginx (lightweight).
frontend/nginx.conf: Configures Nginx to serve the Angular SPA properly. Routes all requests to index.html so Angular's router can handle navigation.
docker-compose.yml: Orchestrates MongoDB, Redis, backend, and frontend. They communicate on an internal network. Data persists in volumes.