A comprehensive backend API for WorkNest - a collaborative project management application with real-time features.
- π Authentication System - Secure user registration and login with JWT tokens
- π Project Management - Create, update, and manage collaborative projects
- β Task Management - Create, assign, track, and manage tasks within projects
- π¬ Real-time Messaging - Instant chat functionality within project rooms
- π File Management - Upload and share files using Cloudinary integration
- π€ User Management - User profiles, updates, and search functionality
- π Real-time Updates - Socket.io integration for live notifications
- π‘οΈ Security - JWT authentication, rate limiting, helmet security headers
- β Input Validation - Zod schema validation for all inputs
- π Logging - Winston logger for error and activity tracking
- β‘ API Rate Limiting - Protection against brute-force attacks
- βοΈ Cloud Storage - Cloudinary integration for file uploads
- π³ Docker Support - PostgreSQL database in containerized environment
| Category | Technology |
|---|---|
| Runtime | Node.js |
| Language | TypeScript |
| Framework | Express.js |
| Database | PostgreSQL |
| ORM | Prisma |
| Real-time | Socket.io |
| Authentication | JWT (jsonwebtoken) |
| Validation | Zod |
| File Storage | Cloudinary |
| Logging | Winston |
| Rate Limiting | express-rate-limit |
| Security | Helmet, CORS, Compression |
| Development | nodemon, tsx, ts-node |
WorkNest-Backend/
βββ prisma/
β βββ schema.prisma # Database schema
β βββ migrations/ # Database migrations
βββ src/
β βββ app.ts # Express app configuration
β βββ index.ts # Application entry point
β βββ routes.ts # API routes aggregation
β βββ config/
β β βββ cloudinary.ts # Cloudinary configuration
β β βββ db.ts # Prisma database client
β β βββ env.ts # Environment variables validation
β β βββ socket.ts # Socket.io setup
β βββ constants/
β β βββ statusCodes.ts # HTTP status codes
β βββ middlewares/
β β βββ auth.middleware.ts # JWT authentication
β β βββ error.middleware.ts# Global error handling
β β βββ rateLimit.middleware.ts # API rate limiting
β β βββ validation.middleware.ts # Zod schema validation
β βββ modules/
β β βββ auth/ # Authentication module
β β β βββ auth.controller.ts
β β β βββ auth.routes.ts
β β β βββ auth.schema.ts
β β β βββ auth.service.ts
β β βββ file/ # File management module
β β βββ messages/ # Messaging module
β β βββ projects/ # Project management module
β β βββ tasks/ # Task management module
β β βββ user/ # User management module
β βββ startup/
β β βββ prod.ts # Production middleware setup
β βββ utils/
β βββ AppError.ts # Custom error class
β βββ catchAsync.ts # Async error wrapper
β βββ permissions.ts # Authorization utilities
β βββ responseObject.ts # API response formatter
βββ docker-compose.yml # Docker configuration
βββ nodemon.json # Nodemon configuration
βββ package.json # Dependencies and scripts
βββ tsconfig.json # TypeScript configuration
| Method | Endpoint | Description |
|---|---|---|
| POST | /auth/register |
Register a new user |
| POST | /auth/login |
Login and get JWT token |
| Method | Endpoint | Description |
|---|---|---|
| GET | /user/me |
Get current user profile |
| PATCH | /user/me |
Update user details |
| GET | /user/search?q=email |
Search users by email |
| Method | Endpoint | Description |
|---|---|---|
| POST | /project |
Create a new project |
| GET | /project |
Get all user's projects |
| GET | /project/:id/members |
Get project members |
| POST | /project/add-member |
Add member to project |
| POST | /project/remove-member |
Remove member from project |
| PATCH | /project/:id |
Update project details |
| DELETE | /project/:id |
Delete project |
| Method | Endpoint | Description |
|---|---|---|
| POST | /tasks |
Create a new task |
| GET | /tasks/:id |
Get tasks for a project |
| PATCH | /tasks/:taskId |
Update task status |
| PATCH | /tasks/:taskId/assign |
Assign task to user |
| DELETE | /tasks/:taskId |
Delete task |
| Method | Endpoint | Description |
|---|---|---|
| POST | /message |
Send a message |
| GET | /message/:projectId |
Get chat history |
| Method | Endpoint | Description |
|---|---|---|
| POST | /file/upload |
Upload a file |
| GET | /file/:projectId |
Get project files |
| DELETE | /file/:fileId |
Delete a file |
Socket.io connections require JWT authentication. Pass the JWT token in the handshake query or headers:
const socket = io("http://localhost:5050", {
query: { token: "your-jwt-token" },
});Or in headers:
const socket = io("http://localhost:5050", {
extraHeaders: { token: "your-jwt-token" },
});| Event | Payload | Description |
|---|---|---|
join_project |
projectId |
Join a project room |
| Event | Payload | Description |
|---|---|---|
invited_to_project |
{ projectId } |
User added to project |
new_message |
Message |
New message sent |
task_created |
Task |
New task created |
task_updated |
Task |
Task status updated |
task_assigned |
Task |
Task assigned to user |
new_file |
File |
New file uploaded |
User
id- UUID primary keyname- Optional display nameemail- Unique email addresspassword- Hashed password- Relations: projects, projectMembers, tasks, messages, files
Project
id- UUID primary keyname- Project nameownerId- Owner user IDdescription- Optional description- Relations: owner, members, tasks, messages, files
ProjectMember
id- UUID primary keyuserId- User IDprojectId- Project IDrole- "owner" or "member"- Unique:
[userId, projectId]
Task
id- UUID primary keytitle- Task titledescription- Optional descriptionstatus- "todo", "in_progress", or "done"projectId- Project IDassignedToId- Optional assignee ID
Message
id- UUID primary keycontent- Message textprojectId- Project IDsenderId- Sender user ID
File
id- UUID primary keyname- File nameurl- Cloudinary URLsize- File size in bytesprojectId- Project IDuploaderId- Uploader user ID
- Node.js (v18+)
- PostgreSQL (or use Docker)
- Cloudinary account
-
Clone the repository
cd WorkNest-Backend -
Install dependencies
npm install
-
Set up environment variables
cp .env.example .env # If you have an example fileOr create
.envwith the following:NODE_ENV=development PORT=5050 DATABASE_URL=postgresql://postgres@localhost:5433/worknest JWT_SECRET=your-super-secret-key-at-least-32-characters JWT_EXPIRES_IN=7d CLOUDINARY_CLOUD_NAME=your-cloud-name CLOUDINARY_API_KEY=your-api-key CLOUDINARY_API_SECRET=your-api-secret
-
Set up the database
# Using Docker (recommended) npm run dock:start # Or use your local PostgreSQL
-
Run database migrations
npm run db:setup
-
Start the development server
# Development mode (with hot reload) npm run dev # Or build and run production server npm run build npm start
The server will be running at
http://localhost:5050
| Script | Description |
|---|---|
npm run dev |
Start development server with tsx |
npm run build |
Build for production |
npm run start |
Start production server |
npm run db:migrate |
Run Prisma migrations |
npm run db:push |
Push schema to database |
npm run db:generate |
Generate Prisma client |
npm run db:setup |
Run migrations and generate client |
npm run db:view |
Open Prisma Studio |
npm run dock:start |
Start Docker containers |
npm run dock:stop |
Stop Docker containers |
- JWT Authentication - Secure token-based auth
- Password Hashing - bcrypt with salt rounds
- Rate Limiting - 100 requests/15min for API, 5 attempts/hour for auth
- Helmet - Security headers (CSP, HSTS, etc.)
- CORS - Cross-origin resource sharing control
- Input Validation - Zod schemas for all inputs
- Error Handling - Global error middleware with logging
All API responses follow this structure:
{
message: string; // Human-readable message
status: number; // HTTP status code
success: boolean; // Indicates success/failure
data: object; // Response data
}Example success response:
{
"message": "Project created successfully",
"status": 201,
"success": true,
"data": {
"id": "uuid",
"name": "My Project",
"ownerId": "uuid"
}
}Example error response:
{
"message": "Validation Error",
"status": 400,
"success": false,
"data": [
{
"path": "email",
"message": "Invalid email format"
}
]
}The application uses a centralized error handling middleware that:
- Catches all errors globally
- Logs errors with Winston (error.log for 5xx, combined.log for all)
- Returns appropriate HTTP status codes
- Includes stack traces only in development mode
// Custom operational error
throw new AppError("User not found", 404);Start PostgreSQL with Docker:
# Start the container
npm run dock:start
# Stop the container
npm run dock:stopDocker configuration in docker-compose.yml:
- PostgreSQL 17 Alpine
- Port 5433 mapped to host
- Persistent volume for data
ISC License
Developed with β€οΈ by Simon Adama for collaborative project management