- Overview
- Technology Stack
- Architecture
- Features
- Project Structure
- Getting Started
- Workflow
- API Documentation
- Database Schema
- Security
सहायPath (SahayPath - "Path of Help") is a comprehensive blood donation platform that bridges the gap between blood donors and hospitals/recipients in need. The platform uses intelligent matching algorithms, real-time location services, and AI-powered document verification to ensure safe and efficient blood donations.
- 🩸 Quick Blood Matching: Connect donors with recipients using ML-based intelligent matching
- 🏥 Hospital Integration: Enable hospitals to manage blood requests and inventory
- ✅ Secure Verification: AI-powered OCR for Aadhaar/PAN/Hospital license verification
- 📍 Location-Based Matching: Find nearest donors using geolocation
- 🤖 LightGBM ML Model: 15-feature gradient boosting for optimal donor-request pairing
- 👨⚕️ Admin Dashboard: Comprehensive platform management and analytics
| Technology | Version | Purpose |
|---|---|---|
| Next.js | 14.2.16 | React framework with SSR/SSG |
| React | 18.0+ | UI library |
| TypeScript | 5.0+ | Type safety |
| Tailwind CSS | 3.4+ | Utility-first styling |
| Radix UI | Latest | Accessible component primitives |
| shadcn/ui | Latest | Pre-built component library |
| Lucide React | Latest | Icon library |
| React Hook Form | 7.54+ | Form management |
| Zod | 3.23+ | Schema validation |
| date-fns | 4.1.0 | Date utilities |
| Recharts | 2.15+ | Data visualization |
| Technology | Version | Purpose |
|---|---|---|
| Node.js | 16.0+ | JavaScript runtime |
| Express.js | 4.18.2 | Web framework |
| MySQL | 8.0+ | Relational database |
| mysql2 | 3.6.5 | MySQL driver with Promise support |
| JWT | 9.0.2 | Authentication tokens |
| bcryptjs | 2.4.3 | Password hashing |
| Helmet | 7.1.0 | Security headers |
| CORS | 2.8.5 | Cross-origin resource sharing |
| Multer | 2.0.2 | File upload handling |
| Sharp | 0.34.5 | Image processing |
| Express Validator | 7.3.1 | Request validation |
| Express Rate Limit | 7.1.5 | API rate limiting |
| Technology | Version | Purpose |
|---|---|---|
| LightGBM | Latest | ML-based donor matching |
| NumPy | Latest | Numerical computing for ML |
| scikit-learn | Latest | ML utilities & preprocessing |
| PaddleOCR | Latest | Document text extraction |
| Python | 3.8+ | AI/ML service runtime |
| python-shell | 5.0.0 | Node-Python bridge |
| OpenCV | Latest | Image preprocessing |
| PIL/Pillow | Latest | Image manipulation |
| Technology | Purpose |
|---|---|
| Nodemon | Development auto-reload |
| Concurrently | Run multiple dev servers |
| ESLint | Code linting |
| Git | Version control |
| VS Code | IDE |
┌─────────────────────────────────────────────────────────────┐
│ CLIENT LAYER │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Donors │ │Hospitals │ │ Admins │ │Recipients│ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
└───────┼────────────┼─────────────┼─────────────┼──────────┘
│ │ │ │
└────────────┴─────────────┴─────────────┘
│
┌────────────▼─────────────┐
│ NEXT.JS FRONTEND │
│ ┌────────────────────┐ │
│ │ Pages & Routes │ │
│ │ - Dashboard │ │
│ │ - Profile │ │
│ │ - Donor Search │ │
│ │ - Request Mgmt │ │
│ │ - Admin Panel │ │
│ └────────────────────┘ │
│ ┌────────────────────┐ │
│ │ Components │ │
│ │ - UI Library │ │
│ │ - Forms │ │
│ │ - Charts │ │
│ └────────────────────┘ │
│ ┌────────────────────┐ │
│ │ State Management │ │
│ │ - Auth Context │ │
│ │ - API Client │ │
│ └────────────────────┘ │
└────────────┬─────────────┘
│ HTTP/REST
┌────────────▼─────────────┐
│ EXPRESS.JS BACKEND │
│ ┌────────────────────┐ │
│ │ API Routes │ │
│ │ - Auth │ │
│ │ - Donors │ │
│ │ - Hospitals │ │
│ │ - Requests │ │
│ │ - Bookings │ │
│ │ - Admin │ │
│ │ - Verification │ │
│ │ - Matching (ML) │ │
│ └────────────────────┘ │
│ ┌────────────────────┐ │
│ │ Middleware │ │
│ │ - JWT Auth │ │
│ │ - Validation │ │
│ │ - Rate Limiting │ │
│ │ - Error Handling │ │
│ └────────────────────┘ │
│ ┌────────────────────┐ │
│ │ Services │ │
│ │ - LightGBM ML │ │
│ │ - Rule-based Match │ │
│ │ - Verification │ │
│ │ - Notifications │ │
│ └────────────────────┘ │
└────┬──────────────┬──────┘
│ │
┌────────▼──────┐ ┌───▼─────────┐
│ MYSQL DB │ │ PYTHON OCR │
│ │ │ SERVICE │
│ - Users │ │ │
│ - Profiles │ │ PaddleOCR │
│ - Requests │ │ + OpenCV │
│ - Bookings │ │ │
│ - Inventory │ │ Document │
│ - Verifications│ │ Processing │
└───────────────┘ └─────────────┘
User Login
│
▼
JWT Token Generation
│
▼
Token Stored (localStorage)
│
▼
Protected Route Access
│
▼
Token Verification (Middleware)
│
▼
Role-Based Authorization
- ✅ Profile Management: Complete donor profile with medical history and location
- ✅ Availability Status: Set availability (available/busy/unavailable)
- ✅ Blood Request Alerts: View urgent blood requests nearby
- ✅ Donation History: Track all donations and impact
- ✅ Document Verification: Aadhaar/PAN verification with OCR
- ✅ Location Preferences: Set max travel distance and city/district/state
- ✅ Time Preferences: Choose preferred donation times
- ✅ Volunteer for Requests: Opt-in to donate for specific hospital requests
- ✅ Create Blood Requests: Submit blood requirement requests with auto-hospital suggestion
- ✅ Hospital Auto-Suggestion: Automatically suggests nearby hospitals based on location
- ✅ Proximity Matching: Hospitals sorted by proximity (same city → district → state)
- ✅ Request Management: Track all submitted requests and their status
- ✅ Urgency Levels: Set urgency (critical/urgent/moderate/routine)
- ✅ Medical Details: Provide patient details, medical reason, and contact info
- ✅ Unified Dashboard: Access both donor and recipient features from one dashboard
- ✅ Blood Request Management: Create and manage blood requests
- ✅ Donor Search: Find verified donors by blood type and location
- ✅ Blood Inventory: Track blood bank inventory
- ✅ Booking Management: Schedule and confirm donations
- ✅ Hospital Verification: License verification with OCR
- ✅ Urgency Levels: Mark requests as critical/urgent/routine
- ✅ Request History: View all past and active requests
- ✅ Incoming Requests: Review blood requests from recipients
- ✅ Profile Management: Update hospital details, location, and departments
- ✅ Dashboard Analytics: User statistics, verification metrics
- ✅ User Management: View and manage all users
- ✅ Verification Management: Approve/reject document verifications
- ✅ System Health: Monitor API and database status
- ✅ User Roles: Manage donors, hospitals, and recipients
- ✅ Activity Tracking: Monitor platform activity
-
🤖 LightGBM ML Matching System (Primary)
- Gradient Boosting Decision Trees (GBDT)
- 15 engineered features for donor-request pairing
- Blood Compatibility Scoring (0-1): Multi-level compatibility matrix (exact, compatible, emergency)
- Normalized Distance (0-1): Haversine formula with 50km max range
- Urgency Matching (0-1): Priority alignment (emergency > urgent > routine)
- Donor Experience (0-1): Normalized donation count (0-50+ donations)
- Time Match Score (0-1): Preferred donation time compatibility
- Availability Score (0-1): Immediate availability vs scheduled
- Emergency Contact (0/1): Binary flag for emergency contact presence
- Donation Gap (days): Time since last donation
- Units Match (0/1): Donor capacity meets request requirement
- Blood Type Encoding: One-hot encoded blood groups (A+, B+, O+, AB+, A-, B-, O-, AB-)
- City Match (0/1): Same city priority boost
- Weight Normalized (0-1): Weight/70kg for capacity estimation
- Medical Conditions (0/1): Binary flag for health conditions
- Age Normalized (0-1): Age/80 for health indicator
- Automatic model training with 10,000 synthetic samples
- Model persistence via pickle for fast inference
- JSON-based Node-Python IPC integration
-
🧠 Rule-Based Matching (Fallback)
- Blood type compatibility
- Geographic proximity
- Donor availability
- Urgency prioritization
- Travel distance consideration
- Automatic fallback if ML service unavailable
-
🔒 AI-Powered Verification
- PaddleOCR text extraction
- Aadhaar card verification
- PAN card verification
- Hospital license validation
- Document authenticity checks
-
📍 Location Services
- Geolocation tracking
- Distance calculation
- Nearby donor search
- Map integration ready
sahaypath/
├── app/ # Next.js app directory
│ ├── admin/ # Admin dashboard
│ │ └── page.tsx # Admin panel UI
│ ├── auth/ # Authentication pages
│ │ ├── signin/ # Login page
│ │ └── signup/ # Registration page
│ ├── dashboard/ # User dashboards
│ │ ├── page.tsx # Main unified dashboard (donors & recipients)
│ │ ├── hospital/ # Hospital dashboard
│ │ ├── ngo/ # NGO dashboard (future)
│ │ └── recipient/ # Legacy recipient dashboard (being deprecated)
│ ├── donors/ # Donor management
│ │ ├── page.tsx # Donor list/search
│ │ └── new-request/ # Create request (legacy)
│ ├── hospitals/ # Hospital pages
│ ├── matching/ # Matching algorithm UI
│ ├── needy/ # Blood request pages (main page for recipients)
│ │ └── page.tsx # View requests & create new requests
│ ├── profile/ # User profile
│ │ └── page.tsx # Profile settings (unified for donors/hospitals)
│ ├── register/ # Registration flows
│ │ └── donor/ # Donor registration
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Landing page
│ └── globals.css # Global styles
│
├── backend/ # Express.js backend
│ ├── src/
│ │ ├── config/
│ │ │ └── database.js # MySQL connection pool
│ │ ├── controllers/
│ │ │ ├── authController.js # Authentication logic
│ │ │ ├── donorController.js # Donor operations & profile
│ │ │ ├── hospitalController.js # Hospital operations & workflow
│ │ │ ├── profileController.js # Profile management
│ │ │ ├── requestController.js # Request handling
│ │ │ ├── recipientController.js # Recipient request creation & hospital matching
│ │ │ └── verificationController.js # Document verification
│ │ ├── database/
│ │ │ ├── schema.sql # Database schema (if exists)
│ │ │ ├── schema-tables.sql # Table definitions
│ │ │ └── migrate.js # Migration runner
│ │ ├── middleware/
│ │ │ ├── auth.js # JWT verification
│ │ │ └── validation.js # Request validation
│ │ ├── routes/
│ │ │ ├── authRoutes.js # /api/auth/*
│ │ │ ├── donorRoutes.js # /api/donors/*
│ │ │ ├── hospitalRoutes.js # /api/hospitals/*
│ │ │ ├── profileRoutes.js # /api/profile/*
│ │ │ ├── requestRoutes.js # /api/requests/*
│ │ │ ├── recipientRoutes.js # /api/recipients/* (new)
│ │ │ ├── adminRoutes.js # /api/admin/*
│ │ │ ├── matchingRoutes.js # /api/matching/* (ML)
│ │ │ └── cleanupRoutes.js # Cleanup utilities
│ │ ├── services/
│ │ │ ├── lightgbm_matching.py # LightGBM ML service
│ │ │ ├── lightgbmMatchingService.js # Node-Python bridge
│ │ │ └── verificationService.js # OCR integration
│ │ └── server.js # Express app entry
│ ├── uploads/ # Document uploads
│ │ └── documents/ # Verification docs
│ ├── package.json
│ └── nodemon.json
│
├── components/ # React components
│ ├── ui/ # shadcn/ui components
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ ├── dialog.tsx
│ │ ├── form.tsx
│ │ ├── input.tsx
│ │ ├── select.tsx
│ │ ├── table.tsx
│ │ ├── tabs.tsx
│ │ ├── toast.tsx
│ │ └── ... (50+ UI components)
│ ├── navbar.tsx # Navigation bar
│ ├── theme-provider.tsx # Dark mode support
│ ├── error-boundary.tsx # Error handling
│ └── donor-profile-setup.tsx # Donor onboarding
│
├── lib/ # Utilities and helpers
│ ├── api.ts # API client class
│ ├── auth-context.tsx # Authentication context
│ ├── matching-algorithm.ts # Blood matching logic
│ └── utils.ts # Helper functions
│
├── hooks/ # Custom React hooks
│ ├── use-mobile.ts
│ └── use-toast.ts
│
├── public/ # Static assets
│ └── images/
│
├── styles/
│ └── globals.css # Tailwind imports
│
├── ocr_service.py # Python OCR service
├── package.json # Frontend dependencies
├── tsconfig.json # TypeScript config
├── next.config.mjs # Next.js config
├── tailwind.config.ts # Tailwind config
├── components.json # shadcn config
└── README.md # This file
- Node.js >= 16.0.0
- Python >= 3.8
- MySQL >= 8.0
- npm or pnpm or yarn
- Git
-
Clone the repository
git clone https://github.com/codewithshxbh/Sahaypath.git cd sahaypath -
Install frontend dependencies
npm install # or pnpm install -
Install backend dependencies
cd backend npm install cd ..
-
Install Python dependencies
python -m venv .venv .venv\Scripts\activate # Windows # source .venv/bin/activate # Linux/Mac pip install paddlepaddle paddleocr opencv-python pillow numpy
-
Setup MySQL Database
mysql -u root -p < backend/src/database/schema.sql -
Configure Environment Variables
Create
.envin backend directory:PORT=5000 DB_HOST=localhost DB_PORT=3306 DB_USER=root DB_PASSWORD=your_password DB_NAME=sahaypath JWT_SECRET=your-super-secret-jwt-key-change-this CORS_ORIGIN=http://localhost:3000 NODE_ENV=development RATE_LIMIT_WINDOW=15 RATE_LIMIT_MAX=100
-
Run Development Servers
npm run dev
This runs both frontend (port 3000) and backend (port 5000) concurrently.
Or run separately:
# Terminal 1 - Frontend npm run dev:frontend # Terminal 2 - Backend npm run dev:backend
-
Access the Application
- Frontend: http://localhost:3000
- Backend API: http://localhost:5000
INSERT INTO users (id, email, password_hash, user_type, is_active)
VALUES (
UUID(),
'admin@sahaypath.com',
-- Password: 'admin123' (hashed with bcrypt)
'$2a$10$YourHashedPasswordHere',
'admin',
TRUE
);sequenceDiagram
User->>Frontend: Fill registration form
Frontend->>Backend: POST /api/auth/signup
Backend->>MySQL: Create user record
Backend->>Frontend: Return JWT token
Frontend->>LocalStorage: Store token
Frontend->>User: Redirect to profile setup
Steps:
- User chooses role (Donor/Hospital/Recipient)
- Fills registration form with email/password
- Backend validates data and hashes password
- JWT token generated and returned
- Token stored in localStorage
- User redirected to profile completion
sequenceDiagram
Donor->>Frontend: Complete profile form
Frontend->>Backend: POST /api/profile/donor
Backend->>MySQL: Create donor_profile
Frontend->>User: Show verification upload
Donor->>Frontend: Upload Aadhaar document
Frontend->>Backend: POST /api/verification/upload
Backend->>Python: Process with PaddleOCR
Python->>Backend: Return extracted data
Backend->>MySQL: Store verification record
Backend->>Frontend: Verification pending
Steps:
- Fill personal details (name, DOB, blood type, etc.)
- Add location (address, city, state, pincode)
- Set preferences (travel distance, preferred time)
- Upload Aadhaar/PAN for verification
- OCR extracts document data
- Verification marked as "pending"
- Admin reviews and approves
sequenceDiagram
Recipient->>Frontend: Open create request dialog
Frontend->>Backend: GET /api/recipients/nearby-hospitals
Backend->>MySQL: Query hospitals by location
Backend->>Frontend: Return sorted hospitals
Frontend->>Recipient: Display hospital dropdown
Recipient->>Frontend: Fill request form + select hospital
Frontend->>Backend: POST /api/recipients/requests
Backend->>MySQL: Validate hospital exists
Backend->>MySQL: Insert donation_request
Backend->>Frontend: Request created successfully
Frontend->>Recipient: Show success notification
Steps:
- User clicks "Create Request" on dashboard or /needy page
- Dialog opens with request form
- Backend auto-fetches nearby hospitals:
- Same city (proximity_score = 1)
- Same district (proximity_score = 2)
- Same state (proximity_score = 3)
- User fills form:
- Blood type needed
- Urgency level (critical/urgent/moderate/routine)
- Patient details (name, age)
- Contact info (person, phone)
- Required by date
- Medical reason/case description
- Select hospital from auto-suggested list
- Frontend maps urgency:
moderate→medium,urgent→high - Request sent to selected hospital
- Hospital staff reviews and processes request
Key Features:
- ✅ Auto hospital suggestion based on user location
- ✅ Proximity-based sorting
- ✅ Unified form with validation
- ✅ Urgency level mapping to database ENUMs
- ✅ Real-time hospital availability check
sequenceDiagram
Hospital->>Frontend: Create blood request
Frontend->>Backend: POST /api/requests
Backend->>MySQL: Insert donation_request
Backend->>Matching: Run matching algorithm
Matching->>MySQL: Query eligible donors
Matching->>Backend: Return matched donors
Backend->>Frontend: Show matched donors
Frontend->>Hospital: Display donor list
Steps:
- Hospital fills request form
- Patient details
- Blood type needed
- Units required
- Urgency level (critical/urgent/routine)
- Required by date
- Request saved to database
- Matching algorithm runs:
- Filter by blood type compatibility
- Calculate distance from hospital
- Check donor availability
- Sort by urgency and proximity
- Matched donors displayed
- Hospital can contact donors
ML Model Architecture:
- Algorithm: Gradient Boosting Decision Trees (GBDT)
- Features: 15 engineered donor-request features
- Training: 10,000 synthetic samples with realistic distributions
- Output: Match probability score (0-1)
- Persistence: Pickle serialization for fast loading
Feature Engineering (15 features):
# backend/src/services/lightgbm_matching.py
def extract_features(donor, request):
return [
# 1. Blood compatibility score (0-1)
blood_compatibility_score(donor, request), # exact=1, compatible=0.8, emergency=0.3
# 2. Normalized distance (0-1, inverse)
normalize_distance(donor, request), # Haversine formula, max 50km
# 3. Urgency match score (0-1)
urgency_match_score(donor, request), # emergency > urgent > routine
# 4. Donor experience (0-1)
donor['total_donations'] / 50, # Normalized donation count
# 5. Time preference match (0-1)
time_match_score(donor, request), # Preferred donation time
# 6. Availability score (0-1)
1 if donor['availability'] == 'immediate' else 0.5,
# 7. Emergency contact (0/1)
1 if donor['emergency_contact'] else 0,
# 8. Donation gap (days)
(datetime.now() - donor['last_donation_date']).days,
# 9. Units match (0/1)
1 if donor['units_can_donate'] >= request['units_needed'] else 0,
# 10-17. Blood type one-hot encoding (8 features)
*encode_blood_type(donor['blood_type']), # A+, B+, O+, AB+, A-, B-, O-, AB-
# 18. City match (0/1)
1 if donor['city'] == request['hospital_city'] else 0,
# 19. Weight normalized (0-1)
donor['weight'] / 70, # Standard weight reference
# 20. Medical conditions (0/1)
1 if donor['medical_conditions'] else 0,
# 21. Age normalized (0-1)
donor['age'] / 80 # Max age reference
]ML Matching Workflow:
sequenceDiagram
Hospital->>Frontend: Create request
Frontend->>Backend: POST /api/matching/ml
Backend->>Python: lightgbm_matching.py
Python->>Model: Load blood_matching_model.pkl
Python->>FeatureExtractor: Extract 15 features per donor
Model->>Model: Predict match scores
Model->>Python: Ranked predictions
Python->>Python: Filter 56-day gap
Python->>Backend: Top N donors (JSON)
Backend->>Frontend: Display matches
Advantages:
- 📊 Learns complex feature interactions
- 🎯 Multi-objective optimization in single score
- 📈 Continuous improvement with real data
- 🔄 Adapts to regional donation patterns
- ⚡ Faster than multi-step rule-based sorting
Algorithm (used if ML service unavailable):
// lib/matching-algorithm.ts
function matchDonorsToRequest(request, donors) {
// Step 1: Filter by blood type compatibility
const compatibleDonors = donors.filter(donor =>
isBloodTypeCompatible(donor.blood_type, request.blood_type)
);
// Step 2: Filter by availability
const availableDonors = compatibleDonors.filter(donor =>
donor.availability_status === 'available'
);
// Step 3: Calculate distance and filter by travel distance
const nearbyDonors = availableDonors.filter(donor => {
const distance = calculateDistance(
request.hospital_location,
donor.location
);
return distance <= donor.max_travel_distance;
});
// Step 4: Score and sort donors
const scoredDonors = nearbyDonors.map(donor => ({
...donor,
score: calculateMatchScore(donor, request)
}));
// Step 5: Sort by score (highest first)
return scoredDonors.sort((a, b) => b.score - a.score);
}Matching Criteria:
- ✅ Blood type compatibility (A+, A-, B+, B-, AB+, AB-, O+, O-)
- ✅ Geographic proximity (< max_travel_distance)
- ✅ Donor availability status
- ✅ Last donation date (56 days minimum gap)
- ✅ Urgency level prioritization
- ✅ Donor total donations (reliability score)
sequenceDiagram
User->>Backend: Upload document image
Backend->>FileSystem: Save to uploads/
Backend->>Python: Call ocr_service.py
Python->>PaddleOCR: Initialize OCR
PaddleOCR->>Image: Extract text regions
Image->>PaddleOCR: Return text + confidence
PaddleOCR->>Python: Structured data
Python->>Backend: JSON response
Backend->>MySQL: Store extracted_data
Backend->>Admin: Notify for review
OCR Process:
- User uploads document (Aadhaar/PAN/License)
- Image saved to
backend/uploads/documents/ - Node.js calls Python script via python-shell
- PaddleOCR processes image:
- Detects text regions
- Recognizes characters
- Returns text with confidence scores
- Extracted data stored in
user_verifications.extracted_data(JSON) - Admin reviews extracted data
- Admin approves/rejects verification
Supported Documents:
- Aadhaar Card: Extract name, number, DOB, address
- PAN Card: Extract name, number, DOB
- Hospital License: Extract registration number, validity
sequenceDiagram
Admin->>Frontend: View pending verifications
Frontend->>Backend: GET /api/admin/verifications
Backend->>MySQL: Query pending records
MySQL->>Backend: Return verifications
Backend->>Frontend: Display list
Admin->>Frontend: Click verify/reject
Frontend->>Backend: PUT /api/admin/verifications/:id/status
Backend->>MySQL: Update verification_status
Backend->>Frontend: Success response
Frontend->>Admin: Show confirmation
Admin Actions:
- View all pending verifications
- Review uploaded document
- Check extracted OCR data
- Approve ✅ or Reject ❌
- If rejected, provide reason
- User notified of decision
- User can resubmit if rejected
sequenceDiagram
Hospital->>Donor: Contact donor
Donor->>Hospital: Confirm availability
Hospital->>Frontend: Create booking
Frontend->>Backend: POST /api/bookings
Backend->>MySQL: Insert donation_booking
Backend->>Donor: Send confirmation
Backend->>Frontend: Booking created
Hospital->>Booking: Update status (scheduled)
Donor->>Hospital: Arrives for donation
Hospital->>Booking: Mark as completed
Backend->>MySQL: Update donor stats
Backend->>Donor: Update total_donations
Booking States:
pending→ Booking created, waiting confirmationconfirmed→ Donor confirmed availabilityscheduled→ Appointment scheduledcompleted→ Donation completedcancelled→ Booking cancelled
http://localhost:5000/api
POST /auth/signup
Content-Type: application/json
{
"email": "user@example.com",
"password": "securePassword123",
"userType": "user" | "hospital" | "admin",
"phone": "9876543210"
}
Response:
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "uuid",
"email": "user@example.com",
"userType": "user"
}
}POST /auth/signin
Content-Type: application/json
{
"email": "user@example.com",
"password": "securePassword123"
}
Response:
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "uuid",
"email": "user@example.com",
"role": "user"
},
"profile": { ... }
}GET /donors?bloodType=A+&city=Delhi&limit=10
Authorization: Bearer <token>
Response:
{
"success": true,
"data": [
{
"id": "uuid",
"first_name": "John",
"last_name": "Doe",
"blood_type": "A+",
"city": "Delhi",
"availability_status": "available",
"total_donations": 5
}
]
}POST /profile/donor
Authorization: Bearer <token>
Content-Type: application/json
{
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "1990-01-01",
"gender": "male",
"bloodType": "A+",
"weight": 75,
"address": "123 Main St",
"city": "Delhi",
"state": "Delhi",
"pincode": "110001"
}POST /requests
Authorization: Bearer <token>
Content-Type: application/json
{
"patientName": "Jane Smith",
"bloodType": "O+",
"unitsNeeded": 2,
"urgencyLevel": "critical",
"medicalReason": "Surgery",
"requiredBy": "2025-12-15",
"department": "Emergency",
"doctorName": "Dr. Kumar"
}GET /requests?status=pending&bloodType=O+&urgency=critical
Authorization: Bearer <token>
Response:
{
"success": true,
"data": [
{
"id": "uuid",
"hospital_name": "AIIMS Delhi",
"patient_name": "Jane Smith",
"blood_type": "O+",
"units_needed": 2,
"urgency_level": "critical",
"required_by": "2025-12-15",
"status": "pending"
}
]
}POST /verification/upload
Authorization: Bearer <token>
Content-Type: multipart/form-data
{
"docType": "aadhaar" | "pan" | "hospital_registration",
"document": <file>
}
Response:
{
"success": true,
"verificationId": "uuid",
"data": {
"id": "uuid",
"docType": "aadhaar",
"status": "pending"
}
}GET /verification/status
Authorization: Bearer <token>
Response:
{
"success": true,
"aadhaar": {
"verification_type": "aadhaar",
"verification_status": "verified",
"extracted_data": { ... }
},
"pan": {
"verification_status": "pending"
}
}GET /recipients/nearby-hospitals?city=Greater%20Noida&district=Gautam%20Buddha%20Nagar&state=Uttar%20Pradesh&bloodType=O+
Authorization: Bearer <token>
Response:
{
"success": true,
"hospitals": [
{
"id": "uuid",
"hospital_name": "Yatharth Wellness Hospital",
"city": "Greater Noida",
"district": "Gautam Buddha Nagar",
"state": "Uttar Pradesh",
"proximity_score": 1,
"blood_units_available": 5,
"contact_phone": "1234567890",
"departments": "Emergency,ICU,Surgery"
}
],
"message": "Hospitals found"
}Query Parameters:
city(required): City namedistrict(optional): District namestate(required): State namebloodType(optional): Blood type to check inventory
Proximity Score:
1= Same city2= Same district3= Same state4= Other
POST /recipients/requests
Authorization: Bearer <token>
Content-Type: application/json
{
"hospitalId": "uuid",
"bloodType": "O+",
"patientName": "John Doe",
"patientAge": 35,
"unitsNeeded": 1,
"urgency": "moderate",
"medicalReason": "Blood loss during accident",
"requiredBy": "2025-12-15",
"contactPerson": "Jane Doe",
"contactPhone": "9876543210"
}
Response:
{
"success": true,
"message": "Request sent to hospital successfully",
"data": {
"requestId": "uuid"
}
}Urgency Mapping:
- Frontend
critical→ Databasecritical - Frontend
urgent→ Databasehigh - Frontend
moderate→ Databasemedium - Frontend
routine→ Databaselow
GET /admin/stats
Authorization: Bearer <admin-token>
Response:
{
"success": true,
"data": {
"totalUsers": 16,
"pendingVerifications": 3,
"verifiedUsers": 12,
"totalDonations": 45
}
}GET /admin/verifications?status=pending&limit=50
Authorization: Bearer <admin-token>
Response:
{
"success": true,
"data": [
{
"id": "uuid",
"user_name": "John Doe",
"user_email": "john@example.com",
"verification_type": "aadhaar",
"verification_status": "pending",
"document_path": "/uploads/...",
"extracted_data": { ... }
}
]
}PUT /admin/verifications/:id/status
Authorization: Bearer <admin-token>
Content-Type: application/json
{
"status": "verified" | "rejected",
"rejectionReason": "Invalid document" // if rejected
}GET /admin/users?role=user&status=verified&limit=50
Authorization: Bearer <admin-token>
Response:
{
"success": true,
"data": [
{
"id": "uuid",
"email": "user@example.com",
"user_type": "user",
"phone": "9876543210",
"verification_status": "verified",
"created_at": "2025-01-01T00:00:00Z"
}
]
}| Table | Purpose | Key Columns |
|---|---|---|
users |
User accounts & auth | id, email, password_hash, user_type |
donor_profiles |
Donor information | user_id, blood_type, location, availability |
hospital_profiles |
Hospital details | user_id, hospital_name, license_number |
donation_requests |
Blood requests | hospital_id, blood_type, urgency_level |
donation_bookings |
Scheduled donations | request_id, donor_id, status |
user_verifications |
Document verification | user_id, verification_type, status |
blood_inventory |
Hospital blood stock | hospital_id, blood_type, units |
notifications |
User notifications | user_id, message, read_status |
users (1) ──→ (1) donor_profiles
users (1) ──→ (1) hospital_profiles
users (1) ──→ (N) user_verifications
hospital_profiles (1) ──→ (N) donation_requests
donation_requests (1) ──→ (N) donation_bookings
donor_profiles (1) ──→ (N) donation_bookings-- Users table
INDEX idx_email (email)
INDEX idx_user_type (user_type)
INDEX idx_emergency (emergency_contact)
-- Donor profiles
INDEX idx_blood_type (blood_type)
INDEX idx_location (city, state)
INDEX idx_availability (availability_status)
-- Donation requests
INDEX idx_status_urgency (status, urgency_level)
INDEX idx_blood_type (blood_type)
INDEX idx_required_by (required_by)
-- Verifications
INDEX idx_user_verification (user_id, verification_type)
INDEX idx_verification_status (verification_status)-
Authentication
- JWT tokens with expiration
- Bcrypt password hashing (10 rounds)
- Token stored in httpOnly cookies (recommended) or localStorage
-
Authorization
- Role-based access control (RBAC)
- Middleware protection for routes
- Admin-only endpoints
-
API Security
- Helmet.js for security headers
- CORS configuration
- Rate limiting (100 requests per 15 minutes)
- Request validation with express-validator
-
Data Protection
- SQL injection prevention (parameterized queries)
- XSS protection
- Input sanitization
- File upload restrictions (size, type)
-
Password Policy
- Minimum 6 characters (should be 8+ in production)
- Hashed with bcrypt
- Never logged or exposed
JWT_SECRET=<strong-secret-key>
DB_PASSWORD=<database-password>.env files to Git!
- ✅ Single Dashboard for All Users: Combined donor and recipient features into one dashboard at
/dashboard - ✅ Role-Based Features: Users see relevant features based on their role (user/hospital/admin)
- ✅ Removed Redundancy: Deprecated separate
/dashboard/recipient- all users use/dashboard - ✅ Toggle Functionality: Users can switch between donor and recipient modes seamlessly
- ✅ Auto Hospital Suggestion: Automatically suggests nearby hospitals based on user location
- ✅ Proximity-Based Sorting: Hospitals sorted by same city → district → state
- ✅ Dual Access Points: Create requests from both
/dashboardand/needypages - ✅ Smart Form Validation: Required fields with helpful placeholders
- ✅ Urgency Mapping: Frontend urgency values correctly mapped to database ENUMs
- ✅ Real-time Hospital Availability: Shows blood inventory if available
- ✅ Location Fields: Added district field for better proximity matching
- ✅ Emergency Contact: Phone number stored in
emergency_contactfield - ✅ Profile Persistence: Fixed issues with profile data saving and loading
- ✅ Medical Conditions: Optional text fields now handled correctly (empty string → null)
- ✅ Hospital Profiles: Full update endpoint with location and department management
- ✅ New Recipient Routes:
/api/recipients/nearby-hospitalsand/api/recipients/requests - ✅ Urgency Level Mapping: Backend automatically maps frontend urgency to database ENUM values
critical→criticalurgent→highmoderate→mediumroutine→low
- ✅ Location-Based Queries: SQL queries with proximity scoring
- ✅ Blood Inventory Integration: Hospital suggestions include current blood availability
- ✅ Request Validation: Comprehensive validation for all request fields
- ✅ Sonner Toast Integration: Better notification system with toast alerts
- ✅ Loading States: Skeleton loaders and spinner indicators
- ✅ Error Handling: Detailed error messages with JSON debugging support
- ✅ Form Defaults: Smart defaults using user profile data
- ✅ Hospital Selection: Dropdown with proximity indicators (🎯 for closest)
- User registration and login
- Donor profile creation
- Hospital profile creation
- Document upload and OCR
- Blood request creation
- Donor search and filtering
- Matching algorithm accuracy
- Admin verification approval/rejection
- Booking creation and status updates
- Profile updates
- Password reset (if implemented)
# Register user
curl -X POST http://localhost:5000/api/auth/signup \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"test123","userType":"user"}'
# Login
curl -X POST http://localhost:5000/api/auth/signin \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"test123"}'
# Get donors (with token)
curl http://localhost:5000/api/donors \
-H "Authorization: Bearer <your-token>"
# ML-based donor matching
curl -X POST http://localhost:5000/api/matching/ml \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-token>" \
-d '{
"request": {
"blood_type": "O+",
"urgency": "emergency",
"units_needed": 2,
"hospital_lat": 28.6139,
"hospital_lng": 77.2090,
"hospital_city": "Delhi"
},
"donors": [/* donor array */],
"maxDistance": 50
}'
# Get matching model info
curl http://localhost:5000/api/matching/model/info \
-H "Authorization: Bearer <your-token>"Problem: Frontend sends urgency values that don't match database ENUM.
Solution: Backend now automatically maps urgency values:
// In recipientController.js
const urgencyMap = {
'critical': 'critical',
'urgent': 'high',
'moderate': 'medium',
'routine': 'low'
};Verify: Check backend logs for the mapping output.
Problem: No hospitals appear when creating a request.
Debugging Steps:
# 1. Check if hospitals exist in database
mysql> SELECT id, hospital_name, city, district, state FROM hospital_profiles;
# 2. Verify user profile has location
mysql> SELECT city, district, state FROM donor_profiles WHERE user_id = '<your-user-id>';
# 3. Test the API directly
curl "http://localhost:5000/api/recipients/nearby-hospitals?city=Greater%20Noida&district=Gautam%20Buddha%20Nagar&state=Uttar%20Pradesh" \
-H "Authorization: Bearer <your-token>"Common Causes:
- User profile missing location data → Update profile with city/district/state
- No hospitals registered in that location → Register a test hospital
- Authorization token missing → Check localStorage for 'auth_token'
Problem: Profile fields reset after saving.
Solution:
- Ensure
emergency_contactfield exists in database for phone storage - Check that
districtcolumn exists indonor_profilesandhospital_profiles - Verify empty strings are converted to NULL for optional text fields
SQL Migration:
ALTER TABLE donor_profiles ADD COLUMN district VARCHAR(100);
ALTER TABLE hospital_profiles ADD COLUMN district VARCHAR(100);Problem: API returns "No token provided" or "Invalid token".
Solution:
// Check token in browser console
console.log(localStorage.getItem('auth_token'));
// If null or undefined, user needs to login again
// If exists but still fails, token may be expired
// Clear and re-login
localStorage.removeItem('auth_token');
// Navigate to /auth/signinProblem: Backend can't connect to MySQL.
Check:
# 1. Is MySQL running?
mysql --version
mysql -u root -p # Try connecting
# 2. Check backend .env
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=your_password
DB_NAME=sahaypath
# 3. Verify database exists
mysql> SHOW DATABASES;
mysql> USE sahaypath;
mysql> SHOW TABLES;Problem: "CORS policy: No 'Access-Control-Allow-Origin' header"
Solution:
// In backend/src/server.js, verify CORS config:
app.use(cors({
origin: 'http://localhost:3000',
credentials: true
}));If using different port:
CORS_ORIGIN=http://localhost:3001Problem: npm run build fails or shows TypeScript errors.
Solutions:
# Clear cache and reinstall
rm -rf node_modules .next
npm install
# Check for type errors
npm run type-check
# Update dependencies
npm updateProblem: Document verification fails.
Check:
# 1. Is Python virtual environment activated?
.venv\Scripts\activate # Windows
source .venv/bin/activate # Linux/Mac
# 2. Are dependencies installed?
pip list | grep -E "paddle|opencv|pillow"
# 3. Test OCR service directly
python ocr_service.pyProblem: Matching falls back to rule-based.
Debug:
# Check if model file exists
ls backend/src/services/blood_matching_model.pkl
# Test Python service
cd backend/src/services
python lightgbm_matching.py
# Check Node logs for errors
[BACKEND] ML Service Error: ...Problem: SQL errors about missing columns.
Solution:
-- Check current schema
DESCRIBE donation_requests;
-- Add missing columns if needed
ALTER TABLE donation_requests
ADD COLUMN blood_type_needed VARCHAR(5),
ADD COLUMN urgency_level ENUM('critical', 'high', 'medium', 'low'),
ADD COLUMN case_description TEXT;- Set
NODE_ENV=production - Use strong JWT_SECRET
- Configure production database
- Set up HTTPS/SSL
- Enable production logging
- Set up monitoring (error tracking)
- Configure CORS for production domain
- Optimize images and assets
- Enable compression middleware
- Set up backup strategy
- Configure rate limiting for production
- Review and harden security headers
- Frontend: Vercel, Netlify, AWS Amplify
- Backend: Railway, Render, Heroku, AWS EC2
- Database: PlanetScale, AWS RDS, Digital Ocean
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License.
- Developer: Shubhendu Chakrabarti (@codewithshxbh)
- Project: सहायPath (SahayPath)
For issues or questions:
- GitHub Issues: Create an issue
- Email: support@sahaypath.com (if available)
- shadcn/ui for the beautiful component library
- Radix UI for accessible primitives
- PaddleOCR for OCR capabilities
- Next.js team for the amazing framework
- All open-source contributors
Made with ❤️ for saving lives
सहायPath - Where Every Drop Counts