Skip to content

Latest commit

 

History

History
788 lines (615 loc) · 19.4 KB

File metadata and controls

788 lines (615 loc) · 19.4 KB

Medical Clinic API - Complete Documentation

📋 Table of Contents

  1. Project Overview
  2. Architecture
  3. File Structure Explained
  4. Database Models
  5. API Endpoints
  6. Authentication & Authorization
  7. Setup & Installation
  8. Environment Variables
  9. Usage Examples

🎯 Project Overview

This is a Medical Clinic Management System backend API built with:

  • Node.js & Express.js (ES6 Modules)
  • MongoDB & Mongoose (Database)
  • JWT (Authentication)
  • Bcrypt (Password Hashing)
  • Joi (Input Validation)
  • Nodemailer (Email Notifications)
  • Multer & Sharp (File Upload & Image Processing)

Key Features

✅ Role-based access control (Admin, Doctor, Patient) ✅ JWT authentication with token-based security ✅ Email notifications for appointments ✅ Doctor availability management ✅ Appointment booking system ✅ User status management (Active, Blocked, Pending) ✅ Image upload with processing ✅ Input validation on all routes


🏗️ Architecture

The project follows a modular architecture with clear separation of concerns:

┌─────────────────────────────────────────────────┐
│                   Client (React)                 │
└─────────────────────┬───────────────────────────┘
                      │ HTTP Requests
                      ↓
┌─────────────────────────────────────────────────┐
│              Express.js Server                   │
│  ┌──────────────────────────────────────────┐  │
│  │  Middlewares (CORS, Auth, Validation)    │  │
│  └──────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────┐  │
│  │  Routes (User, Doctor, Appointment)      │  │
│  └──────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────┐  │
│  │  Controllers (Business Logic)            │  │
│  └──────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────┐  │
│  │  Models (Mongoose Schemas)               │  │
│  └──────────────────────────────────────────┘  │
└─────────────────────┬───────────────────────────┘
                      │
                      ↓
┌─────────────────────────────────────────────────┐
│              MongoDB Database                    │
└─────────────────────────────────────────────────┘

📁 File Structure Explained

Root Files

index.js

Purpose: Server entry point

  • Imports the Express app
  • Connects to MongoDB database
  • Starts the server on specified port
  • Logs server status
import app from './app.js';
import connectDB from './Database/connection.js';

app.js

Purpose: Express application configuration

  • Sets up middlewares (CORS, JSON parser, etc.)
  • Defines all API routes
  • Configures error handling
  • Serves static files (uploads)

package.json

Purpose: Project configuration

  • Lists all dependencies
  • Defines npm scripts (start, dev)
  • Sets "type": "module" for ES6 support

.env

Purpose: Environment variables (sensitive data)

  • Database connection string
  • JWT secret key
  • Email configuration
  • Port number

jsconfig.json

Purpose: JavaScript/TypeScript configuration

  • Enables ES6 module resolution
  • Enforces consistent file name casing
  • Provides better IDE support

📂 Database/

connection.js

Purpose: MongoDB connection handler

  • Uses Mongoose to connect to MongoDB
  • Handles connection errors
  • Exits process if connection fails
const connectDB = async () => {
    await mongoose.connect(process.env.MONGO_URI);
};

📂 Models/

Contains all Mongoose schemas and models.

user.model.js

Purpose: User schema for all users (Admin, Doctor, Patient)

  • Fields: userName, email, password, role, status, phone
  • Hooks: Pre-save hook to hash passwords with bcrypt
  • Methods: matchPassword() to compare passwords
  • Roles: Admin, Doctor, Patient
  • Status: Pending, Active, Blocked

doctor.model.js

Purpose: Doctor profile information

  • Fields: user (ref to User), specialty, bio, experience, consultationFee, availability
  • Availability: Array of days with time slots
  • Relationships: References User model

patient.model.js

Purpose: Patient profile information

  • Fields: user (ref to User), dateOfBirth, gender, address, medicalHistory
  • Relationships: References User model

appointment.model.js

Purpose: Appointment booking data

  • Fields: patient, doctor, appointmentDate, timeSlot, status, notes, reason
  • Status: Pending, Confirmed, Completed, Cancelled
  • Relationships: References User and Doctor models

