Skip to content

lethib/my_patients

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

71 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

My Patients Logo

My Patients

A secure patient management system for healthcare practitioners

Modern, privacy-focused application for managing patient records and generating professional invoices.

Features β€’ Tech Stack β€’ Getting Started β€’ Development β€’ Deployment


πŸ“– About

My Patients is a full-stack web application designed to help healthcare practitioners manage their patient records securely. Built with a focus on data privacy and security, it provides encrypted storage for sensitive patient information including social security numbers, along with automated invoice generation capabilities.

This is a personal project built to explore modern web technologies including Rust backend development and secure cryptographic practices.

✨ Features

Patient Management

  • Secure Patient Records - Store patient information with AES-GCM encryption for sensitive data
  • SSN Protection - Double-layer security with encrypted storage and hashed indexing for fast, secure lookups
  • Multi-Office Support - Manage patients across multiple practitioner offices

Invoice Generation

  • PDF Invoices - Generate professional PDF invoices with native Rust PDF generation
  • Digital Signatures - Add practitioner signatures to invoices
  • Business Information - Complete practitioner business details integration

πŸ› οΈ Tech Stack

Backend

  • Rust - Systems programming language for performance and safety
  • Loco - Rails-inspired web framework for Rust
  • SeaORM - Async ORM for database operations
  • PostgreSQL - Primary database (SQLite supported for development)

Frontend

Security & Encryption

  • AES-GCM - Symmetric encryption for sensitive data
  • Argon2 - Password hashing
  • Base64 - Encoding for encrypted data

DevOps

  • Docker - Multi-stage optimized builds
  • Google Cloud Run - Serverless container deployment
  • Distroless Images - Minimal attack surface for production

πŸš€ Getting Started

Prerequisites

  • Rust 1.88+ (Install)
  • Bun (Install)
  • PostgreSQL 15+ or SQLite for development
  • Docker (optional, for containerized deployment)

Environment Setup

Create a .env file in the root directory:

# Database
DATABASE_URL=postgres://user:password@localhost:5432/my_patients

# Encryption Keys (generate secure random keys)
ENCRYPTION_KEY=your-32-byte-base64-encoded-key
SSN_SALT_KEY=your-secure-salt-key

# JWT
JWT_SECRET=your-jwt-secret-key

# Supabase Storage (optional, for invoice storage)
SUPABASE_URL=your-supabase-url
SUPABASE_KEY=your-supabase-key
SUPABASE_BUCKET=your-bucket-name

Installation

  1. Clone the repository
git clone https://github.com/yourusername/my_patients.git
cd my_patients
  1. Install backend dependencies
cargo build
  1. Install frontend dependencies
cd frontend
bun install
  1. Run database migrations
cargo loco db migrate
  1. Start the development servers

In one terminal (backend):

cargo loco start

In another terminal (frontend):

cd frontend
bun run dev

The application will be available at http://localhost:5173 (frontend) with API at http://localhost:5150 (backend).

πŸ’» Development

Project Structure

my_patients/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ app.rs              # Application setup & routing
β”‚   β”œβ”€β”€ controllers/        # HTTP request handlers
β”‚   β”œβ”€β”€ models/             # Database models & business logic
β”‚   β”œβ”€β”€ services/           # Business services (crypto, invoice, etc.)
β”‚   β”œβ”€β”€ validators/         # Request validation logic
β”‚   β”œβ”€β”€ workers/            # Background job workers
β”‚   └── middlewares/        # Custom middleware
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ routes/         # TanStack Router routes
β”‚   β”‚   β”œβ”€β”€ components/     # React components
β”‚   β”‚   β”œβ”€β”€ api/            # API client & types
β”‚   β”‚   β”œβ”€β”€ hooks/          # Custom React hooks
β”‚   β”‚   └── i18n/           # Translations
β”‚   └── public/             # Static assets
β”œβ”€β”€ migration/              # Database migrations
β”œβ”€β”€ config/                 # Environment configurations
└── dockerfile              # Multi-stage production build

