Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🏥 MediBook — Healthcare Appointment Platform

Backend Engineer Assignment — Scalable healthcare appointment booking system using Spring Boot + Python + RabbitMQ + PostgreSQL + React


🏗 Architecture

┌─────────────────────────────────────────────────────────────┐
│              React Frontend (Vite + TypeScript)              │
│         Login · Book · History · Live Event Feed            │
└──────────────────────────┬──────────────────────────────────┘
                           │ REST API (HTTP + JWT)
                           ▼
┌─────────────────────────────────────────────────────────────┐
│         Spring Boot Backend  :8080                          │
│   Auth · Appointments · Slots · Event Publisher             │
│   PostgreSQL JPA · Swagger UI · JWT Security                │
└──────────────────────────┬──────────────────────────────────┘
                           │ Publish events
                           ▼
┌─────────────────────────────────────────────────────────────┐
│      RabbitMQ  :5672  (Management UI :15672)                │
│   appointment.created  ·  appointment.cancelled             │
└──────────────────────────┬──────────────────────────────────┘
                           │ Consume events
                           ▼
┌─────────────────────────────────────────────────────────────┐
│         Python Worker  :8001                                │
│   Consumes events → Simulates Notification → Updates Status │
│   FastAPI health endpoint · SQLAlchemy DB logs              │
└─────────────────────────────────────────────────────────────┘

⚡ Quick Start (Docker)

# Clone / open project
cd healthcare-platform

# Start all 5 services with one command
docker-compose up --build

# Access:
#   Frontend:           http://localhost:3000
#   Backend API:        http://localhost:8080
#   Swagger UI:         http://localhost:8080/swagger-ui.html
#   RabbitMQ Mgmt UI:  http://localhost:15672  (guest/guest)
#   Python Worker:      http://localhost:8001/health

⏳ First build takes ~3-5 minutes (Maven downloads dependencies). Subsequent builds are fast.


🛠 Tech Stack

Layer Technology
Backend Core Spring Boot 3.2 (Java 17)
Worker Service Python 3.11 + FastAPI
Messaging RabbitMQ 3.13
Database PostgreSQL 15
Frontend Vite + React 18 + TypeScript
Auth JWT (jjwt 0.12.5) + BCrypt
API Docs SpringDoc OpenAPI (Swagger)
Containerization Docker + Docker Compose

📋 API Reference

Auth (Public)

Method Endpoint Description
POST /api/auth/register Register new user
POST /api/auth/login Login → returns JWT

Slots (JWT Required)

Method Endpoint Description
GET /api/slots/doctors List all doctors
GET /api/slots/available?doctorId=&date= Available slots for doctor+date

Appointments (JWT Required)

Method Endpoint Description
POST /api/appointments Book appointment {"slotId": 1}
DELETE /api/appointments/{id} Cancel appointment
GET /api/appointments/my My appointments + logs
GET /api/appointments/{id} Appointment detail

Internal (Python Worker)

Method Endpoint Description
PUT /api/internal/appointments/status Update appointment status

🔄 End-to-End Flow

1. User registers/logs in → gets JWT
2. Frontend fetches available slots → selects doctor + date + time
3. User books appointment → Spring Boot saves to DB (status: PENDING)
4. Spring Boot publishes "appointment.created" event to RabbitMQ
5. Python worker consumes event → logs notification to console + DB
6. Python worker calls Spring Boot /api/internal/appointments/status
7. Appointment status updated to CONFIRMED in DB
8. Frontend Live Event Feed picks up status change (polls every 4s)
9. User sees real-time: PENDING → CONFIRMED

🗄 Database Schema

users          (id, name, email, password_hash, role, created_at)
doctors        (id, name, specialization)
slots          (id, doctor_id, slot_date, slot_time, is_booked)  -- UNIQUE(doctor_id, date, time)
appointments   (id, user_id, slot_id, status, created_at, updated_at)  -- UNIQUE(slot_id)
appointment_logs (id, appointment_id, event_type, notes, created_at)

🔐 Security

  • JWT Authentication: Bearer token required for all protected endpoints
  • Password Hashing: BCrypt (Spring Security)
  • Duplicate Booking Prevention: DB UNIQUE constraint on slot_id + Pessimistic Locking (SELECT ... FOR UPDATE)
  • CORS: Configured for localhost:3000
  • Input Validation: Bean Validation (@NotNull, @Email, etc.)

🐍 Python Worker Details

The Python worker (python-worker/) is an independent service that:

  1. Connects to RabbitMQ with auto-retry (15 attempts × 5s)
  2. Subscribes to appointment.created and appointment.cancelled queues
  3. On appointment.created:
    • Simulates email notification (1.5s delay + console log)
    • Writes NOTIFICATION_SENT log to PostgreSQL
    • Calls Spring Boot /api/internal/appointments/status → sets CONFIRMED
  4. On appointment.cancelled:
    • Simulates cancellation notification
    • Writes log to DB
  5. Error handling: basic_nack(requeue=False) on failure (dead-letter)
  6. FastAPI: Health endpoint at :8001/health for Docker health checks

🌟 Bonus Features

  • Docker Compose — one-command startup with health checks
  • RabbitMQ Management UI — visual queue monitoring
  • Swagger UI — interactive API documentation
  • Slot Seeding — 5 doctors × 14 days × 7 time slots on startup
  • Live Event Feed — frontend polls and shows backend events in real-time
  • Appointment Logs — full audit trail in DB
  • Python Worker Auto-Restart — consumer thread auto-restarts on crash
  • Environment Variables — no hardcoded secrets

🧪 Development (Without Docker)

Backend

# Requires: Java 17+, Maven, running PostgreSQL + RabbitMQ

cd backend
mvn spring-boot:run
# → http://localhost:8080

Python Worker

cd python-worker
pip install -r requirements.txt
python main.py
# → http://localhost:8001

Frontend

cd frontend
npm install
npm run dev
# → http://localhost:3000

📁 Project Structure

healthcare-platform/
├── docker-compose.yml
├── README.md
├── backend/                    Spring Boot (Java 17)
│   ├── Dockerfile
│   ├── pom.xml
│   └── src/main/java/com/healthcare/
│       ├── config/             SecurityConfig, RabbitMQConfig, SwaggerConfig, DataSeeder
│       ├── controller/         AuthController, AppointmentController, SlotController, InternalController
│       ├── service/            AuthService, AppointmentService, SlotService, EventPublisherService
│       ├── repository/         JPA repositories with custom queries
│       ├── model/              User, Doctor, Slot, Appointment, AppointmentLog
│       ├── dto/                Request/Response DTOs + Event DTOs
│       ├── security/           JwtUtil, JwtFilter, UserDetailsServiceImpl
│       └── exception/          GlobalExceptionHandler
├── python-worker/              Python 3.11 + FastAPI
│   ├── Dockerfile
│   ├── main.py                 FastAPI app + thread management
│   ├── consumer.py             RabbitMQ event handlers
│   ├── notification.py         Notification simulation
│   └── db.py                   SQLAlchemy DB logging
└── frontend/                   Vite + React + TypeScript
    ├── Dockerfile
    ├── nginx.conf
    └── src/
        ├── App.tsx             Router + auth protection
        ├── context/            AuthContext
        ├── api/                Axios client + TypeScript types
        ├── components/         Navbar, AppointmentCard, EventStatusFeed
        └── pages/              Login, Register, Dashboard, Book, History

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages