Workora is an enterprise-grade, full-stack freelancing marketplace platform that seamlessly connects Clients looking to post projects with Freelancers bidding on opportunities. Engineered with strict Clean Architecture, real-time Socket.IO messaging, automated Stripe Escrow Payments, milestone tracking, subscription tiers, and administrative dispute resolution.
--
Workora bridges the trust gap between hirers and remote freelancers. Unlike conventional gig platforms where financial risk is high, Workora utilizes a Milestone-Based Escrow Model: funds are locked safely in escrow before work begins and released to the freelancer's wallet only upon client verification and approval of deliverables. If disagreements arise, an integrated Dispute Resolution Mechanism allows administrators to evaluate proof of work and render fair financial arbitration.
The backend is built adhering to Uncle Bob's Clean Architecture (Domain-Driven Design) principles to isolate core business rules from frameworks, databases, and external services.
ββββββββββββββββββββββββββββββββββββββββββ
β Frameworks & Drivers β
β (Express, Mongoose, Socket.io, Stripe)β
β ββββββββββββββββββββββββββββββββββββ β
β β Interface Adapters β β
β β (Controllers, Repositories) β β
β β ββββββββββββββββββββββββββββββ β β
β β β Application β β β
β β β Use Cases β β β
β β β ββββββββββββββββββββββββ β β β
β β β β Domain Entities β β β β
β β β ββββββββββββββββββββββββ β β β
β β ββββββββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββ
- Framework Independence: Express or Mongoose can be swapped without touching core domain rules.
- Testability: Use Cases contain pure business logic and can be unit-tested without DB connection.
- Separation of Concerns: Controllers deal with HTTP, Repositories deal with DB data mapping, and Use Cases govern workflows.
- Multi-Role Authentication: Dedicated portals and role access controls for Clients, Freelancers, and Admins.
- Social Login: One-click sign-in using Google OAuth 2.0 (
@react-oauth/google). - OTP Verification & Password Recovery: Automated email dispatch using
Nodemailer. - JWT Session Security: Access and refresh tokens with secure cookie/header storage.
- Profile Customization: Manage avatars, professional titles, skill tags, hourly rates, portfolio links, and bios.
- Job Publishing: Clients post jobs with budget parameters, categories, required skills, and project deadlines.
- Advanced Discovery: Freelancers search, filter, and paginate through open positions by category, budget, and posted date.
- Proposal Submission: Freelancers submit tailored cover letters, proposed budgets, and execution timelines.
- Proposal Review & Hiring: Clients review incoming proposals, compare applicant profiles, and select freelancers for hire.
- Milestone Decomposition: Break projects into granular payment milestones (e.g., Design phase 30%, Development phase 70%).
- Escrow Funding: Client funds each milestone through Stripe Checkout. Payments are held in Escrow ledger.
- Deliverable Submission: Freelancers upload work progress and code links directly to specific milestones (
SubmitWorkModal). - Approval & Instant Payout: Upon client approval, Escrow funds are automatically released to the freelancer's Workora wallet (
PaymentSuccess).
- Instant Messaging: Built on
Socket.IOfor low-latency bidirectional communication between client and hired freelancer. - Read Receipts & Status: Real-time read indicators, unread message badges, and room-based message broadcasting.
- History Persistence: Chat history saved seamlessly in MongoDB for audit and dispute referencing.
- Dispute Escalation: Either party can raise a formal dispute (
RaiseDisputeModal) if contract terms are violated or deliverables are rejected. - Proof of Work Inspection: Admins inspect project chat logs, submitted milestone files, and initial contract terms.
- Admin Arbitration: Admins can execute partial or full refunds to clients or release disputed funds to freelancers (
ConcernList).
- Pro Subscriptions: Stripe-powered recurring monthly subscriptions for Clients and Freelancers (
SubscriptionPage). - Limit Enforcement: Subscriptions unlock higher proposal submission caps, reduced platform commission fees, and priority job listings.
- Ledger Tracking: Built-in wallet for tracking pending escrow balances, available balances, deposit history, and payout logs.
- Financial History: Transparent breakdown of platform commission, milestone payouts, and refunds.
- Platform Analytics: Dashboard reporting key platform metrics, total active contracts, revenue, and active users.
- User Management: Block/Unblock suspicious user accounts and manage freelancer verification badges.
- Taxonomy Management: Create, edit, and reorganize job categories and platform skill tags.
- Escrow Oversight: Monitor active escrow funds across all running contracts.
| Technology | Description |
|---|---|
| React 19 | Modern UI Component Framework (Vite powered) |
| TypeScript | Type-safe development across UI and state |
| Redux Toolkit & Redux Persist | Global state management & session persistence |
| Tailwind CSS v4 | Utility-first responsive styling system |
| Framer Motion | Micro-animations and page transitions |
| Socket.io-client | Real-time WebSocket communication client |
| React Hook Form | High-performance form state & validation |
| Lucide React | Modern iconography library |
| React Hot Toast & Confetti | Toast notifications & celebratory confetti feedback |
| Technology | Description |
|---|---|
| Node.js & Express v5 | Server environment & HTTP framework |
| TypeScript | Strict static typing for clean architecture entities |
| MongoDB & Mongoose | Document database & Object Data Modeling (ODM) |
| Socket.IO | Bidirectional real-time event web server |
| Stripe Node SDK | Checkout sessions, Escrow payment handling & Webhook parsing |
| Google Auth Library | Server-side Google OAuth token verification |
| Bcrypt & JWT | Password hashing & JSON Web Token generation |
| Nodemailer | Email dispatch for OTP verification and notifications |
| Node Cache | In-memory cache for fast lookup performance |
| Technology | Description |
|---|---|
| Docker & Docker Compose | Multi-container containerized deployment setup |
| ESLint & Prettier | Static code analysis and code formatting rules |
| Husky & Lint-Staged | Git pre-commit hooks enforcing linting before code commits |
Workora/
βββ Backend/
β βββ src/
β β βββ domain/ # Core entities & repository interfaces
β β βββ useCase/ # Business logic (Client, Freelancer, Admin, Chat)
β β β βββ admin/ # Admin workflows (auth, client, concern, dashboard)
β β β βββ client/ # Client workflows (auth, bid, escrow, jobs, milestone, payment)
β β β βββ freelancer/ # Freelancer workflows (auth, bid, dashboard, jobs, milestone)
β β β βββ chat/ # Real-time chat use cases
β β βββ adapters/ # Controllers, Repositories, Middlewares, Presenters
β β βββ frameWork/ # Express routes, Mongoose models, Socket server, Stripe SDK
β β βββ shared/ # Constants, utility helpers, error handlers
β βββ Dockerfile
β βββ package.json
β
βββ Frontend/
β βββ src/
β β βββ assets/ # Visual assets and images
β β βββ components/ # UI Components (admin, client, freelancer, common, chat, layout)
β β βββ hooks/ # Custom React hooks
β β βββ pages/ # Page components divided by role (Admin, Client, Freelancer)
β β βββ routes/ # Role-based protected routes & app router
β β βββ service/ # API services & Socket connections
β β βββ store/ # Redux slices & store configuration
β βββ Dockerfile
β βββ package.json
β
βββ docker-compose.yml # Container orchestration for DB, Backend, and Frontend
βββ README.md
- Challenge: Standard payment flows rely on client-side redirects to confirm payments. If a user closes their browser before returning to the app, funds remain in limbo, leading to race conditions where milestone statuses become out-of-sync.
- Solution: Engineered a robust Stripe Webhook Handler (
/client/stripe/webhook). Escrow funding state updates are triggered asynchronously by Stripeβs cryptographically signed webhook events, ensuring ledger consistency regardless of client network drops.
- Challenge: Express applications usually apply
express.json()globally. Parsing incoming Stripe webhook payloads into JSON corrupts the raw signature buffer required by Stripe to verify webhook authenticity. - Solution: Configured conditional middleware execution in
app.tsto skip standard JSON parsing for the Stripe webhook route:this._app.use((req, res, next) => { if (req.originalUrl.startsWith('/client/stripe/webhook')) { next(); } else { express.json()(req, res, next); } });
- Challenge: Guaranteeing zero message loss, real-time UI updates, and atomic read-receipt updates across active WebSockets while maintaining message persistence in MongoDB.
- Solution: Implemented room-isolated Socket handlers (
join_chat,send_message,mark_as_read). When a message is sent, it is first processed throughChatUsecaseto generate a database record with a timestamp and ID, then immediately broadcasted to room participants.
- Challenge: Preventing database schemas or Express HTTP objects (
req,res) from leaking into core business logic (Use Cases), which often makes code unmaintainable. - Solution: Enforced strict dependency inversion. Controllers extract HTTP parameters and pass plain data transfer objects (DTOs) into Use Cases. Use Cases interact exclusively with Repository Interfaces (abstractions), while concrete Mongoose repositories implement these interfaces.
- Challenge: Managing non-linear state transitions (
PendingβFundedβIn ProgressβSubmittedβApproved / DisputedβCompleted / Refunded). - Solution: Created state-machine validation logic inside use cases (
escrowFundUseCase,hireFreelancerUseCase) that validates prerequisites before allowing state changes, preventing unauthorized milestone releases or invalid dispute entries.
- Node.js:
v18.xor later - npm:
v9.xor later - MongoDB: Local instance or MongoDB Atlas URI
- Stripe Account: API Keys for test/production integration
Create a .env file in the Backend directory:
PORT=3560
MONGODB_URL=your_mongodb_connection_string
EMAIL=your_email@gmail.com
PASS=your_email_app_password
ACCESS_TOKEN_KEY=your_access_token_secret
REFRESH_TOKEN_KEY=your_refresh_token_secret
GOOGLE_CLIENT_ID=your_google_client_id
STRIPE_SECRET_KEY=your_stripe_secret_key
PUBLISHABLE_KEY=your_stripe_publishable_key
STRIPE_WEBHOOK_SECRET=your_stripe_webhook_secret
CLIENT_URL=http://localhost:5173
FRONTEND_URL=http://localhost:5173
STRIPE_CLIENT_PRICE_ID=your_stripe_client_price_id
STRIPE_FREELANCER_PRICE_ID=your_stripe_freelancer_price_idCreate a .env file in the Frontend directory (if required by your Vite setup):
VITE_API_BASE_URL=http://localhost:3560
VITE_GOOGLE_CLIENT_ID=your_google_client_id-
Clone the Repository:
git clone https://github.com/dhyyan/WORKORA.git cd WORKORA -
Install Root & Sub-package Dependencies:
npm install cd Backend && npm install cd ../Frontend && npm install cd ..
-
Run the Backend Server:
cd Backend npm run devBackend will run on http://localhost:3560
-
Run the Frontend App:
cd Frontend npm run devFrontend will run on http://localhost:5173
You can run the entire Workora stack (MongoDB, Backend, Frontend) with a single command using Docker Compose:
docker-compose up --build- Frontend: http://localhost
- Backend API: http://localhost:3560
- MongoDB: localhost:27017
Workora uses Husky and Lint-Staged to maintain strict code quality standards on every git commit.
-
Lint Backend:
cd Backend npm run lint -
Lint Frontend:
cd Frontend npm run lint
Developed with Dhyan by Dhyan