A production-grade SaaS platform where clients submit tasks and receive deliverables without managing freelancers.
Core Value Proposition:
- Clients submit tasks and receive final deliverables (ZERO freelancer coordination)
- Platform handles assignment, tracking, quality assurance, and delivery
- Freelancers get clear tasks and steady work
- Admin controls quality, flow, and fairness
This is NOT a freelancer marketplace.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CLIENT LAYER β
β React + Vite + Tailwind CSS (Role-based Dashboards) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β API GATEWAY LAYER β
β Express.js RESTful API + JWT Auth Middleware β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β BUSINESS LOGIC LAYER β
β Controllers + Services + State Machine + Validators β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DATA ACCESS LAYER β
β MongoDB + Mongoose ODM β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. User Login β POST /api/auth/login
2. Server validates credentials (bcrypt)
3. Generate JWT access token (15min) + refresh token (7days)
4. Store refresh token in httpOnly cookie
5. Access token sent in response body
6. Client stores access token in memory (not localStorage)
7. Include access token in Authorization header
8. Refresh token rotation on renewal
- Client: Can only access own tasks, submit requests, approve deliverables
- Freelancer: Can only see assigned tasks, submit work, view earnings
- Admin: Full platform access, task assignment, QA, user management
- bcrypt password hashing (salt rounds: 12)
- JWT with short expiration
- Refresh token rotation
- Rate limiting on auth endpoints
- Input validation and sanitization
- MongoDB injection prevention
- CORS configuration
- Helmet.js security headers
- Environment variable protection
{
_id: ObjectId,
email: String (unique, indexed),
password: String (hashed),
role: Enum ['client', 'freelancer', 'admin'],
profile: {
firstName: String,
lastName: String,
phone: String,
avatar: String
},
// Freelancer-specific
freelancerProfile: {
skills: [String],
experience: Number,
availability: String,
performanceScore: Number (0-100),
completedTasks: Number,
rating: Number
},
// Client-specific
clientProfile: {
company: String,
totalTasksSubmitted: Number
},
status: Enum ['active', 'suspended', 'blocked'],
refreshToken: String,
createdAt: Date,
updatedAt: Date
}{
_id: ObjectId,
taskId: String (unique, auto-generated),
client: ObjectId (ref: User),
freelancer: ObjectId (ref: User),
assignedBy: ObjectId (ref: User - admin),
taskDetails: {
title: String,
type: Enum ['video-editing', 'web-development', 'design', 'writing', 'other'],
description: String,
requirements: String,
attachments: [String], // URLs
deadline: Date,
budget: Number,
revisionLimit: Number (default: 2)
},
status: Enum [
'submitted', // Client submitted
'under_review', // Admin reviewing
'assigned', // Assigned to freelancer
'in_progress', // Freelancer working
'submitted_work', // Freelancer submitted
'qa_review', // Admin QA
'revision_requested', // Need changes
'delivered', // Sent to client
'client_revision', // Client wants changes
'completed', // Client approved
'cancelled', // Cancelled
'disputed' // In dispute
],
workflow: {
submittedAt: Date,
reviewedAt: Date,
assignedAt: Date,
startedAt: Date,
submittedWorkAt: Date,
qaCompletedAt: Date,
deliveredAt: Date,
completedAt: Date
},
metrics: {
revisionsUsed: Number,
reassignmentCount: Number,
actualCompletionTime: Number // hours
},
priority: Enum ['low', 'medium', 'high', 'urgent'],
tags: [String],
createdAt: Date,
updatedAt: Date
}{
_id: ObjectId,
task: ObjectId (ref: Task),
freelancer: ObjectId (ref: User),
submissionType: Enum ['initial', 'revision'],
content: {
description: String,
deliverables: [String], // URLs
notes: String
},
qaReview: {
reviewer: ObjectId (ref: User - admin),
status: Enum ['pending', 'approved', 'rejected'],
feedback: String,
reviewedAt: Date
},
clientReview: {
status: Enum ['pending', 'approved', 'revision_requested'],
feedback: String,
reviewedAt: Date
},
version: Number,
createdAt: Date,
updatedAt: Date
}{
_id: ObjectId,
paymentId: String (unique),
task: ObjectId (ref: Task),
client: ObjectId (ref: User),
freelancer: ObjectId (ref: User),
amounts: {
taskBudget: Number,
platformCommission: Number, // percentage
platformFee: Number, // calculated
freelancerPayout: Number // calculated
},
status: Enum ['pending', 'escrowed', 'released', 'refunded'],
escrow: {
heldAt: Date,
releaseScheduled: Date,
releasedAt: Date
},
transactionDetails: {
paymentMethod: String,
transactionId: String,
gateway: String // future: 'stripe'
},
createdAt: Date,
updatedAt: Date
}{
_id: ObjectId,
task: ObjectId (ref: Task),
reviewer: ObjectId (ref: User),
reviewee: ObjectId (ref: User),
reviewType: Enum ['client_to_platform', 'platform_to_freelancer'],
rating: Number (1-5),
feedback: String,
createdAt: Date,
updatedAt: Date
}{
_id: ObjectId,
recipient: ObjectId (ref: User),
type: Enum [
'task_assigned',
'task_submitted',
'qa_feedback',
'client_approval',
'revision_requested',
'payment_released',
'deadline_reminder'
],
content: {
title: String,
message: String,
actionUrl: String
},
relatedTask: ObjectId (ref: Task),
status: Enum ['unread', 'read'],
priority: Enum ['low', 'medium', 'high'],
createdAt: Date,
readAt: Date
}{
_id: ObjectId,
user: ObjectId (ref: User),
action: String,
resource: String,
resourceId: ObjectId,
changes: Object,
ipAddress: String,
userAgent: String,
timestamp: Date
}// Users
- email (unique)
- role
- status
- 'freelancerProfile.performanceScore' (for assignment logic)
// Tasks
- taskId (unique)
- client
- freelancer
- status
- 'taskDetails.deadline'
- createdAt
// Submissions
- task
- freelancer
- 'qaReview.status'
// Payments
- paymentId (unique)
- task
- status
// Notifications
- recipient + status (compound)
- createdAt ββββββββββββββββ
β SUBMITTED β (Client creates task)
ββββββββ¬ββββββββ
β
βΌ
ββββββββββββββββ
β UNDER_REVIEW β (Admin reviews task)
ββββββββ¬ββββββββ
β
ββββββββββββ΄βββββββββββ
β β
βΌ βΌ
[Reject/Cancel] ββββββββββββββββ
β ASSIGNED β (Admin assigns to freelancer)
ββββββββ¬ββββββββ
β
βΌ
ββββββββββββββββ
β IN_PROGRESS β (Freelancer working)
ββββββββ¬ββββββββ
β
βΌ
ββββββββββββββββ
βSUBMITTED_WORKβ (Freelancer submits)
ββββββββ¬ββββββββ
β
βΌ
ββββββββββββββββ
β QA_REVIEW β (Admin quality check)
ββββββββ¬ββββββββ
β
ββββββββββββββΌβββββββββββββ
β β
βΌ βΌ
[QA Rejected] ββββββββββββββββ
(Revision or β DELIVERED β (Sent to client)
Reassign) ββββββββ¬ββββββββ
β β
β βΌ
β ββββββββββββββββ
β βClient Reviewsβ
β ββββββββ¬ββββββββ
β β
β βββββββββββΌββββββββββ
β β β
β βΌ βΌ
β [Client Approves] [Revision Request]
β β β
β βΌ βΌ
β ββββββββββββββββ ββββββββββββββββ
β β COMPLETED β βCLIENT_REVISIONβ
β ββββββββββββββββ ββββββββ¬ββββββββ
β β
ββββββββββββββββββββββββββββββββββ
(Back to IN_PROGRESS)
| Current State | Allowed Next States | Who Can Transition |
|---|---|---|
| submitted | under_review, cancelled | Admin |
| under_review | assigned, cancelled | Admin |
| assigned | in_progress, reassigned | Freelancer, Admin |
| in_progress | submitted_work | Freelancer |
| submitted_work | qa_review | System (automatic) |
| qa_review | delivered, revision_requested, reassigned | Admin |
| revision_requested | in_progress | System (automatic) |
| delivered | completed, client_revision, disputed | Client |
| client_revision | in_progress | System (automatic) |
| completed | - | Final State |
| cancelled | - | Final State |
| disputed | qa_review | Admin |
POST /api/auth/register - Register new user
POST /api/auth/login - Login (returns access + refresh token)
POST /api/auth/refresh - Refresh access token
POST /api/auth/logout - Logout (invalidate refresh token)
POST /api/auth/forgot-password - Request password reset
POST /api/auth/reset-password - Reset password with token
GET /api/auth/me - Get current user info
GET /api/client/dashboard - Client dashboard stats
POST /api/client/tasks - Create new task
GET /api/client/tasks - Get all client's tasks
GET /api/client/tasks/:id - Get specific task details
PATCH /api/client/tasks/:id/approve - Approve final delivery
PATCH /api/client/tasks/:id/revision - Request revision
GET /api/client/payments - Get payment history
GET /api/client/invoices - Get invoices
POST /api/client/reviews - Submit platform review
GET /api/freelancer/dashboard - Freelancer dashboard stats
GET /api/freelancer/profile - Get freelancer profile
PUT /api/freelancer/profile - Update freelancer profile
GET /api/freelancer/tasks - Get assigned tasks
GET /api/freelancer/tasks/:id - Get task details
PATCH /api/freelancer/tasks/:id/accept - Accept task
PATCH /api/freelancer/tasks/:id/reject - Reject task
POST /api/freelancer/tasks/:id/submit - Submit work
GET /api/freelancer/earnings - Get earnings history
GET /api/freelancer/performance - Get performance metrics
GET /api/admin/dashboard - Admin dashboard with analytics
GET /api/admin/tasks - Get all tasks (with filters)
GET /api/admin/tasks/:id - Get task details
PATCH /api/admin/tasks/:id/review - Review submitted task
POST /api/admin/tasks/:id/assign - Assign task to freelancer
POST /api/admin/tasks/:id/reassign - Reassign task
PATCH /api/admin/submissions/:id/qa - QA review submission
GET /api/admin/users - Get all users (with filters)
GET /api/admin/users/:id - Get user details
PATCH /api/admin/users/:id/status - Update user status (suspend/block)
GET /api/admin/freelancers - Get all freelancers with metrics
GET /api/admin/analytics - Platform analytics
POST /api/admin/disputes/:id/resolve - Resolve dispute
GET /api/admin/payments - Get all payments
PATCH /api/admin/settings - Update platform settings
GET /api/notifications - Get user notifications
PATCH /api/notifications/:id/read - Mark notification as read
PATCH /api/notifications/read-all - Mark all as read
POST /api/upload - Upload file (task attachments/deliverables)
- Skill Matching: Match task type with freelancer skills
- Performance Score: Prioritize freelancers with score > 70
- Availability: Check freelancer's current workload
- Past Performance: Consider completion rate and ratings
- Workload Balancing: Distribute tasks fairly
Assignment Priority Score =
(Performance Score * 0.4) +
(Skill Match * 0.3) +
(Availability * 0.2) +
(Past Completion Rate * 0.1)Platform Commission: 15% (configurable by admin)
Task Budget: $100
Platform Fee: $15
Freelancer Payout: $85
Payment Flow:
1. Client pays $100 β Escrowed
2. Task completed β Admin releases payment
3. Platform keeps $15
4. Freelancer receives $85- Default revision limit: 2 per task
- Each revision extends deadline by 48 hours
- After revision limit: admin intervention required
- Unlimited revisions incur additional charges
- Deadline warning: 24 hours before
- Overdue penalty: -5 performance score
- 3 missed deadlines: temporary suspension
- Client can extend deadline (one-time, max 48 hours)
Performance Score (0-100) =
(On-time Completion Rate * 40) +
(First-time Approval Rate * 30) +
(Client Satisfaction * 20) +
(Admin QA Pass Rate * 10)- All submissions go through admin QA
- QA must complete within 12 hours
- 3 failed QA = task reassignment
- Auto-reassignment after 2nd revision failure
- Client or freelancer raises dispute
- Task status β 'disputed'
- Payment held in escrow
- Admin investigates (48-hour SLA)
- Admin decision is final
- Payment released or refunded based on decision
TaskNexus/
βββ backend/
β βββ src/
β β βββ config/
β β β βββ database.js
β β β βββ jwt.js
β β β βββ constants.js
β β βββ models/
β β β βββ User.js
β β β βββ Task.js
β β β βββ Submission.js
β β β βββ Payment.js
β β β βββ Review.js
β β β βββ Notification.js
β β β βββ AuditLog.js
β β βββ middleware/
β β β βββ auth.js
β β β βββ roleCheck.js
β β β βββ validation.js
β β β βββ errorHandler.js
β β β βββ rateLimiter.js
β β βββ controllers/
β β β βββ authController.js
β β β βββ clientController.js
β β β βββ freelancerController.js
β β β βββ adminController.js
β β β βββ notificationController.js
β β βββ services/
β β β βββ taskService.js
β β β βββ assignmentService.js
β β β βββ paymentService.js
β β β βββ notificationService.js
β β β βββ performanceService.js
β β β βββ emailService.js
β β βββ routes/
β β β βββ auth.routes.js
β β β βββ client.routes.js
β β β βββ freelancer.routes.js
β β β βββ admin.routes.js
β β β βββ notification.routes.js
β β βββ utils/
β β β βββ validators.js
β β β βββ helpers.js
β β β βββ logger.js
β β βββ app.js
β βββ .env.example
β βββ .gitignore
β βββ package.json
β βββ server.js
β
βββ frontend/
β βββ public/
β βββ src/
β β βββ assets/
β β βββ components/
β β β βββ common/
β β β β βββ Navbar.jsx
β β β β βββ Sidebar.jsx
β β β β βββ Button.jsx
β β β β βββ Input.jsx
β β β β βββ Modal.jsx
β β β β βββ Table.jsx
β β β β βββ Badge.jsx
β β β β βββ Card.jsx
β β β βββ auth/
β β β β βββ LoginForm.jsx
β β β β βββ RegisterForm.jsx
β β β β βββ ProtectedRoute.jsx
β β β βββ client/
β β β β βββ ClientDashboard.jsx
β β β β βββ CreateTask.jsx
β β β β βββ TaskList.jsx
β β β β βββ TaskDetails.jsx
β β β β βββ PaymentHistory.jsx
β β β βββ freelancer/
β β β β βββ FreelancerDashboard.jsx
β β β β βββ ProfileSetup.jsx
β β β β βββ AssignedTasks.jsx
β β β β βββ SubmitWork.jsx
β β β β βββ Earnings.jsx
β β β βββ admin/
β β β βββ AdminDashboard.jsx
β β β βββ TaskManagement.jsx
β β β βββ AssignTask.jsx
β β β βββ QAReview.jsx
β β β βββ UserManagement.jsx
β β β βββ Analytics.jsx
β β β βββ PlatformSettings.jsx
β β βββ context/
β β β βββ AuthContext.jsx
β β β βββ NotificationContext.jsx
β β βββ hooks/
β β β βββ useAuth.js
β β β βββ useTask.js
β β β βββ useNotification.js
β β βββ services/
β β β βββ api.js
β β β βββ authService.js
β β β βββ taskService.js
β β β βββ uploadService.js
β β βββ utils/
β β β βββ constants.js
β β β βββ helpers.js
β β β βββ validators.js
β β βββ pages/
β β β βββ LandingPage.jsx
β β β βββ Login.jsx
β β β βββ Register.jsx
β β β βββ ClientDashboard.jsx
β β β βββ FreelancerDashboard.jsx
β β β βββ AdminDashboard.jsx
β β β βββ NotFound.jsx
β β βββ App.jsx
β β βββ main.jsx
β β βββ index.css
β βββ .env.example
β βββ .gitignore
β βββ index.html
β βββ package.json
β βββ tailwind.config.js
β βββ postcss.config.js
β βββ vite.config.js
β
βββ README.md
β User authentication (all 3 roles) β Client: Create task, track status, approve delivery β Freelancer: View assigned tasks, submit work β Admin: Assign tasks, QA review, user management β Task workflow state machine β Mock escrow payment system β Basic notifications β Performance scoring β Revision handling (up to 2) β File upload/download β Role-based dashboards
π Real Stripe payment integration π Advanced AI task assignment (ML model) π Real-time chat (Socket.io) π Video call integration for disputes π Advanced analytics & reporting π Freelancer application system π Multi-currency support π Mobile app (React Native) π Email notifications (SendGrid) π SMS alerts (Twilio) π Advanced search & filters π Bulk task upload π API for third-party integrations π White-label solution
-
Smart Task Assignment
- ML model trained on past assignments
- Predict best freelancer match
- Optimize for completion time + quality
-
Quality Prediction
- Analyze submission before admin QA
- Flag potential quality issues
- Suggest improvements
-
Dynamic Pricing
- AI-based budget recommendations
- Market rate analysis
- Demand-based pricing
-
Fraud Detection
- Detect suspicious patterns
- Flag duplicate submissions
- Identify fake accounts
-
Automated QA Assistance
- Pre-screen deliverables
- Check for completeness
- Validate against requirements
- Environment variables for sensitive data
- bcrypt password hashing (salt rounds: 12)
- JWT with short expiration (15min access, 7d refresh)
- Refresh token rotation
- httpOnly cookies for refresh tokens
- CORS whitelist
- Helmet.js security headers
- Rate limiting (express-rate-limit)
- Input validation (Joi/express-validator)
- MongoDB injection prevention
- XSS protection
- CSRF tokens (for state-changing operations)
- File upload validation (size, type, scan)
- API request logging
- Audit trail for critical actions
- Role-based access control enforcement
- Session management
- SQL injection prevention (N/A - using MongoDB)
- Implement database connection pooling
- Use MongoDB indexes strategically
- Consider sharding for horizontal scaling
- Archive old completed tasks
- Implement caching layer (Redis)
- Implement API versioning (/api/v1/)
- Use load balancer (Nginx)
- Implement CDN for static assets
- API response pagination
- Background job queue (Bull/Redis)
- Code splitting and lazy loading
- Optimize bundle size
- Implement service worker (PWA)
- Image optimization
- Skeleton loaders for better UX
- Application Performance Monitoring (APM)
- Error tracking (Sentry)
- Log aggregation (Winston + CloudWatch)
- Uptime monitoring
- Database query performance tracking
- Unit tests (Jest)
- Integration tests (Supertest)
- API contract tests
- Load testing (Artillery)
- Component tests (React Testing Library)
- E2E tests (Playwright)
- Accessibility tests
- Visual regression tests
- Local MongoDB
- Node.js dev server (nodemon)
- Vite dev server (HMR)
- MongoDB Atlas
- Heroku/Railway (backend)
- Vercel (frontend)
- Environment: staging
- MongoDB Atlas (Production cluster)
- AWS EC2/ECS (backend)
- Cloudflare + S3 (frontend)
- CI/CD: GitHub Actions
- Monitoring: Datadog
β¨ Built production-grade SaaS platform with 100K+ users potential β¨ Implemented secure JWT authentication with refresh token rotation β¨ Designed complex state machine for task workflow management β¨ Built escrow payment system ready for Stripe integration β¨ Implemented role-based access control (RBAC) across 3 user types β¨ Created intelligent task assignment algorithm with ML readiness β¨ Architected scalable MongoDB schema with proper indexing β¨ Built RESTful API with 30+ endpoints following best practices β¨ Implemented comprehensive audit logging and security measures β¨ Designed responsive SaaS UI with Tailwind CSS
Built by a senior startup CTO mindset | Production-ready | Scalable | Secure