Skip to content

Th-Shivam/HealthVault

Repository files navigation

πŸ₯ HealthVault

Your Secure Digital Health Locker - Manage, share, and control access to your medical records with ease.

React Vite Supabase Tailwind CSS Vercel


πŸ“‹ Table of Contents


🌟 Overview

HealthVault is a modern, secure digital health records management system that empowers patients to:

  • Upload and store medical documents securely
  • Share records with healthcare providers via OTP or QR code
  • Control and revoke access to their medical data
  • Track who accessed their records and when

Built with privacy and security at its core, HealthVault uses end-to-end encryption, temporary access tokens, and granular access controls to ensure your medical data remains strictly under your control.


✨ Features

πŸ‘€ Patient Features

  • πŸ” Secure Authentication - Email/password login with Supabase Auth
  • πŸ“€ Upload Medical Records - Support for PDFs, images (JPG, PNG)
  • πŸ”— Flexible Sharing Options:
    • OTP-based sharing - Generate 6-digit codes for doctors
    • QR code sharing - Instant access via QR scan
  • πŸ•’ Time-limited Access - All shared access expires automatically
  • ❌ Revoke Access - Instantly revoke doctor access at any time
  • πŸ“Š Access Logs - View who accessed your records and when
  • πŸ—‘οΈ Delete Records - Permanently remove records from the system
  • πŸ“§ Email Notifications - Real-time alerts when records are accessed

πŸ‘¨β€βš•οΈ Doctor Features

  • πŸ”“ Quick Access - Verify via OTP or QR code scan
  • πŸ“± Mobile-Friendly - QR scanner works on mobile devices
  • πŸ“„ View & Download - Access shared medical records
  • ⏱️ Session Management - Secure, time-limited access tokens
  • πŸ“– Read-Only Access - View records without modification rights

πŸ”’ Security Features

  • πŸ›‘οΈ Row-Level Security (RLS) - Database-level access control
  • πŸ”‘ JWT Authentication - Secure token-based authentication
  • πŸ” Encrypted Storage - Files stored in Supabase secure storage
  • πŸ“ Access Logging - Complete audit trail of all record access
  • ⏲️ Token Expiration - Auto-expiring access grants (15 minutes for doctors)
  • 🚫 No Data Leakage - Signed URLs expire after 1 hour

πŸ› οΈ Tech Stack

Frontend

  • React 19.2 - Modern React with Hooks
  • Vite 7.2 - Lightning-fast build tool
  • React Router 7.9 - Client-side routing
  • Tailwind CSS 3.4 - Utility-first CSS framework
  • React Hot Toast - Beautiful toast notifications
  • React QR Reader - QR code scanning
  • React QR Code - QR code generation

Backend

  • Vercel Serverless Functions - API routes
  • Supabase - Backend-as-a-Service
    • PostgreSQL database
    • Authentication
    • File storage
    • Row-Level Security (RLS)
  • JWT - JSON Web Tokens for doctor sessions
  • SendGrid - Email notifications

DevOps

  • Vercel - Hosting & CI/CD
  • GitHub - Version control
  • ESLint - Code linting

πŸ—οΈ Architecture

High-Level Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      Client (React SPA)                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Login   β”‚  β”‚Dashboard β”‚  β”‚  Share   β”‚  β”‚  Doctor  β”‚   β”‚
β”‚  β”‚  Signup  β”‚  β”‚  Upload  β”‚  β”‚  Record  β”‚  β”‚  Portal  β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
                            β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Vercel Serverless API Routes                    β”‚
β”‚  /api/upload-record    /api/generate-otp                    β”‚
β”‚  /api/get-records      /api/generate-qr                     β”‚
β”‚  /api/verify-otp       /api/verify-qr                       β”‚
β”‚  /api/revoke-access    /api/log-access                      β”‚
β”‚  /api/delete-record    /api/signed-url                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
                            β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Supabase Backend                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚  β”‚  PostgreSQL  β”‚  β”‚     Auth     β”‚  β”‚   Storage    β”‚     β”‚
