Skip to content

Latest commit

ย 

History

85 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Health Care Management System โ€” FastAPI Backend

A modern, robust healthcare management API built with FastAPI โ€” delivering secure, scalable, and efficient healthcare services with real-time notifications.

๐Ÿš€ Quick Start with Docker

Prerequisites

  • Docker & Docker Compose
  • Python 3.11+ (for local development)

Production Deployment

cp .env.example .env   # then set real passwords and SECRET_KEY
docker compose up --build -d

The API will be available at: http://localhost:8000 API Documentation: http://localhost:8000/docs

Set FIRST_ADMIN_EMAIL / FIRST_ADMIN_PASSWORD in .env to have an admin account created on first startup.


๐Ÿ—๏ธ Tech Stack

Backend & API

FastAPI Python SQLAlchemy Pydantic

Database & Caching

PostgreSQL Redis RabbitMQ

Infrastructure & DevOps

Docker Docker Compose JWT


๐Ÿ“ Project Structure

.
โ”œโ”€โ”€ app/
โ”‚   โ”œโ”€โ”€ api/
โ”‚   โ”‚   โ”œโ”€โ”€ routes/           # API endpoint handlers
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ auth.py
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ user.py
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ patient.py
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ doctor.py
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ appointment.py
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ medical_record.py
โ”‚   โ”‚   โ””โ”€โ”€ deps.py           # Auth and role dependencies
โ”‚   โ”œโ”€โ”€ core/                 # Core application logic
โ”‚   โ”‚   โ”œโ”€โ”€ config.py         # Configuration management
โ”‚   โ”‚   โ”œโ”€โ”€ security.py       # JWT and password hashing
โ”‚   โ”‚   โ”œโ”€โ”€ cache.py          # Redis response caching middleware
โ”‚   โ”‚   โ”œโ”€โ”€ rate_limiter.py   # Redis rate limiting middleware
โ”‚   โ”‚   โ”œโ”€โ”€ notifications.py  # Publishes appointment events to RabbitMQ
โ”‚   โ”‚   โ””โ”€โ”€ timeutils.py      # UTC normalization
โ”‚   โ”œโ”€โ”€ crud/                 # Database operations layer
โ”‚   โ”œโ”€โ”€ db/                   # SQLAlchemy models and session
โ”‚   โ”œโ”€โ”€ schemas/              # Pydantic schemas
โ”‚   โ””โ”€โ”€ tests/                # Test suites
โ”œโ”€โ”€ docker-compose.yml        # Multi-service orchestration
โ”œโ”€โ”€ Dockerfile                # API container
โ”œโ”€โ”€ Dockerfile.notification   # Notification worker container
โ”œโ”€โ”€ notification_service.py   # Async notification worker (RabbitMQ โ†’ email)
โ”œโ”€โ”€ API_EXAMPLES.http         # Example requests
โ””โ”€โ”€ .env.example              # Environment template

๐Ÿณ Docker Services

The system runs as a multi-container application. Only the API port is published; the other services are reachable on the internal network.

Service Purpose Port Health Check
app FastAPI Application 8000 HTTP 200 on /health
notification Email notification worker โ€“ Restarts on failure
db PostgreSQL Database 5432 (internal) pg_isready
redis Cache and rate limiting 6379 (internal) redis-cli ping
rabbitmq Message Queue 5672 (internal) rabbitmq-diagnostics ping

๐Ÿ› ๏ธ Getting Started

Option 1: Docker (Recommended)

# Production deployment
docker compose up --build -d

# View logs
docker compose logs -f app notification

# Stop services
docker compose down

Option 2: Local Development

# Create virtual environment
python -m venv .venv
source .venv/bin/activate  # Linux/Mac
# OR
.\.venv\Scripts\Activate.ps1  # Windows

# Install dependencies
pip install -r requirements-dev.txt

# Point the app at your services (or put these in .env)
export DATABASE_URL=postgresql://user:pass@localhost:5432/healthcare
export SECRET_KEY=dev-secret

# Run the application
uvicorn app.main:app --reload --host 127.0.0.1 --port 8000

Redis and RabbitMQ are optional locally: caching and rate limiting fail open, and notifications are logged as errors when RabbitMQ is unreachable. Disable them with CACHE_ENABLED=false, RATE_LIMIT_ENABLED=false and NOTIFICATIONS_ENABLED=false.


๐Ÿ“œ Available Commands

Docker Commands

Command Description
docker compose up --build -d Build and start all services
docker compose logs -f [service] Follow service logs
docker compose down Stop and remove containers
docker compose exec app [cmd] Execute command in app container

Development Commands

Command Description
uvicorn app.main:app --reload Start development server
pytest -q Run test suite quietly
pytest -v Run tests with verbose output
pytest --cov=app Run tests with coverage

๐ŸŽฏ Core Features

  • ๐Ÿ” Secure Authentication โ€“ JWT (HS256) bearer tokens, bcrypt password hashing
  • ๐Ÿ‘ฅ Role-Based Access Control โ€“ Patient, Doctor, Staff and Admin roles
  • ๐Ÿ“… Appointment Management โ€“ Availability windows, conflict detection, free slot lookup, rescheduling and cancellation
  • ๐Ÿฉบ Medical Records โ€“ Doctor-authored records, readable by the patient
  • โšก Real-time Notifications โ€“ Appointment events published to RabbitMQ and emailed by a worker
  • ๐Ÿ’พ Caching โ€“ Per-user Redis response caching, invalidated on writes
  • ๐Ÿš€ Rate Limiting โ€“ Per-IP request throttling
  • ๐Ÿ“Š Health Checks โ€“ Container and service health monitoring

API Overview

