Healthcare Platform
Scenario: HIPAA-Compliant Medical Records
Building a healthcare platform with:
- Patient data encryption
- Audit trails for all access
- Role-based access control
- Integration with medical devices
- Real-time vital monitoring
CLAUDE.md for Healthcare Systems
## Healthcare Platform Security & Compliance
### HIPAA-Compliant Type System
```typescript
// Branded types for PII/PHI
type PHI<T> = T & { __phi: true };
type PII<T> = T & { __pii: true };
interface Patient {
id: string;
mrn: PHI<string>; // Medical Record Number
name: PII<string>;
dateOfBirth: PII<Date>;
ssn: PHI<string>;
conditions: MedicalCondition[];
medications: Medication[];
allergies: Allergy[];
encounters: Encounter[];
}
// Encryption decorator for PHI fields
function Encrypted(target: any, propertyKey: string) {
let value: any;
const getter = function() {
return decrypt(value);
};
const setter = function(newVal: any) {
value = encrypt(newVal);
// Audit log
auditLog({
action: 'PHI_ACCESSED',
field: propertyKey,
entityType: target.constructor.name,
timestamp: new Date(),
});
};
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter,
enumerable: true,
configurable: true,
});
}
// Secure patient data class
class SecurePatient {
id: string;
@Encrypted
mrn: PHI<string>;
@Encrypted
name: PII<string>;
@Encrypted
dateOfBirth: PII<Date>;
@Encrypted
ssn: PHI<string>;
constructor(data: PatientData) {
this.id = data.id;
this.mrn = data.mrn as PHI<string>;
this.name = data.name as PII<string>;
this.dateOfBirth = data.dateOfBirth as PII<Date>;
this.ssn = data.ssn as PHI<string>;
}
}
// Role-based access control
interface AccessControl {
role: UserRole;
permissions: Permission[];
dataAccess: DataAccessLevel;
}
enum UserRole {
PATIENT = 'PATIENT',
NURSE = 'NURSE',
DOCTOR = 'DOCTOR',
ADMIN = 'ADMIN',
BILLING = 'BILLING',
}
interface Permission {
resource: string;
actions: ('read' | 'write' | 'delete')[];
conditions?: AccessCondition[];
}
interface AccessCondition {
type: 'time_based' | 'relationship' | 'emergency';
params: Record<string, any>;
}
// FHIR-compliant resources
interface FHIRResource {
resourceType: string;
id: string;
meta: {
versionId: string;
lastUpdated: Date;
security?: SecurityLabel[];
};
}
interface FHIRPatient extends FHIRResource {
resourceType: 'Patient';
identifier: Identifier[];
name: HumanName[];
telecom: ContactPoint[];
gender: 'male' | 'female' | 'other' | 'unknown';
birthDate: string;
address: Address[];
}Medical Device Integration
// HL7/FHIR message handling
export class MedicalDeviceGateway {
private deviceConnections = new Map<string, DeviceConnection>();
async connectDevice(
deviceId: string,
protocol: 'HL7' | 'FHIR' | 'DICOM'
): Promise<void> {
const connection = await this.establishConnection(deviceId, protocol);
connection.on('data', async (data) => {
const parsed = await this.parseMessage(data, protocol);
await this.processVitalSigns(deviceId, parsed);
});
connection.on('error', (error) => {
this.handleDeviceError(deviceId, error);
});
this.deviceConnections.set(deviceId, connection);
}
private async processVitalSigns(
deviceId: string,
data: VitalSignsData
): Promise<void> {
// Validate data
const validation = this.validateVitalSigns(data);
if (!validation.valid) {
throw new Error(`Invalid vital signs data: ${validation.error}`);
}
// Check for critical values
const alerts = this.checkCriticalValues(data);
if (alerts.length > 0) {
await this.triggerAlerts(alerts);
}
// Store in time-series database
await this.storeVitalSigns({
deviceId,
patientId: data.patientId,
timestamp: data.timestamp,
vitals: data.vitals,
});
// Broadcast to monitoring dashboard
this.broadcast({
type: 'vital_signs_update',
deviceId,
data,
});
}
private checkCriticalValues(data: VitalSignsData): Alert[] {
const alerts: Alert[] = [];
// Heart rate
if (data.vitals.heartRate) {
if (data.vitals.heartRate < 40 || data.vitals.heartRate > 150) {
alerts.push({
type: 'critical',
metric: 'heart_rate',
value: data.vitals.heartRate,
message: `Critical heart rate: ${data.vitals.heartRate} bpm`,
});
}
}
// Blood pressure
if (data.vitals.bloodPressure) {
const { systolic, diastolic } = data.vitals.bloodPressure;
if (systolic > 180 || diastolic > 120) {
alerts.push({
type: 'critical',
metric: 'blood_pressure',
value: `${systolic}/${diastolic}`,
message: `Hypertensive crisis: ${systolic}/${diastolic}`,
});
}
}
// Oxygen saturation
if (data.vitals.oxygenSaturation && data.vitals.oxygenSaturation < 90) {
alerts.push({
type: 'critical',
metric: 'oxygen_saturation',
value: data.vitals.oxygenSaturation,
message: `Low oxygen saturation: ${data.vitals.oxygenSaturation}%`,
});
}
return alerts;
}
}
// React component for real-time monitoring
export function VitalSignsMonitor({ patientId }: { patientId: string }) {
const [vitals, setVitals] = useState<VitalSigns | null>(null);
const [alerts, setAlerts] = useState<Alert[]>([]);
const [connection, setConnection] = useState<'connected' | 'disconnected'>('disconnected');
useEffect(() => {
const ws = new WebSocket(process.env.NEXT_PUBLIC_VITALS_WS_URL!);
ws.onopen = () => {
setConnection('connected');
ws.send(JSON.stringify({
type: 'subscribe',
patientId,
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
switch (message.type) {
case 'vital_signs_update':
setVitals(message.data.vitals);
break;
case 'alert':
setAlerts(prev => [...prev, message.alert]);
break;
}
};
ws.onclose = () => {
setConnection('disconnected');
};
return () => {
ws.close();
};
}, [patientId]);
return (
<div className="vitals-monitor">
<ConnectionStatus status={connection} />
{alerts.length > 0 && (
<AlertBanner alerts={alerts} onDismiss={setAlerts} />
)}
{vitals && (
<VitalsDisplay
heartRate={vitals.heartRate}
bloodPressure={vitals.bloodPressure}
oxygenSaturation={vitals.oxygenSaturation}
temperature={vitals.temperature}
respiratoryRate={vitals.respiratoryRate}
/>
)}
</div>
);
}Audit Logging for HIPAA Compliance
interface HIPAAAuditLog {
id: string;
timestamp: Date;
userId: string;
userRole: UserRole;
action: AuditAction;
resourceType: string;
resourceId: string;
patientId?: string;
phi_accessed: string[]; // Which PHI fields were accessed
reason?: string; // Reason for access
outcome: 'success' | 'failure';
ipAddress: string;
userAgent: string;
sessionId: string;
}
export class HIPAAAuditLogger {
private buffer: HIPAAAuditLog[] = [];
private flushInterval: NodeJS.Timer;
constructor(private storage: AuditStorage) {
// Flush every 30 seconds or when buffer reaches 100 entries
this.flushInterval = setInterval(() => this.flush(), 30000);
}
async log(entry: Omit<HIPAAAuditLog, 'id' | 'timestamp'>): Promise<void> {
const auditEntry: HIPAAAuditLog = {
id: crypto.randomUUID(),
timestamp: new Date(),
...entry,
};
this.buffer.push(auditEntry);
if (this.buffer.length >= 100) {
await this.flush();
}
}
private async flush(): Promise<void> {
if (this.buffer.length === 0) return;
const entries = [...this.buffer];
this.buffer = [];
try {
await this.storage.bulkInsert(entries);
} catch (error) {
// Re-add to buffer on failure
this.buffer.unshift(...entries);
throw error;
}
}
async query(params: {
userId?: string;
patientId?: string;
dateFrom: Date;
dateTo: Date;
actions?: AuditAction[];
}): Promise<HIPAAAuditLog[]> {
return this.storage.query(params);
}
async generateComplianceReport(
dateFrom: Date,
dateTo: Date
): Promise<ComplianceReport> {
const logs = await this.query({ dateFrom, dateTo });
return {
period: { from: dateFrom, to: dateTo },
totalAccesses: logs.length,
uniqueUsers: new Set(logs.map(l => l.userId)).size,
accessByRole: this.groupByRole(logs),
phiAccessSummary: this.summarizePHIAccess(logs),
suspiciousActivities: this.detectSuspiciousActivities(logs),
failedAccesses: logs.filter(l => l.outcome === 'failure'),
};
}
private detectSuspiciousActivities(logs: HIPAAAuditLog[]): SuspiciousActivity[] {
const activities: SuspiciousActivity[] = [];
// Detect unusual access patterns
const userAccesses = this.groupByUser(logs);
for (const [userId, userLogs] of userAccesses) {
// Multiple failed attempts
const failures = userLogs.filter(l => l.outcome === 'failure');
if (failures.length > 5) {
activities.push({
type: 'multiple_failures',
userId,
count: failures.length,
description: `User had ${failures.length} failed access attempts`,
});
}
// After-hours access
const afterHours = userLogs.filter(l => {
const hour = l.timestamp.getHours();
return hour < 6 || hour > 22;
});
if (afterHours.length > 0) {
activities.push({
type: 'after_hours_access',
userId,
count: afterHours.length,
description: `User accessed PHI outside normal hours ${afterHours.length} times`,
});
}
// Bulk data access
const bulkAccess = this.detectBulkAccess(userLogs);
if (bulkAccess) {
activities.push(bulkAccess);
}
}
return activities;
}
}
## Critical Compliance Requirements
1. **Encryption**: All PHI must be encrypted at rest and in transit
2. **Access Control**: Implement role-based access with audit logging
3. **Audit Trail**: Log all PHI access with user, timestamp, and reason
4. **Data Integrity**: Ensure data cannot be tampered with
5. **Business Associate Agreements**: Required for all third-party services
## Security Implementation Checklist
- [ ] Implement field-level encryption for PHI
- [ ] Set up comprehensive audit logging
- [ ] Configure role-based access control
- [ ] Enable automatic session timeouts
- [ ] Implement data backup and recovery
- [ ] Set up intrusion detection
- [ ] Regular security assessments
- [ ] Staff training on HIPAA compliance
## Related Resources
- [[docs/reference/templates/fullstack-typescript|Full-Stack TypeScript Template]]
- [HIPAA Security Rule](https://www.hhs.gov/hipaa/for-professionals/security/index.html)
- [FHIR Specification](https://www.hl7.org/fhir/)
- [HL7 Standards](https://www.hl7.org/)
## 🧭 Quick Navigation
[← Financial Trading](/docs/reference/templates/real-world-scenarios/financial-trading-platform) | [Back to Scenarios](../index) | [Workshop Exercises →](workshop-exercises)