β”‚  β”‚   Database   β”‚  β”‚   (Users)    β”‚  β”‚   (Files)    β”‚     β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚  Tables: records, grants, access_logs                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Database Schema

-- Records table
records (
  id          UUID PRIMARY KEY,
  patient_id  UUID REFERENCES auth.users(id),
  title       TEXT,
  description TEXT,
  file_url    TEXT,
  uploaded_at TIMESTAMP
)

-- Access grants table
grants (
  id           UUID PRIMARY KEY,
  patient_id   UUID REFERENCES auth.users(id),
  doctor_email TEXT,
  otp_hash     TEXT,
  qr_token     TEXT,
  expires_at   TIMESTAMP,
  is_active    BOOLEAN,
  records      JSONB,
  created_at   TIMESTAMP
)

-- Access logs table
access_logs (
  id          UUID PRIMARY KEY,
  grant_id    UUID REFERENCES grants(id),
  doctor_id   TEXT,
  record_id   UUID REFERENCES records(id),
  accessed_at TIMESTAMP
)

πŸš€ Getting Started

Prerequisites

  • Node.js 18+ and npm
  • Supabase account (supabase.com)
  • Vercel account (for deployment)

Installation

  1. Clone the repository
git clone https://github.com/Th-Shivam/HealthVault.git
cd HealthVault
  1. Install dependencies
npm install --legacy-peer-deps
  1. Set up environment variables

Create a .env file in the root directory:

# Frontend (Vite)
VITE_SUPABASE_URL=your_supabase_project_url
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key

# Backend (Serverless functions)
SUPABASE_URL=your_supabase_project_url
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key

# Email Notifications (SendGrid)
SENDGRID_API_KEY=your_sendgrid_api_key_here
  1. Set up Supabase database

Run the SQL commands in supabase_setup.sql:

# Copy the contents of supabase_setup.sql
# Paste and execute in Supabase SQL Editor
  1. Run development server
# For frontend only
npm run dev

# For full-stack (API routes + frontend)
npx vercel dev
  1. Access the application
http://localhost:3000

πŸ”§ Environment Setup

Supabase Configuration

  1. Create a new project at supabase.com
  2. Navigate to Settings β†’ API
  3. Copy the following values:
    • Project URL β†’ VITE_SUPABASE_URL and SUPABASE_URL
    • Anon/Public Key β†’ VITE_SUPABASE_ANON_KEY
    • Service Role Key β†’ SUPABASE_SERVICE_ROLE_KEY ⚠️ (Keep this secret!)

Storage Bucket Setup

  1. Go to Storage in Supabase dashboard
  2. Create a new bucket named medical-records
  3. Set it to Public (for now) or configure RLS policies
  4. Note: For production, use private buckets with signed URLs

SendGrid Configuration (Optional but Recommended)

  1. Create a free account at sendgrid.com
  2. Verify your sender email address
  3. Navigate to Settings β†’ API Keys
  4. Create a new API key with Full Access permissions
  5. Copy the API key to your .env file as SENDGRID_API_KEY
  6. Important: Replace noreply@healthvault.app in api/services/email-service.js with your verified sender email

Note: Without SendGrid configured, the app will work perfectly but email notifications will be skipped.


πŸ’Ύ Database Setup

Execute the following SQL in your Supabase SQL Editor:

# Run the complete setup script
cat supabase_setup.sql | supabase db reset

This creates:

  • βœ… records table with RLS policies
  • βœ… grants table with RLS policies
  • βœ… access_logs table with RLS policies
  • βœ… medical-records storage bucket
  • βœ… Storage policies for authenticated uploads

πŸ“‘ API Documentation

Patient APIs

POST /api/upload-record

Upload a medical record.

Request:

{
  "patient_id": "uuid",
  "title": "Blood Test Report",
  "description": "Annual checkup",
  "file": "base64_encoded_file",
  "file_name": "report.pdf"
}

Response:

{
  "success": true,
  "record_id": "uuid"
}

POST /api/generate-otp

Generate OTP for sharing records.

Request:

{
  "patient_id": "uuid",
  "doctor_email": "doctor@example.com",
  "record_ids": ["uuid1", "uuid2"]
}