📂 Middlewares/

Contains Express middleware functions.

auth.js

Purpose: Authentication & Authorization

  • protect: Verifies JWT token from Authorization header
    • Extracts token from "Bearer "
    • Verifies token with JWT_SECRET
    • Attaches user to req.user
    • Returns 401 if invalid
  • authorize(...roles): Checks if user has required role
    • Returns 403 if unauthorized role

validate.js

Purpose: Input validation using Joi

  • Takes a Joi schema as parameter
  • Validates req.body against schema
  • Returns 400 with error messages if validation fails

errorHandler.js

Purpose: Global error handler

  • Catches all errors from routes
  • Returns consistent error response format
  • Shows stack trace in development mode

notFound.js

Purpose: 404 handler for undefined routes

  • Creates error with 404 status
  • Passes to error handler

upload.js

Purpose: File upload configuration with Multer

  • Configures storage (saves to uploads/ folder)
  • Generates unique filenames
  • Filters file types (only images: jpeg, jpg, png, gif)
  • Sets file size limit (5MB)

📂 Utils/

Contains utility/helper functions.

generateToken.js

Purpose: JWT token generation

  • Takes user ID as parameter
  • Signs token with JWT_SECRET
  • Sets expiration time (default 30 days)
  • Returns signed token string

sendEmail.js

Purpose: Email sending with Nodemailer

  • Configures SMTP transporter
  • Sends HTML emails
  • Used for welcome emails and appointment confirmations

imageProcessor.js

Purpose: Image processing with Sharp

  • Resizes images to specified dimensions
  • Compresses images (JPEG quality)
  • Deletes original file after processing
  • Returns processed file path

📂 Modules/

Feature-based modules (each domain has its own folder).

📂 Modules/user/

user.model.js: User schema (duplicate of Models/user.model.js for module organization)

user.validation.js: Joi validation schemas

  • registerValidation: Validates registration data
  • loginValidation: Validates login credentials

user.controller.js: User business logic

  • register: Creates new user, hashes password, sends welcome email, returns JWT
  • login: Validates credentials, checks if blocked, returns JWT
  • getProfile: Returns authenticated user's profile

user.routes.js: User API routes

  • POST /api/users/register - Register (with validation)
  • POST /api/users/login - Login (with validation)
  • GET /api/users/profile - Get profile (protected)

📂 Modules/doctor/

doctor.model.js: Doctor schema (duplicate of Models/doctor.model.js)

doctor.controller.js: Doctor business logic

  • createDoctorProfile: Creates doctor profile (Doctor role only)
  • getDoctors: Lists all doctors with optional specialty filter
  • setAvailability: Updates doctor's available time slots

doctor.routes.js: Doctor API routes

  • POST /api/doctors/profile - Create profile (Doctor only)
  • GET /api/doctors - List doctors (public)
  • PUT /api/doctors/availability - Set availability (Doctor only)

📂 Modules/appointment/

appointment.model.js: Appointment schema

appointment.controller.js: Appointment business logic

  • bookAppointment: Books appointment, checks availability, sends email
  • getAppointments: Lists appointments (filtered by role)
  • updateAppointmentStatus: Updates status and notes (Doctor/Admin)

appointment.routes.js: Appointment API routes

  • POST /api/appointments - Book appointment (Patient only)
  • GET /api/appointments - List appointments (role-based filtering)
  • PUT /api/appointments/:id - Update status (Doctor/Admin)

📂 Modules/admin/

admin.controller.js: Admin business logic

  • getAllUsers: Lists all users (without passwords)
  • updateUserStatus: Changes user status (Active/Blocked/Pending)
  • getAllAppointments: Lists all appointments with populated data

admin.routes.js: Admin API routes

  • GET /api/admin/users - List all users (Admin only)
  • PUT /api/admin/users/:id/status - Update user status (Admin only)
  • GET /api/admin/appointments - List all appointments (Admin only)

📂 Modules/patient/

patient.model.js: Patient schema (for future patient-specific features)


🗄️ Database Models

User Model

{
  userName: String (3-20 chars),
  email: String (unique, lowercase),
  password: String (hashed, min 6 chars),
  role: Enum ['Admin', 'Doctor', 'Patient'],
  status: Enum ['Pending', 'Active', 'Blocked'],
  phone: String,
  timestamps: true
}

