A comprehensive, secure, and scalable digital healthcare platform designed for the Indian healthcare ecosystem. CuraNet enables seamless Electronic Health Records (EHR) management with advanced consent-based data sharing, multi-role access control, and HIPAA-compliant security features.
- Features
- Tech Stack
- System Architecture
- Getting Started
- Environment Variables
- API Documentation
- Database Schema
- Security Features
- Development
- Deployment
- Testing
- Contributing
- License
- Every user gets a unique Health ID (
HID-YYYY-XXXXXXXX) - Centralized patient identification across all healthcare providers
- Portable medical records across hospitals
- Patients: Manage personal health data, appointments, consent
- Doctors: Access patient records, create observations, manage appointments
- Pharmacies: View prescriptions, update medication status
- Admins: System administration, user management, analytics
- Encounters: Doctor visits, consultations, diagnoses
- Observations: Vital signs (BP, heart rate, glucose, weight, etc.)
- Prescriptions: Medication records with dosage and duration
- Lab Results: Test reports with reference ranges
- File Attachments: X-rays, scans, medical documents (PDF, DICOM, images)
- Self-Reporting: Patients can record health data with doctor verification
- Granular consent control (READ_BASIC, READ_FULL, WRITE, DELETE)
- Time-bound access with automatic expiration
- Consent request workflow with approval/rejection
- Revocable at any time by patient
- Comprehensive audit trail
- Generate time-limited emergency access tokens
- Share critical health information without login
- Configurable data scope (allergies, medications, emergency contacts)
- Automatic expiration and access logging
- Book appointments with doctors
- Status tracking: PENDING β CONFIRMED β COMPLETED/CANCELLED
- Automated email/SMS notifications
- Doctor and patient notes
- Appointment history and analytics
- Patients can record their own health measurements
- IoT device data integration ready
- Photo/file attachments for symptoms
- Doctor verification workflow (PENDING β VERIFIED β REJECTED)
- Device metadata tracking
- Patient health trends (blood pressure, glucose over time)
- Admin dashboard with system metrics
- Appointment statistics
- User engagement analytics
- Consent usage patterns
- Secure file upload with encryption
- Chunked upload support for large files
- File sharing with consent validation
- Access logging and audit trail
- Support for medical imaging (DICOM)
- Appearance settings (dark mode, themes)
- Notification preferences (email, SMS, push)
- Security settings (2FA, session management)
- Privacy controls and data export
- Language preferences
- Node.js v24.1.0 - JavaScript runtime
- Express v5.1.0 - Web application framework
- TypeScript v5.0.0 - Type-safe JavaScript
- PostgreSQL v16 - Primary database
- Prisma v6.16.2 - Modern ORM with type safety
- Neon - Serverless PostgreSQL (pooling enabled)
- JWT - JSON Web Tokens (Access + Refresh)
- Argon2 - Password hashing (military-grade)
- Helmet - Security headers (CSP, HSTS, XSS protection)
- Express Rate Limit - DDoS protection
- CORS - Cross-Origin Resource Sharing
- Cookie Parser - Secure HTTP-only cookies
- Resend - Transactional emails with verified domains
- Nodemailer - SMTP/Ethereal fallback
- Twilio (ready) - SMS notifications
- Winston - Structured logging with log rotation
- APM Hooks - New Relic, Datadog, Application Insights ready
- Correlation IDs - Request tracking across services
- Nodemon - Auto-restart on file changes
- ESLint - Code linting
- Prettier - Code formatting
- Husky - Git hooks
- Docker - Containerization
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Client Applications β
β (Web App, Mobile App, Admin Dashboard) β
βββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β HTTPS/REST API
β
βββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββ
β Express Server (Port 3001) β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Security Layer (Helmet, CORS, Rate Limiting) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Authentication Middleware (JWT Verification) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Request Tracking (Correlation IDs, APM) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β API Routes Layer β β
β β β’ /api/auth β’ /api/records β β
β β β’ /api/consent β’ /api/appointments β β
β β β’ /api/uploads β’ /api/emergency β β
β β β’ /api/analytics β’ /api/admin β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Controllers & Business Logic β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Services Layer β β
β β β’ AuthService β’ ConsentService β β
β β β’ EmailService β’ NotificationService β β
β β β’ FileService β’ AuditService β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β Prisma ORM
β
βββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββ
β PostgreSQL Database (Neon) β
β β’ 36 Tables with relationships β
β β’ Connection pooling for scalability β
β β’ Automated backups and migrations β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β External Services β
β β’ Resend (Email) β
β β’ Twilio (SMS - ready) β
β β’ Cloud Storage (S3 - ready) β
β β’ APM Tools (New Relic/Datadog - ready) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Node.js v24.x or higher
- PostgreSQL 16 or Neon database
- npm or yarn package manager
- Git
- Clone the repository
git clone https://github.com/yourusername/curanet-backend.git
cd curanet-backend- Install dependencies
npm install- Set up environment variables
cp .env.example .env
# Edit .env with your configurationProduction email note:
- Use
EMAIL_FROMon your verified domain, for exampleCuraNet <noreply@curanet.in>. - Do not use personal mailbox domains like
gmail.com,outlook.com, oryahoo.comwith Resend. - If using Resend, set both
RESEND_API_KEYandRESEND_VERIFIED_DOMAIN.
- Generate Prisma client
npm run db:generate- Run database migrations
npm run db:migrate- Seed database (optional)
npm run db:seed- Start development server
npm run devServer will start at http://localhost:3001
# Development
npm run dev # Start with hot reload
npm run type-check # TypeScript type checking
npm run lint # Run ESLint
npm run lint:fix # Fix linting issues
# Database
npm run db:studio # Open Prisma Studio
npm run db:migrate # Create migration
npm run db:migrate:prod # Deploy migrations to production
npm run db:reset # Reset database (WARNING: deletes all data)
# Production
npm run build # Build TypeScript
npm start # Start production server
# Docker
npm run docker:build # Build Docker image
npm run docker:run # Run Docker container
npm run docker:compose # Start with docker-composeCreate a .env file in the root directory:
# ===================================
# Server Configuration
# ===================================
NODE_ENV=development
PORT=3001
LOG_LEVEL=info
# ===================================
# Database
# ===================================
DATABASE_URL="postgresql://user:password@host:5432/curanet?pgbouncer=true&connection_limit=10"
DATABASE_URL_NON_POOLING="postgresql://user:password@host:5432/curanet"
# ===================================
# Authentication & Security
# ===================================
JWT_SECRET="your-super-secret-jwt-key-min-256-bits"
JWT_REFRESH_SECRET="your-super-secret-refresh-key-min-256-bits"
PASSWORD_PEPPER="your-password-pepper-256-bits"
# ===================================
# CORS & Frontend
# ===================================
CORS_ORIGIN="https://yourdomain.com,https://www.yourdomain.com"
FRONTEND_URL="https://yourdomain.com"
# ===================================
# Email Service (Resend)
# ===================================
RESEND_API_KEY="re_xxxxxxxxx"
RESEND_VERIFIED_DOMAIN="curanet.in"
EMAIL_FROM="CuraNet <noreply@curanet.in>"
# ===================================
# SMS Service (Twilio - Optional)
# ===================================
TWILIO_ACCOUNT_SID="your-twilio-account-sid"
TWILIO_AUTH_TOKEN="your-twilio-auth-token"
TWILIO_PHONE_NUMBER="+1234567890"
# ===================================
# File Upload
# ===================================
MAX_FILE_SIZE=52428800 # 50MB in bytes
MAX_FILES_PER_REQUEST=10
# ===================================
# APM & Monitoring (Optional)
# ===================================
APM_PROVIDER="" # newrelic, datadog, applicationinsights, prometheus
NEW_RELIC_LICENSE_KEY=""
DATADOG_API_KEY=""# Generate JWT secrets (Linux/Mac)
node -e "console.log(require('crypto').randomBytes(64).toString('base64'))"
# Windows PowerShell
node -e "console.log(require('crypto').randomBytes(64).toString('base64'))"http://localhost:3001/api
Register a new user
Request Body:
{
"email": "patient@example.com",
"password": "SecurePass123!",
"role": "patient",
"name": "John Doe",
"phone": "+919876543210"
}Response:
{
"message": "Registration successful",
"user": {
"healthId": "HID-2025-A1B2C3D4",
"email": "patient@example.com",
"role": "patient",
"status": "pending_verification"
}
}Login with email/phone and password
Request Body:
{
"email": "patient@example.com",
"password": "SecurePass123!"
}Response:
{
"message": "Login successful",
"user": {
"healthId": "HID-2025-A1B2C3D4",
"email": "patient@example.com",
"role": "patient"
},
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "stored-in-httponly-cookie"
}Refresh access token
Response:
{
"accessToken": "eyJhbGciOiJIUzI1NiIs..."
}Logout and revoke refresh token
Request consent from a patient
Headers:
Authorization: Bearer <access_token>
Request Body:
{
"patientHealthId": "HID-2025-A1B2C3D4",
"purpose": "Treatment consultation",
"scope": ["READ_BASIC", "READ_OBSERVATIONS"],
"requestedExpiry": "2025-12-31T23:59:59Z",
"message": "I need access to review your medical history"
}Grant consent (patient only)
Request Body:
{
"requestId": "clx123456789",
"endTime": "2025-12-31T23:59:59Z"
}List all consents
Query Parameters:
role- Filter by role (patient/provider)status- Filter by status (ACTIVE/REVOKED/EXPIRED)
Revoke a consent
Request Body:
{
"consentId": "clx123456789",
"reason": "Treatment completed"
}Create a new encounter
Request Body:
{
"patientHealthId": "HID-2025-A1B2C3D4",
"type": "CONSULTATION",
"reason": "Routine checkup",
"notes": "Patient presenting with fever"
}Add an observation
Request Body:
{
"patientHealthId": "HID-2025-A1B2C3D4",
"encounterId": "clx123456789",
"code": "blood_pressure",
"value": { "systolic": 120, "diastolic": 80 },
"unit": "mmHg"
}Get patient's medical records
Response:
{
"patient": {
"healthId": "HID-2025-A1B2C3D4",
"profile": { ... }
},
"encounters": [ ... ],
"observations": [ ... ],
"prescriptions": [ ... ]
}Book an appointment
Request Body:
{
"doctorId": "HID-2025-D1D2D3D4",
"requestedTime": "2025-12-28T10:00:00Z",
"reasonForVisit": "Annual checkup",
"duration": 30
}List appointments
Query Parameters:
status- PENDING, CONFIRMED, COMPLETED, CANCELLEDdate- Filter by date
Update appointment status
Request Body:
{
"status": "CONFIRMED",
"doctorNotes": "Confirmed for 10 AM slot"
}Create emergency share link
Request Body:
{
"scope": ["ALLERGIES", "MEDICATIONS", "EMERGENCY_CONTACT"],
"expiresIn": 24
}Response:
{
"shareUrl": "https://curanet.com/emergency/abcd1234",
"shareId": "abcd1234",
"expiresAt": "2025-12-28T10:00:00Z"
}Access emergency data
Initialize file upload
Request Body:
{
"filename": "xray-chest.jpg",
"mimeType": "image/jpeg",
"fileSize": 2048576,
"category": "XRAY"
}Upload file
Form Data:
file: <binary>
uploadToken: <token-from-initialize>
List user's files
Download file
Delete file
Get patient health trends
Query Parameters:
metric- blood_pressure, glucose, weight, etc.startDate- Start date for trendendDate- End date for trend
List all users (admin only)
Update user status
System analytics dashboard
model User {
healthId String @id
email String? @unique
phone String? @unique
role UserRole
passwordHash String
status UserStatus
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}model Consent {
id String @id @default(cuid())
patientId String
providerId String
status ConsentStatus @default(ACTIVE)
scope ConsentScope[]
permissions String[]
purpose String
startTime DateTime @default(now())
endTime DateTime?
createdAt DateTime @default(now())
}model Encounter {
id String @id @default(cuid())
patientId String
providerId String
type String
reason String?
startTime DateTime
endTime DateTime?
notes String?
observations Observation[]
}model Observation {
id String @id @default(cuid())
patientId String
providerId String
encounterId String?
code String
value Json
unit String?
source ObservationSource @default(DOCTOR_RECORDED)
verificationStatus VerificationStatus @default(PENDING)
recordedAt DateTime @default(now())
}Total Models: 36 tables including:
- Authentication (RefreshToken, EmailVerification, PasswordResetToken)
- Medical Records (Encounter, Observation, Prescription)
- Consent Management (Consent, ConsentRequest)
- Appointments (Appointment, AppointmentNotification)
- File Management (FileUpload, FileAccess)
- User Settings (SecuritySettings, NotificationSettings, AppearanceSettings)
- Audit (HealthIdAudit, AuditLog)
- JWT-based authentication with access + refresh tokens
- Refresh token rotation on every use
- HTTP-only cookies for refresh tokens
- Role-based access control (RBAC)
- Device fingerprinting
- Argon2id hashing algorithm (OWASP recommended)
- Password pepper (application-level secret)
- Minimum password requirements enforced
- Password reset with time-limited tokens
- Helmet security headers (CSP, HSTS, XSS protection)
- CORS with whitelist validation
- Rate limiting (100 req/15min per IP)
- Request size limits
- SQL injection prevention (Prisma ORM)
- Consent-based data access
- Granular permissions (READ_BASIC, READ_FULL, WRITE)
- Time-bound access with auto-expiration
- Comprehensive audit trail
- Data encryption at rest and in transit
- Structured logging with Winston
- Request correlation IDs
- Security event logging
- Failed login attempt tracking
- APM integration ready
- Audit trails for all data access
- Encrypted data transmission (HTTPS)
- Access control and authentication
- Data integrity checks
- Automatic session timeout
- File type validation (whitelist)
- File size limits (50MB default)
- Virus scanning ready
- Secure file storage with encryption
- Access logging
backend/
βββ prisma/
β βββ schema.prisma # Database schema
β βββ migrations/ # Database migrations
βββ src/
β βββ controllers/ # Route controllers
β β βββ auth.controller.ts
β β βββ consent.controller.ts
β β βββ records.controller.ts
β β βββ ...
β βββ routes/ # API routes
β β βββ auth.routes.ts
β β βββ consent.routes.ts
β β βββ ...
β βββ services/ # Business logic
β β βββ email.service.ts
β β βββ consent.service.ts
β β βββ ...
β βββ middlewares/ # Custom middlewares
β β βββ authMiddleware.ts
β β βββ consentMiddleware.ts
β β βββ ...
β βββ utils/ # Utility functions
β β βββ logger.ts
β β βββ prisma.ts
β β βββ validation.ts
β β βββ apm.ts
β βββ types/ # TypeScript types
β β βββ ambient.d.ts
β βββ index.ts # Entry point
βββ tests/ # Test files
β βββ unit/
β βββ integration/
β βββ security/
βββ uploads/ # Uploaded files
βββ .env # Environment variables
βββ .env.example # Environment template
βββ tsconfig.json # TypeScript config
βββ package.json # Dependencies
βββ Dockerfile # Docker config
βββ docker-compose.yml # Docker compose
βββ README.md # This file
- TypeScript for type safety
- ESLint for code quality
- Prettier for code formatting
- Async/await for asynchronous code
- Error handling with try-catch blocks
- Winston logger instead of console.log
- Prisma best practices (transactions, optimistic locking)
# Create feature branch
git checkout -b feature/your-feature-name
# Make changes and commit
git add .
git commit -m "feat: add new feature"
# Push and create PR
git push origin feature/your-feature-namefeat: Add new feature
fix: Fix bug
docs: Update documentation
style: Code formatting
refactor: Code refactoring
test: Add tests
chore: Build/config changes
- Set
NODE_ENV=production - Generate strong JWT secrets (64+ characters)
- Configure production DATABASE_URL
- Set up HTTPS/SSL certificates
- Configure CORS with production domains
- Enable rate limiting
- Set up logging and monitoring
- Configure email service (SendGrid)
- Set up automated backups
- Enable error tracking (Sentry)
- Configure APM (New Relic/Datadog)
- Set up CI/CD pipeline
- Run security audit (
npm audit)
Build Image:
docker build -t curanet-backend:latest .Run Container:
docker run -d \
--name curanet-backend \
-p 3001:3001 \
--env-file .env \
curanet-backend:latestDocker Compose:
docker-compose up -dheroku create curanet-backend
heroku addons:create heroku-postgresql:standard-0
git push heroku main- Launch EC2 instance (Ubuntu 22.04)
- Install Node.js and PostgreSQL
- Clone repository
- Set up environment variables
- Run with PM2:
pm2 start npm --name "curanet" -- start
Connect GitHub repository and configure environment variables
# Unit tests
npm run test:unit
# Integration tests
npm run test:integration
# Security tests
npm run test:security
# All tests
npm test
# Coverage report
npm run test:coverageImport postman_collection.json into Postman for pre-configured API tests.
# Using Apache Bench
ab -n 1000 -c 10 http://localhost:3001/api/healthz
# Using Artillery
artillery quick --count 10 --num 100 http://localhost:3001/api/healthz- Database connection pooling (Neon)
- Query optimization with Prisma
- Response caching (Redis ready)
- Pagination for large datasets
- Lazy loading of relationships
- Graceful shutdown handling
- Request batching where applicable
- Winston structured logging
- APM integration (New Relic/Datadog)
- Request duration tracking
- Slow query detection
- Error rate monitoring
- Memory usage tracking
We welcome contributions! Please follow these steps:
- Fork the repository
- Create feature branch (
git checkout -b feature/AmazingFeature) - Commit changes (
git commit -m 'feat: add amazing feature') - Push to branch (
git push origin feature/AmazingFeature) - Open Pull Request
- Write clear, descriptive commit messages
- Add tests for new features
- Update documentation
- Follow existing code style
- Ensure all tests pass
This project is licensed under the MIT License - see the LICENSE file for details.
Made with β€οΈ for better healthcare in India
Last Updated: December 27, 2025