A production-grade task management system built with Node.js, TypeScript, PostgreSQL (Neon DB), and Redis.
- Project Overview
- Tech Stack
- Project Structure
- Setup & Installation
- Database Schema
- Development Progress
- Scripts
- Environment Variables
- Testing
- API Documentation
- Contributing
TaskFlow is an enterprise-grade task management platform designed for teams and organizations. It supports:
- ✅ Multi-tenant workspaces - Team collaboration with role-based access
- ✅ Project & task management - Hierarchical organization with task dependencies
- ✅ Real-time updates - WebSocket-based live collaboration (Coming Soon)
- ✅ File attachments - S3-based document storage (Coming Soon)
- ✅ Activity feeds - Comprehensive audit logs and notifications
- ✅ Advanced search - Full-text search and filtering (Coming Soon)
- ✅ Background jobs - Asynchronous email notifications and processing (Coming Soon)
- ✅ Analytics dashboard - Project insights and team productivity metrics (Coming Soon)
- Runtime: Node.js 20+ with TypeScript
- Framework: Express.js with ES Modules
- Database: PostgreSQL (Neon DB - Serverless)
- ORM: Prisma 6.19
- Caching: Redis (Coming Soon)
- Authentication: JWT with refresh tokens (Coming Soon)
- Testing: Jest + Supertest
- Code Quality: ESLint + Prettier
- Version Control: Git
- Package Manager: npm
- Environment: Docker Compose (Coming Soon)
- Socket.io for real-time features
- BullMQ for background job processing
- AWS S3 for file storage
- Winston for structured logging
- Swagger for API documentation
taskflow/
├── prisma/
│ ├── schema.prisma # Database schema definition
│ └── migrations/ # Database migration history
│ └── 20251125163954_init/ # Initial migration
├── src/
│ ├── config/
│ │ └── database.ts # Prisma client instance
│ ├── controllers/ # Request handlers (Coming Soon)
│ ├── middleware/ # Express middleware (Coming Soon)
│ ├── routes/ # API route definitions (Coming Soon)
│ ├── services/ # Business logic (Coming Soon)
│ ├── types/ # TypeScript type definitions (Coming Soon)
│ ├── utils/ # Helper functions (Coming Soon)
│ ├── __tests__/ # Test files
│ │ └── server.test.ts # Server integration tests
│ └── server.ts # Express app & server entry point
├── .env # Environment variables (gitignored)
├── .prettierrc # Code formatting rules
├── eslint.config.js # Linting configuration
├── jest.config.js # Testing configuration
├── tsconfig.json # TypeScript compiler options
├── package.json # Dependencies & scripts
└── README.md # Project documentation (you are here!)
- Node.js 20+ (Download)
- npm 10+
- Git
git clone <your-repo-url>
cd taskflownpm installCreate a .env file in the root directory:
# Database (Neon DB)
DATABASE_URL="postgresql://username:password@host.neon.tech/dbname?sslmode=require"
# Server
PORT=3000
NODE_ENV=development
# JWT Secrets (Change these in production!)
JWT_SECRET="your-super-secret-jwt-key-change-this"
JWT_REFRESH_SECRET="your-super-secret-refresh-key-change-this"
# Redis (Coming Soon)
REDIS_URL="redis://localhost:6379"
# AWS S3 (Coming Soon)
AWS_REGION="us-east-1"
AWS_ACCESS_KEY_ID="your-aws-key"
AWS_SECRET_ACCESS_KEY="your-aws-secret"
AWS_S3_BUCKET="taskflow-attachments"# Generate Prisma Client
npx prisma generate
# Run migrations to create database tables
npx prisma migrate dev --name init
# (Optional) Open Prisma Studio to view your database
npx prisma studio# Start development server with hot-reload
npm run dev
# Server will be available at http://localhost:3000# Test health endpoint
curl http://localhost:3000/health
# Expected response:
# {"status":"healthy"}Our database is designed for multi-tenancy with the following models:
id(CUID) - Primary keyemail(String, unique) - User email addressname(String) - Full namepasswordHash(String) - Hashed passwordavatar(String, optional) - Profile picture URLisActive(Boolean) - Account statuscreatedAt,updatedAt- Timestamps
id(CUID) - Primary keyname(String) - Workspace nameslug(String, unique) - URL-friendly identifierdescription(String, optional) - Workspace descriptionlogo(String, optional) - Workspace logo URLsettings(JSON) - Workspace preferencescreatedById(Foreign key) - Workspace creatorcreatedAt,updatedAt- Timestamps
id(CUID) - Primary keyrole(Enum: OWNER, ADMIN, MEMBER, GUEST) - Access levelworkspaceId(Foreign key) - Associated workspaceuserId(Foreign key) - Team memberjoinedAt- Membership timestamp
id(CUID) - Primary keyname(String) - Project namedescription(String, optional) - Project detailsstatus(Enum: ACTIVE, ARCHIVED, COMPLETED) - Project statestartDate,dueDate(DateTime, optional) - Timelinecolor(String, optional) - UI color tagworkspaceId(Foreign key) - Parent workspacecreatedById(Foreign key) - Project creatorcreatedAt,updatedAt- Timestamps
id(CUID) - Primary keytitle(String) - Task titledescription(String, optional) - Task detailsstatus(Enum: TODO, IN_PROGRESS, IN_REVIEW, DONE, CANCELLED)priority(Enum: LOW, MEDIUM, HIGH, URGENT)dueDate(DateTime, optional) - DeadlineestimatedHours,actualHours(Float, optional) - Time trackingtags(String[]) - Task labelsposition(Int) - Display orderprojectId(Foreign key) - Parent projectcreatedById(Foreign key) - Task creatorassigneeId(Foreign key, optional) - Assigned userparentTaskId(Foreign key, optional) - Subtask relationshipcreatedAt,updatedAt- Timestamps
id(CUID) - Primary keycontent(String) - Comment texttaskId(Foreign key) - Associated taskuserId(Foreign key) - Comment authorcreatedAt,updatedAt- Timestamps
id(CUID) - Primary keyfilename(String) - Original filenamefileUrl(String) - S3 storage URLfileSize(Int) - File size in bytesmimeType(String) - File typetaskId(Foreign key) - Associated taskuploadedById(Foreign key) - UploaderuploadedAt- Upload timestamp
id(CUID) - Primary keytype(Enum: TASK_ASSIGNED, TASK_UPDATED, etc.)title(String) - Notification titlemessage(String) - Notification contentisRead(Boolean) - Read statusdata(JSON, optional) - Additional metadatauserId(Foreign key) - RecipientcreatedAt- Timestamp
id(CUID) - Primary keyaction(Enum: CREATED, UPDATED, DELETED, etc.)entityType(String) - Model name (e.g., "Task")entityId(String) - Record IDchanges(JSON, optional) - Change detailsipAddress,userAgent(String, optional) - Request metadatauserId(Foreign key) - User who performed actiontaskId(Foreign key, optional) - Related taskcreatedAt- Timestamp
User ──┬─── creates ──> Workspace
├─── member of ──> WorkspaceMember
├─── creates ──> Project
├─── creates ──> Task
├─── assigned to ──> Task
└─── writes ──> Comment, ActivityLog
Workspace ──┬─── has ──> WorkspaceMember
└─── contains ──> Project
Project ──── contains ──> Task
Task ──┬─── has ──> Comment
├─── has ──> Attachment
├─── has ──> ActivityLog
└─── parent of ──> Task (subtasks)
We've added strategic indexes for query performance:
@@index([email]) # User lookup
@@index([slug]) # Workspace lookup
@@index([workspaceId, userId]) # Team member queries
@@index([status]) # Task filtering
@@index([priority]) # Task sorting
@@index([projectId]) # Project tasks
@@index([assigneeId]) # User tasks- Initialized Node.js project with TypeScript
- Configured
tsconfig.jsonfor ES2022 modules - Set up project folder structure
- Installed core dependencies (Express, Prisma, TypeScript)
- Configured
package.jsonscripts - Set up
.prettierrcfor code formatting - Configured
eslint.config.jsfor code quality - Created
.envfor environment variables
- Designed multi-tenant database architecture
- Created Prisma schema with 9 models
- Defined relationships and foreign keys
- Set up enums for type safety (Role, TaskStatus, Priority, etc.)
- Added database indexes for performance
- Generated initial migration
- Applied migration to Neon DB
- Created Prisma client singleton (
src/config/database.ts) - Verified schema with Prisma Studio
- Create
Dockerfilefor containerization - Create
docker-compose.ymlfor local development - Configure PostgreSQL service
- Configure Redis service
- Test local container deployment
- Install authentication dependencies (bcryptjs, jsonwebtoken, zod)
- Create authentication middleware
- Implement user registration endpoint
- Implement login endpoint
- Implement JWT token generation
- Implement token refresh logic
- Create "Get Current User" endpoint
- Add request validation with Zod
- Test authentication flow
npm run dev # Start development server with hot-reload
npm run build # Compile TypeScript to JavaScript
npm start # Run production buildnpx prisma generate # Generate Prisma Client
npx prisma migrate dev # Create and apply migration
npx prisma migrate deploy # Apply migrations (production)
npx prisma studio # Open database GUI
npx prisma db seed # Run seed scripts (coming soon)npm test # Run all tests once
npm run test:watch # Run tests in watch mode
npm test -- --coverage # Run tests with coverage report
npm test -- auth.test.ts # Run specific test filenpm run lint # Check for linting errors
npm run format # Format code with Prettier| Variable | Description | Example | Required |
|---|---|---|---|
DATABASE_URL |
Neon PostgreSQL connection string | postgresql://user:pass@host/db |
✅ Yes |
PORT |
Server port | 3000 |
❌ No (default: 3000) |
NODE_ENV |
Environment mode | development / production |
✅ Yes |
JWT_SECRET |
JWT signing key | your-secret-key |
✅ Yes (Week 1, Day 6) |
JWT_REFRESH_SECRET |
Refresh token signing key | your-refresh-secret |
✅ Yes (Week 1, Day 6) |
REDIS_URL |
Redis connection string | redis://localhost:6379 |
✅ Yes (Week 3) |
AWS_REGION |
AWS S3 region | us-east-1 |
✅ Yes (Week 6) |
AWS_ACCESS_KEY_ID |
AWS access key | AKIA... |
✅ Yes (Week 6) |
AWS_SECRET_ACCESS_KEY |
AWS secret key | secret... |
✅ Yes (Week 6) |
AWS_S3_BUCKET |
S3 bucket name | taskflow-attachments |
✅ Yes (Week 6) |
PASS src/__tests__/server.test.ts
Server
GET /
✓ should return API info (177ms)
GET /health
✓ should return health status (7ms)
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
// Example test case
import { describe, it, expect } from '@jest/globals';
import request from 'supertest';
import { app } from '../server';
describe('Server', () => {
it('should return API info', async () => {
const res = await request(app).get('/');
expect(res.status).toBe(200);
expect(res.body).toHaveProperty('message', 'TaskFlow API Server');
});
});# Run all tests
npm test
# Watch mode (re-runs on file changes)
npm run test:watch
# Generate coverage report
npm test -- --coveragehttp://localhost:3000/api
GET /healthResponse:
{
"status": "healthy"
}GET /Response:
{
"message": "TaskFlow API Server",
"status": "ok",
"timestamp": "2025-11-25T10:30:00.000Z"
}POST /api/auth/register- Create new user accountPOST /api/auth/login- Authenticate userGET /api/auth/me- Get current user profilePOST /api/auth/refresh- Refresh access tokenPOST /api/auth/logout- Logout user
This is a learning project following the Backend Mastery Roadmap.
-
Create a feature branch
git checkout -b feature/your-feature-name
-
Make your changes
# Write code npm run format # Format code npm run lint # Check linting npm test # Run tests
-
Commit your changes
git add . git commit -m "feat: add your feature description"
-
Push to repository
git push origin feature/your-feature-name
We follow Conventional Commits:
feat: Add user authentication
fix: Fix database connection pool leak
docs: Update API documentation
test: Add tests for workspace controller
refactor: Improve error handling middleware
chore: Update dependencies
MIT License - See LICENSE file for details
- Prisma - Next-generation ORM
- Neon - Serverless PostgreSQL
- Express.js - Web framework
- TypeScript - Type safety
For questions or issues:
- Open an issue in the repository
- Check the Backend Roadmap for guidance
Built with ❤️ while learning backend development
Last updated: November 25, 2025