Doctor Model

{
  user: ObjectId (ref: User),
  specialty: String (required),
  bio: String (max 500 chars),
  experience: Number (years),
  consultationFee: Number (required),
  availability: [{
    day: Enum [Monday-Sunday],
    slots: [{
      startTime: String,
      endTime: String,
      isBooked: Boolean
    }]
  }],
  timestamps: true
}

Appointment Model

{
  patient: ObjectId (ref: User),
  doctor: ObjectId (ref: Doctor),
  appointmentDate: Date (required),
  timeSlot: {
    startTime: String,
    endTime: String
  },
  status: Enum ['Pending', 'Confirmed', 'Completed', 'Cancelled'],
  notes: String,
  reason: String (required),
  timestamps: true
}

🔐 Authentication & Authorization

How Authentication Works

  1. Registration/Login:

    • User sends credentials
    • Server validates and creates/finds user
    • Server generates JWT token with user ID
    • Token sent back to client
  2. Protected Routes:

    • Client sends token in header: Authorization: Bearer <token>
    • protect middleware verifies token
    • User data attached to req.user
    • Request proceeds to controller
  3. Role-Based Access:

    • authorize('Admin', 'Doctor') checks user role
    • Returns 403 if role not allowed

Token Structure

{
  id: "user_mongodb_id",
  iat: 1234567890,  // issued at
  exp: 1234567890   // expiration
}

🚀 Setup & Installation

Prerequisites

  • Node.js (v14+)
  • MongoDB (local or Atlas)
  • npm or yarn

Installation Steps

# 1. Clone/Download project
cd project

# 2. Install dependencies
npm install

# 3. Create .env file
cp .env.example .env
# Edit .env with your values

# 4. Start MongoDB (if local)
mongod

# 5. Run development server
npm run dev

# 6. Server runs on http://localhost:3000

🔧 Environment Variables

Create a .env file in the root:

# Server Configuration
PORT=3000
NODE_ENV=development

# Database
MONGO_URI=mongodb://localhost:27017/medicalClinicDB

# JWT Configuration
JWT_SECRET=your_super_secret_key_here_change_in_production
JWT_EXPIRE=30d

# Email Configuration (Gmail example)
EMAIL_SERVICE=gmail
EMAIL_USER=your-email@gmail.com
EMAIL_PASS=your-app-specific-password

Getting Gmail App Password

  1. Enable 2-Factor Authentication on Gmail
  2. Go to Google Account → Security → App Passwords
  3. Generate password for "Mail"
  4. Use generated password in EMAIL_PASS

📝 Usage Examples

1. Register a New User

POST http://localhost:3000/api/users/register
Content-Type: application/json

{
  "userName": "John Doe",
  "email": "john@example.com",
  "password": "password123",
  "role": "Patient",
  "phone": "1234567890"
}

Response:

