Skip to content

Latest commit

 

History

History
220 lines (172 loc) · 6.63 KB

File metadata and controls

220 lines (172 loc) · 6.63 KB

🔧 ShramikLink — Blue-Collar Worker Marketplace

"Dunzo for skilled workers" — Find a verified plumber, electrician, or carpenter in under 5 minutes.

Built for India's 500M+ blue-collar workforce with smartphones but no digital presence.


🏗️ Architecture Overview

Flutter App (Android/iOS)
       │
       │  REST API + WebSocket
       ▼
Spring Boot Backend (Java 17)
       │
       ├── PostgreSQL  (all data — users, jobs, otps)
       └── Redis       (worker availability cache by pincode)

📁 Project Structure

shramiklink/
├── backend/                  ← Spring Boot API
│   ├── src/main/java/com/shramiklink/
│   │   ├── controller/       ← HTTP endpoints (REST API)
│   │   ├── service/          ← Business logic
│   │   ├── entity/           ← Database tables (JPA)
│   │   ├── repository/       ← Database queries
│   │   ├── security/         ← JWT auth filter
│   │   ├── config/           ← Redis, WebSocket, Security config
│   │   ├── dto/              ← API request/response shapes
│   │   └── enums/            ← Skill types, job status, etc.
│   ├── Dockerfile
│   └── pom.xml
│
├── flutter_app/              ← Flutter mobile app
│   ├── lib/
│   │   ├── main.dart         ← App entry point
│   │   ├── models/           ← Data classes (Worker, Job, etc.)
│   │   ├── services/         ← API calls (http package)
│   │   ├── providers/        ← State management (Riverpod)
│   │   ├── screens/
│   │   │   ├── auth/         ← Login, OTP screens
│   │   │   ├── worker/       ← Worker dashboard, profile setup
│   │   │   ├── employer/     ← Home, search, booking screens
│   │   │   └── shared/       ← Job detail screen
│   │   └── utils/            ← Constants, theme, router
│   └── pubspec.yaml
│
├── docker-compose.yml        ← Runs backend + postgres + redis together
└── .github/workflows/        ← CI/CD (auto test + deploy)

🚀 Quick Start (Local Development)

Prerequisites

  • Java 17+
  • Flutter 3.16+
  • Docker + Docker Compose
  • Android Studio or VS Code

1. Start Backend (One Command)

# From the root shramiklink/ folder
docker-compose up --build

This starts:

  • PostgreSQL on port 5432
  • Redis on port 6379
  • Spring Boot API on port 8080

Verify it's running:

curl http://localhost:8080/api/auth/health
# → {"status":"UP","service":"ShramikLink"}

2. Run Flutter App

cd flutter_app
flutter pub get
flutter run

⚠️ For Android emulator, the API URL 10.0.2.2:8080 automatically points to your computer's localhost. For a real device, update apiBaseUrl in lib/utils/app_constants.dart to your computer's IP.


🔑 API Reference

All protected routes require: Authorization: Bearer <token>

Auth

Method Endpoint Body Description
POST /api/auth/send-otp {"phone":"9876543210"} Send OTP
POST /api/auth/verify-otp {"phone":"...","otp":"123456","role":"WORKER"} Verify OTP → JWT

Workers

Method Endpoint Description
PUT /api/workers/profile Update worker profile
GET /api/workers/{id} View worker profile
PATCH /api/workers/availability?status=AVAILABLE_NOW Toggle availability
GET /api/workers/search?skill=PLUMBER&pincode=201001 Search workers

Jobs

Method Endpoint Description
POST /api/jobs Create booking
PATCH /api/jobs/{id}/status?status=ACCEPTED Accept/complete job
POST /api/jobs/{id}/rate Rate worker
GET /api/jobs/worker Worker's job history
GET /api/jobs/employer Employer's job history

💡 Key Technical Decisions (Skill Builder)

Why Redis for availability?

  • Employers search "show me plumbers in 201001" thousands of times a day
  • Going to PostgreSQL every time = slow + expensive
  • Redis caches the result for 5 minutes in RAM = 10x faster
  • When a worker changes status → @CacheEvict clears that pincode's cache

Why WebSocket?

  • Without it: Flutter app must ask "any new jobs?" every 5 seconds = wasteful
  • With it: Server pushes "new job!" the instant it happens = efficient + instant
  • Workers get notified in real-time via STOMP over WebSocket

Why JWT over sessions?

  • Mobile apps can't use browser cookies
  • JWT is a signed token stored on device — server verifies the signature without DB lookup
  • Stateless = works across multiple server instances (horizontal scaling)

Why OTP login (no password)?

  • Most workers don't remember complex passwords
  • Phone number is the universal Indian identity — everyone knows their number
  • Reduces support burden (no "forgot password" flow needed)

💰 Revenue Model (Built In)

The 5% platform fee is calculated automatically in JobService.java:

BigDecimal platformFee = totalAmount.multiply(new BigDecimal("0.05"));
Metric Numbers
500 bookings/month ₹50,000+ revenue
₹99 per booking Tier 1 city pricing
₹299/month worker subscription Premium listing

🚢 Production Deployment

Environment Variables (set in your server/cloud)

DATABASE_URL=jdbc:postgresql://your-db-host:5432/shramiklink
DB_USERNAME=shramiklink
DB_PASSWORD=<strong-password>
REDIS_HOST=your-redis-host
JWT_SECRET=<256-bit-random-string>
OTP_MOCK=false

Deploy with Docker

# On your server
git clone your-repo && cd shramiklink
docker-compose up -d

CI/CD

Push to main branch → GitHub Actions automatically:

  1. Runs backend tests
  2. Builds Flutter APK
  3. Deploys new Docker image to your server

Add these GitHub Secrets: SERVER_HOST, SSH_PRIVATE_KEY


📱 SMS Gateway (Production)

In application.properties, set app.otp.mock-enabled=false

Then in OtpService.java, implement:

// Fast2SMS (cheapest for India, ₹0.15 per SMS)
// API: https://fast2sms.com/dev/bulk
private void sendSmsViaFast2SMS(String phone, String otp) {
    // HTTP POST to Fast2SMS API
}

🗺️ Go-To-Market (Ghaziabad First)

  1. Visit 5 housing societies personally
  2. Onboard their regular plumbers/electricians
  3. Show employers the app — "find your usual guy here"
  4. 20 workers + 10 employers = first real traction
  5. Word of mouth → 5 housing societies → 50

Zero marketing budget. Zero travel. One city.