A production-ready Task Manager REST API built using TypeScript, Express, PostgreSQL, Prisma, and Redis.
Designed for scalability, security, and clean architecture with:
- Secure Auth (JWT + Redis blacklist)
- Role-based access
- Full Task management (CRUD + Assign + Complete)
- Comment system
- User management (Admin-only)
- Cloudinary file upload
- Type-safe Prisma ORM
- Centralized validation with Joi
- Enterprise security stack
- ⚙ Tech Stack
- 🔋 Features
- 📦 Quick Start
- 🌍 Environment Variables
- 🧱 API Modules Overview
- 🧪 Testing
- 🛠️ Migration Commands
- 🚀 Deployment on Render
- 📜 Scripts
- 🔒 Security
- 📄 License
| Technology | Purpose |
|---|---|
| Node.js | JavaScript Runtime |
| TypeScript | Type Safety |
| Express.js | HTTP Server Framework |
| PostgreSQL | Primary Database |
| Prisma ORM | Type-safe DB operations |
| Redis | Caching + Token invalidation |
| JWT | Authentication mechanism |
| argon2 | Password hashing |
| Joi | Validation library |
| Cloudinary | Media uploads |
| Multer | File handling |
| Helmet / CORS / Rate Limit | Security |
| Jest + Supertest | Testing |
- JWT authentication
- Redis token invalidation (logout)
- Argon2 password hashing
- Role-based access control (Admin/User)
- Admin-only user operations
- Update roles
- Upload profile picture
- Delete users
- CRUD operations
- Assign tasks to users
- Mark as completed
- Owner/Role-based filtering
- Add task comments
- Fetch comments
- Delete comments
Copy env.example to .env and update the values for your environment:
cp env.example .env
Key settings:
DATABASE_URL— Prisma/PostgreSQL connection string for local dev or production (set this on Railway/Render to the managed DB URL).COMPOSE_DATABASE_URL— override used only bydocker-compose.yml(defaults to the internalpostgresservice so containers can talk to each other).REDIS_HOST/REDIS_PORT— Redis connection (setrediswhen using Compose).JWT_SECRET,CLOUDINARY_*— secrets for auth and file uploads.PORT— API port (defaults to 3000).
git clone https://github.com/shasbinas/task-manager-api-ts.git
cd task-manager-api-tsnpm installnpm run prisma:migrate
npx prisma generatenpm run devThis repo includes a production-ready Dockerfile and docker-compose.yml that bootstraps the API, PostgreSQL, and Redis together.
- Copy
env.example→.envand set your secrets (compose defaults already point the API to the in-cluster Postgres/Redis). - Build and start everything:
docker compose up --buildCompose will:
- create persistent
postgres/redisvolumes, - run Prisma migrations before the API boots,
- expose the API at
http://localhost:3000, - expose PostgreSQL (
localhost:5432) and Redis (localhost:6379) for local tools.
To stop and remove containers + volumes:
docker compose down -vDeployments can reuse the provided Dockerfile; platforms like Railway/Render only need the same env vars that work locally.
Railway/Render tip: make sure
DATABASE_URLis set to the managed Postgres connection string (neverlocalhost) and thatREDIS_HOST/REDIS_PORTpoint to the managed cache if you’re not using the in-cluster Redis.If you’re on Railway and forget to set
DATABASE_URL, the entrypoint will try to construct one from Railway’s defaultPG*environment variables (withsslmode=require). Still, it’s best to addDATABASE_URLexplicitly so Prisma Studio, migrations, and local tooling all share the same value.
| Method | Endpoint | Description |
|---|---|---|
POST |
/register |
Register a new user |
POST |
/login |
Login and receive JWT token |
POST |
/logout |
Logout and invalidate session |
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Get all users |
GET |
/:id |
Get user by ID |
PUT |
/:id/role |
Update user role |
DELETE |
/:id |
Delete user |
| Method | Endpoint | Description |
|---|---|---|
POST |
/ |
Create a new task |
GET |
/ |
Get all tasks (filtered by user) |
GET |
/:id |
Get task by ID |
PUT |
/:id |
Update task |
DELETE |
/:id |
Delete task |
PUT |
/:id/complete |
Mark task as complete |
PUT |
/:id/assign |
Assign task to user |
| Method | Endpoint | Description |
|---|---|---|
POST |
/tasks/:taskId/comments |
Add comment to task |
GET |
/tasks/:taskId/comments |
Get all comments for task |
DELETE |
/comments/:id |
Delete comment |
Run all tests:
npm testWatch mode:
npm run test:watchnpx prisma migrate dev
npx prisma generate
npx prisma studio- Add environment variables
- Use build command:
npm run build && npx prisma migrate deploy- Start command:
npm start"dev": "tsx watch src/server.ts",
"build": "tsc -p tsconfig.build.json",
"start": "node dist/server.js",
"lint": "eslint src --ext .ts",
"lint:fix": "eslint src --ext .ts --fix",
"format": "prettier --write src",
"prisma:migrate": "prisma migrate dev",
"test": "cross-env NODE_ENV=test jest",
"test:watch": "cross-env NODE_ENV=test jest --watch"- Helmet
- CORS
- Rate Limiter
- Redis token blacklist
- Joi request validation
- Argon2 password hashing
MIT License — Free to use and mo