Database Migrations

Create a new migration:

cargo loco db generate migration_name

Run migrations:

cargo loco db migrate

Rollback last migration:

cargo loco db down

Code Quality

Backend linting:

cargo clippy
cargo fmt

Frontend linting:

cd frontend
bun run lint

Testing

Run Rust tests:

cargo test

🚒 Deployment

Docker Build

The project includes an optimized multi-stage Dockerfile:

# Build the image
docker build -t my-patients .

# Run the container
docker run -p 5150:5150 --env-file .env my-patients

The Dockerfile uses:

  • cargo-chef for faster Rust dependency caching
  • Bun for fast frontend builds
  • Distroless base image for minimal attack surface
  • Multi-stage builds for optimal layer caching

Building the Docker Image

Using the dockerfile file, you can build your Docker container image.

From the oven/bun image, build the frontend. β†’ Apple users: disable the Use Rosetta for x86_64/amd64 emulation on Apple Silicon from the Docker Desktop settings. We will build a linux/amd64 image and its seems that tailwind has issues with Apple Rosetta to build our CSS.

From the rust image, build the backend. Then copy all the files from the frontend and backend builds into a new distroless/cc-debian12 image.

⚠️ Backend configuration:

  • localhost won't work for the host in production as you will access the service from outside the container (with a ping on the domain name that will point to the container). Thus the host must be 0.0.0.0.
  • For the CORS configuration, you can set the Access-Control-Allow-Origin header to * or to your Google Cloud Run domain (as it is Client Side Rendering).

⚠️ Backend build:

  • When running a simple cargo run --release, the binary is built for the host architecture. If you want to build it for a specific target, you can use cargo build --release --target x86_64-unknown-linux-gnu (or any other target). Google Cloud Run uses x86_64-unknown-linux-gnu as the target architecture, so you should build your binary for that target.
  • The docker image architecture must be a linux/amd64 image. When running a simple docker build . -t test, it will build the image for the host architecture. If you want to build it for a specific target, you can use docker build . -t test --platform linux/amd64 (or any other target).

Deploying on Google Cloud Run

Prerequisites: your docker image must be pulled on a public or private registry accessible by Google Cloud Run. For instance, you can use Docker Hub (just push your built image to your Docker Hub account).

To deploy your application on Google Cloud Run, visit the Google Cloud Console and follow these steps:

  • Create a global project if you don't have one.
  • Enable the Cloud Run API.
  • Visit the Cloud Run page and click on "Deploy a container".

Service Configuration:

  • Container image URL: the URL of your Docker image (e.g., your-id/your-image-name).
  • Service name: the name of your service (e.g., my-app).
  • Region: select the region where you want to deploy your service (e.g., europe-west9).
  • Authentication: If you want to use JWT authentication, you can allow unauthenticated invocations.
  • Billing: First option, serverless, is the best option for small applications.

Then proceed to the container configuration.

Container Configuration:

  • Container port: set the Google Cloud Run default port (8080). ⚠️ The server.port value must be read from the PORT Google Cloud Run env variable. Otherwise, you app would not be able to restart properly after a cold start. To do that change the hardcoded from to {{ get_env(name="PORT", default="5150") }}.
  • Environment variables: you can set environment variables for your application (e.g., DATABASE_URL, JWT_SECRET, LOCO_ENV etc.).
  • Health checks: you can enable health checks to ensure your service is running correctly. In our case, select HTTP and the path to your health check endpoint. Don't forget to add a small delay because your application might take some time to start up (e.g., 10 seconds).

Then proceed to the last steps.

  • Revision scaling: reduce the number of instances to 3 (can be changed later to upgrade)

πŸ”’ Security Considerations

This project is provided as-is for educational and personal use.

About

πŸ₯ΌπŸ©Ί A secure patient management system for healthcare practitioners

Topics

Resources

Stars

Watchers

Forks