Prefix Endpoints
/api/auth POST /login, POST /register, GET /me
/api/users Admin user management: list, get, update (role, active flag, linked profile)
/api/patients CRUD, GET /me, GET /search?query=
/api/doctors CRUD, GET /specialization/{name}, POST/DELETE /{id}/availability
/api/appointments CRUD, PUT /{id}/status?status=, GET /doctor/{id}/available-slots?date=
/api/medical-records CRUD, GET /patient/{patient_id}

All scheduling times are UTC. Timestamps with an offset are converted; timestamps without one are treated as UTC. Doctor availability is a weekly window (day_of_week 0 = Monday) and slots are 30 minutes.

Roles

User accounts link to a patient or doctor profile through reference_id.

Role Access
Patient Registers publicly, creates and edits their own profile, books/reschedules/cancels their own appointments, reads their own medical records
Doctor Reads patients, manages their own profile, availability and appointment statuses, creates and edits medical records
Staff Manages patients, doctors and all appointments; no medical record access
Admin Everything, including user management and creating non-patient accounts via /api/auth/register

๐Ÿ“ฆ Key Dependencies

  • fastapi, uvicorn โ€“ Web framework and ASGI server
  • pydantic, pydantic-settings, email-validator โ€“ Validation and settings
  • sqlalchemy, psycopg2-binary โ€“ ORM and PostgreSQL driver
  • PyJWT, bcrypt โ€“ Tokens and password hashing
  • redis โ€“ Caching and rate limiting
  • aio-pika โ€“ RabbitMQ publisher (API) and consumer (worker)
  • aiosmtplib โ€“ Email delivery (worker)
  • pytest, pytest-cov, httpx โ€“ Testing (requirements-dev.txt)

โš™๏ธ Configuration

Environment Variables

# Used by docker-compose.yml
DB_PASSWORD=your_secure_password
RABBITMQ_USER=admin
RABBITMQ_PASSWORD=your_rabbitmq_password
SECRET_KEY=your_jwt_secret_key          # required when ENVIRONMENT=production

# Read by the app (compose sets these from the values above)
DATABASE_URL=postgresql://user:pass@db:5432/healthcare_db
REDIS_URL=redis://redis:6379/0
RABBITMQ_URL=amqp://user:pass@rabbitmq:5672/
ACCESS_TOKEN_EXPIRE_MINUTES=30
CACHE_ENABLED=true
RATE_LIMIT_ENABLED=true
RATE_LIMIT_PER_MINUTE=60
NOTIFICATIONS_ENABLED=true
FIRST_ADMIN_EMAIL=admin@example.com
FIRST_ADMIN_PASSWORD=change-me-please

# Notification worker (leave SMTP_SERVER empty to log emails instead of sending)
SMTP_SERVER=smtp.example.com
SMTP_PORT=587
SMTP_USERNAME=
SMTP_PASSWORD=
EMAIL_FROM=noreply@example.com

Configuration Files

  • app/core/config.py โ€“ Centralized configuration management
  • docker-compose.yml โ€“ Service orchestration
  • Dockerfile โ€“ Application container definition
  • Dockerfile.notification โ€“ Worker container definition

๐Ÿš€ Deployment

Production with Docker Compose

  1. Copy .env.example to .env and set real values
  2. Run docker compose up --build -d
  3. Access API at http://your-server:8000
  4. Monitor services with docker compose logs -f

Tables are created automatically on startup. There are no migrations yet, so schema changes to an existing database must be applied manually.

Health Checks

  • API: GET /health
  • Database, Redis, RabbitMQ: automatic health checks in compose

โšก Performance & Security

  • Multi-stage Docker builds for optimized image sizes
  • Non-root user execution for enhanced security
  • Connection pooling with pre-ping for database efficiency
  • Request rate limiting to prevent abuse
  • JWT token expiration for session security
  • Password length validation (8โ€“72 bytes) with bcrypt hashing

๐Ÿงช Testing

Tests use a throwaway SQLite database by default and never read DATABASE_URL. Set TEST_DATABASE_URL to run them against PostgreSQL (CI does this).

# Run all tests
pytest

# Run with coverage
pytest --cov=app --cov-report=html

# Run specific test module
pytest app/tests/test_api.py -v

# Against PostgreSQL (the database is dropped and recreated)
TEST_DATABASE_URL=postgresql://test:test@localhost:5432/test pytest

๐Ÿค Contributing

  1. Fork the repository
  2. Create your feature branch
    git checkout -b feature/amazing-feature
  3. Commit your changes
    git commit -m 'Add amazing feature'
  4. Push to the branch
    git push origin feature/amazing-feature
  5. Open a Pull Request

๐Ÿ“„ License

This project is licensed under the MIT License. See the LICENSE file for more information.


๐Ÿ“ฎ Booking Example

curl:

curl -X POST http://localhost:8000/api/appointments/ \
  -H "Authorization: Bearer <token_jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "patient_id": 1,
    "doctor_id": 2,
    "start_time": "2030-12-03T10:00:00",
    "end_time": "2030-12-03T10:30:00",
    "notes": "Consulta preventiva"
  }'

Python:

import requests

url = "http://localhost:8000/api/appointments/"
headers = {"Authorization": "Bearer <token_jwt>"}
payload = {
    "patient_id": 1,
    "doctor_id": 2,
    "start_time": "2030-12-03T10:00:00",
    "end_time": "2030-12-03T10:30:00",
    "notes": "Consulta preventiva",
}
response = requests.post(url, json=payload, headers=headers)
print(response.status_code, response.json())

See API_EXAMPLES.http for more requests.


๐Ÿฅ Built with โค๏ธ for Modern Healthcare Management

Delivering secure, scalable healthcare APIs with cutting-edge technology.