183 lines
4.7 KiB
Python
183 lines
4.7 KiB
Python
"""
|
|
Simulator models for persistent logging of requests.
|
|
|
|
This module provides models to store:
|
|
- Email simulator requests
|
|
- SMS simulator requests
|
|
- HIS journey events
|
|
- Request metadata and responses
|
|
"""
|
|
from django.db import models
|
|
from django.contrib.auth import get_user_model
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class HISRequestLog(models.Model):
|
|
"""
|
|
Log all HIS (Hospital Information System) requests for tracking and analysis.
|
|
|
|
Stores requests from:
|
|
- Email simulator
|
|
- SMS simulator
|
|
- HIS journey events
|
|
"""
|
|
# Request identification
|
|
request_id = models.AutoField(primary_key=True)
|
|
timestamp = models.DateTimeField(auto_now_add=True, db_index=True)
|
|
|
|
# Channel identification
|
|
CHANNEL_CHOICES = [
|
|
('email', 'Email Simulator'),
|
|
('sms', 'SMS Simulator'),
|
|
('his_event', 'HIS Journey Event'),
|
|
]
|
|
channel = models.CharField(
|
|
max_length=20,
|
|
choices=CHANNEL_CHOICES,
|
|
db_index=True
|
|
)
|
|
|
|
# Request data
|
|
payload = models.JSONField(default=dict, help_text="Full request payload")
|
|
|
|
# Response data
|
|
status = models.CharField(
|
|
max_length=20,
|
|
db_index=True,
|
|
help_text="Request status: success, failed, partial, sent"
|
|
)
|
|
response_data = models.JSONField(
|
|
default=dict,
|
|
null=True,
|
|
blank=True,
|
|
help_text="Full response from simulator"
|
|
)
|
|
|
|
# Processing details
|
|
processing_time_ms = models.IntegerField(
|
|
null=True,
|
|
blank=True,
|
|
help_text="Processing time in milliseconds"
|
|
)
|
|
error_message = models.TextField(
|
|
null=True,
|
|
blank=True,
|
|
help_text="Error message if request failed"
|
|
)
|
|
|
|
# Related objects (when available)
|
|
patient_id = models.CharField(
|
|
max_length=100,
|
|
null=True,
|
|
blank=True,
|
|
db_index=True,
|
|
help_text="Patient MRN when applicable"
|
|
)
|
|
journey_id = models.CharField(
|
|
max_length=100,
|
|
null=True,
|
|
blank=True,
|
|
db_index=True,
|
|
help_text="Journey encounter ID when applicable"
|
|
)
|
|
survey_id = models.CharField(
|
|
max_length=100,
|
|
null=True,
|
|
blank=True,
|
|
db_index=True,
|
|
help_text="Survey ID when applicable"
|
|
)
|
|
hospital_code = models.CharField(
|
|
max_length=50,
|
|
null=True,
|
|
blank=True,
|
|
db_index=True,
|
|
help_text="Hospital code when applicable"
|
|
)
|
|
|
|
# Email/SMS specific fields
|
|
recipient = models.CharField(
|
|
max_length=255,
|
|
null=True,
|
|
blank=True,
|
|
help_text="Email address or phone number"
|
|
)
|
|
subject = models.CharField(
|
|
max_length=500,
|
|
null=True,
|
|
blank=True,
|
|
help_text="Email subject when applicable"
|
|
)
|
|
message_preview = models.TextField(
|
|
null=True,
|
|
blank=True,
|
|
help_text="First 500 characters of message"
|
|
)
|
|
|
|
# HIS event specific fields
|
|
event_type = models.CharField(
|
|
max_length=100,
|
|
null=True,
|
|
blank=True,
|
|
db_index=True,
|
|
help_text="HIS event type code"
|
|
)
|
|
visit_type = models.CharField(
|
|
max_length=50,
|
|
null=True,
|
|
blank=True,
|
|
db_index=True,
|
|
help_text="Visit type: opd, inpatient, ems"
|
|
)
|
|
department = models.CharField(
|
|
max_length=100,
|
|
null=True,
|
|
blank=True,
|
|
help_text="Department name"
|
|
)
|
|
|
|
# Metadata
|
|
ip_address = models.GenericIPAddressField(
|
|
null=True,
|
|
blank=True,
|
|
help_text="Client IP address"
|
|
)
|
|
user_agent = models.TextField(
|
|
null=True,
|
|
blank=True,
|
|
help_text="Client user agent"
|
|
)
|
|
|
|
class Meta:
|
|
ordering = ['-timestamp']
|
|
indexes = [
|
|
models.Index(fields=['timestamp', 'channel']),
|
|
models.Index(fields=['status', 'timestamp']),
|
|
]
|
|
verbose_name = "HIS Request Log"
|
|
verbose_name_plural = "HIS Request Logs"
|
|
|
|
def __str__(self):
|
|
return f"{self.channel.upper()} HIS Request #{self.request_id} - {self.status}"
|
|
|
|
def get_status_display_with_icon(self):
|
|
"""Return status with icon for UI display"""
|
|
icons = {
|
|
'success': '✅',
|
|
'sent': '✅',
|
|
'failed': '❌',
|
|
'partial': '⚠️',
|
|
}
|
|
return f"{icons.get(self.status, '❓')} {self.status.title()}"
|
|
|
|
def get_summary(self):
|
|
"""Return a brief summary of the request"""
|
|
if self.channel == 'email':
|
|
return f"Email to {self.recipient}"
|
|
elif self.channel == 'sms':
|
|
return f"SMS to {self.recipient}"
|
|
elif self.channel == 'his_event':
|
|
return f"Event: {self.event_type}"
|
|
return f"{self.channel} request"
|