{
  "success": true,
  "data": {
    "_id": "65abc123...",
    "userName": "John Doe",
    "email": "john@example.com",
    "role": "Patient",
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}

2. Login

POST http://localhost:3000/api/users/login
Content-Type: application/json

{
  "email": "john@example.com",
  "password": "password123"
}

Response:

{
  "success": true,
  "data": {
    "_id": "65abc123...",
    "userName": "John Doe",
    "email": "john@example.com",
    "role": "Patient",
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}

3. Get User Profile (Protected)

GET http://localhost:3000/api/users/profile
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Response:

{
  "success": true,
  "data": {
    "_id": "65abc123...",
    "userName": "John Doe",
    "email": "john@example.com",
    "role": "Patient",
    "status": "Active",
    "phone": "1234567890"
  }
}

4. Create Doctor Profile (Doctor Only)

POST http://localhost:3000/api/doctors/profile
Authorization: Bearer <doctor_token>
Content-Type: application/json

{
  "specialty": "Cardiology",
  "bio": "Experienced cardiologist with 10 years of practice",
  "experience": 10,
  "consultationFee": 100
}

5. Set Doctor Availability

PUT http://localhost:3000/api/doctors/availability
Authorization: Bearer <doctor_token>
Content-Type: application/json

{
  "availability": [
    {
      "day": "Monday",
      "slots": [
        { "startTime": "09:00", "endTime": "10:00", "isBooked": false },
        { "startTime": "10:00", "endTime": "11:00", "isBooked": false }
      ]
    },
    {
      "day": "Tuesday",
      "slots": [
        { "startTime": "14:00", "endTime": "15:00", "isBooked": false }
      ]
    }
  ]
}

6. Get All Doctors (Public)

GET http://localhost:3000/api/doctors
# Optional: Filter by specialty
GET http://localhost:3000/api/doctors?specialty=Cardiology

Response:

{
  "success": true,
  "data": [
    {
      "_id": "65abc456...",
      "user": {
        "_id": "65abc123...",
        "userName": "Dr. Smith",
        "email": "smith@example.com",
        "phone": "9876543210"
      },
      "specialty": "Cardiology",
      "bio": "Experienced cardiologist...",
      "experience": 10,
      "consultationFee": 100,
      "availability": [...]
    }
  ]
}

7. Book Appointment (Patient Only)

POST http://localhost:3000/api/appointments
Authorization: Bearer <patient_token>
Content-Type: application/json

{
  "doctorId": "65abc456...",
  "appointmentDate": "2024-03-15",
  "timeSlot": {
    "startTime": "09:00",
    "endTime": "10:00"
  },
  "reason": "Regular checkup"
}

8. Get Appointments (Role-based)

GET http://localhost:3000/api/appointments
Authorization: Bearer <token>
  • Patient: Returns only their appointments
  • Doctor: Returns appointments for that doctor
  • Admin: Returns all appointments

9. Update Appointment Status (Doctor/Admin)

PUT http://localhost:3000/api/appointments/65abc789...
Authorization: Bearer <doctor_or_admin_token>
Content-Type: application/json

{
  "status": "Confirmed",
  "notes": "Patient confirmed via phone"
}

10. Admin: Get All Users

GET http://localhost:3000/api/admin/users
Authorization: Bearer <admin_token>

11. Admin: Update User Status

PUT http://localhost:3000/api/admin/users/65abc123.../status
Authorization: Bearer <admin_token>
Content-Type: application/json

{
  "status": "Blocked"
}

🔒 Security Features

  1. Password Hashing: Bcrypt with salt rounds (10)
  2. JWT Tokens: Signed with secret key, expiration time
  3. Role-Based Access: Middleware checks user roles
  4. Input Validation: Joi validates all inputs
  5. Status Management: Can block malicious users
  6. CORS: Configured for cross-origin requests
  7. Error Handling: Doesn't expose sensitive info

📊 API Response Format

Success Response

{
  "success": true,
  "data": { ... }
}

Error Response

{
  "success": false,
  "message": "Error description",
  "errors": ["Validation error 1", "Validation error 2"]
}

🧪 Testing the API

Using Postman

  1. Import collection (create one with all endpoints)
  2. Set environment variable for token
  3. Test each endpoint

Using cURL

# Register
curl -X POST http://localhost:3000/api/users/register \
  -H "Content-Type: application/json" \
  -d '{"userName":"Test","email":"test@test.com","password":"123456"}'

# Login
curl -X POST http://localhost:3000/api/users/login \
  -H "Content-Type: application/json" \
  -d '{"email":"test@test.com","password":"123456"}'

🐛 Common Issues & Solutions

Issue: "Database Connection Failed"

Solution: Check MongoDB is running and MONGO_URI is correct

Issue: "Not authorized, no token"

Solution: Include Authorization: Bearer <token> header

Issue: "Email sending failed"

Solution: Check EMAIL_USER and EMAIL_PASS in .env

Issue: "Port already in use"

Solution: Change PORT in .env or kill process using port


📚 Additional Resources


🎓 Learning Path

  1. Understand Express basics: Routes, middleware, request/response
  2. Learn MongoDB & Mongoose: Schemas, models, queries
  3. Study JWT authentication: Token generation, verification
  4. Practice API testing: Postman, cURL
  5. Explore advanced topics: File uploads, email, validation

📞 Support

For questions or issues:

  1. Check this documentation
  2. Review code comments
  3. Test with Postman
  4. Check console logs for errors

Last Updated: February 2024 Version: 1.0.0