Response:

{
  "success": true,
  "otp": "123456"
}

POST /api/generate-qr

Generate QR code token for sharing.

Request:

{
  "patient_id": "uuid",
  "record_ids": ["uuid1", "uuid2"]
}

Response:

{
  "success": true,
  "qr_token": "signed_token_string"
}

POST /api/revoke-access

Revoke doctor access to records.

Request:

{
  "grant_id": "uuid"
}

Response:

{
  "success": true
}

POST /api/delete-record

Delete a medical record (requires auth).

Headers:

Authorization: Bearer <supabase_access_token>

Request:

{
  "record_id": "uuid",
  "file_path": "path/to/file",
  "patient_id": "uuid"
}

Response:

{
  "success": true,
  "message": "Record deleted successfully"
}

Doctor APIs

POST /api/verify-otp

Verify OTP and get access token.

Request:

{
  "doctor_email": "doctor@example.com",
  "otp": "123456"
}

Response:

{
  "success": true,
  "token": "jwt_access_token"
}

POST /api/verify-qr

Verify QR token and get access.

Request:

{
  "qr_token": "signed_token_string"
}

Response:

{
  "success": true,
  "token": "jwt_access_token"
}

POST /api/get-records

Get shared medical records (requires doctor JWT).

Headers:

Authorization: Bearer <doctor_jwt_token>

Response:

{
  "success": true,
  "records": [
    {
      "id": "uuid",
      "title": "Blood Test",
      "description": "Annual checkup",
      "file_url": "original_url",
      "signed_url": "signed_url_with_token",
      "uploaded_at": "2024-01-01T00:00:00Z"
    }
  ],
  "grant_id": "uuid",
  "doctor_email": "doctor@example.com"
}

POST /api/log-access

Log when a doctor views a record.

Request:

{
  "grant_id": "uuid",
  "doctor_id": "doctor@example.com",
  "record_id": "uuid"
}

Response:

{
  "success": true
}

🌐 Deployment

Deploy to Vercel

  1. Install Vercel CLI
npm install -g vercel
  1. Link your project
vercel link
  1. Set environment variables in Vercel

    • Go to your project settings on vercel.com
    • Add all environment variables from .env
  2. Deploy

git push origin main
# Vercel auto-deploys on push

Build Configuration

The project uses the following build settings:

  • Framework: Vite
  • Build Command: npm run build
  • Output Directory: dist
  • Install Command: npm install --legacy-peer-deps

πŸ”’ Security

Best Practices Implemented

βœ… Authentication & Authorization

  • Supabase Auth for patient login
  • JWT tokens for doctor sessions
  • Row-Level Security (RLS) on all tables

βœ… Data Protection

  • Encrypted file storage
  • Signed URLs with expiration
  • OTP hashing (SHA-256)
  • HMAC-signed QR tokens

βœ… Access Control

  • Temporary access grants (15 min for doctors)
  • Manual revocation capability
  • Audit logging for all access

βœ… API Security

  • CORS headers configured
  • Input validation
  • Error handling without data leakage

Security Considerations

⚠️ For Production

  1. Use a dedicated JWT secret (not Supabase service key)
  2. Set storage bucket to private
  3. Implement rate limiting
  4. Add CAPTCHA to signup/login
  5. Enable MFA for patient accounts
  6. Regular security audits

🀝 Contributing

Contributions are welcome! Please follow these guidelines:

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

Development Guidelines

  • Follow existing code style
  • Write meaningful commit messages
  • Add comments for complex logic
  • Test your changes thoroughly
  • Update documentation as needed

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ‘₯ Authors


πŸ™ Acknowledgments


πŸ“§ Support

For support, email support@healthvault.com or open an issue on GitHub.


Made with ❀️ for better healthcare

Report Bug Β· Request Feature

About

HealthVault is a modern, secure digital health records management system that empowers patients . Built with privacy and security at its core, HealthVault uses end-to-end encryption, temporary access tokens, and granular access controls to ensure your medical data remains strictly under your control .

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages