2025-08-12 13:33:25 +03:00

298 lines
12 KiB
Python

from rest_framework import serializers
from ..models import (
ExternalSystem, IntegrationEndpoint, DataMapping,
IntegrationExecution, WebhookEndpoint, WebhookExecution, IntegrationLog
)
class BaseSerializer(serializers.ModelSerializer):
"""Base serializer with common functionality"""
class Meta:
fields = ['id']
read_only_fields = ['created_at', 'updated_at']
class ExternalSystemSerializer(serializers.ModelSerializer):
"""Serializer for ExternalSystem model"""
system_type_display = serializers.CharField(source='get_system_type_display', read_only=True)
status_display = serializers.CharField(source='get_status_display', read_only=True)
class Meta:
model = ExternalSystem
fields = [
'system_id', 'name', 'description', 'system_type', 'system_type_display',
'base_url', 'api_version', 'authentication_type', 'credentials',
'timeout_seconds', 'retry_attempts', 'status', 'status_display',
'last_health_check', 'is_active', 'created_at', 'updated_at'
]
read_only_fields = ['system_id', 'last_health_check', 'created_at', 'updated_at']
class IntegrationEndpointSerializer(serializers.ModelSerializer):
"""Serializer for IntegrationEndpoint model"""
system_name = serializers.CharField(source='system.name', read_only=True)
method_display = serializers.CharField(source='get_method_display', read_only=True)
class Meta:
model = IntegrationEndpoint
fields = [
'endpoint_id', 'system', 'system_name', 'name', 'description',
'endpoint_url', 'method', 'method_display', 'headers',
'request_template', 'response_mapping', 'timeout_seconds',
'is_active', 'created_at', 'updated_at'
]
read_only_fields = ['endpoint_id', 'created_at', 'updated_at']
class DataMappingSerializer(serializers.ModelSerializer):
"""Serializer for DataMapping model"""
endpoint_name = serializers.CharField(source='endpoint.name', read_only=True)
mapping_type_display = serializers.CharField(source='get_mapping_type_display', read_only=True)
class Meta:
model = DataMapping
fields = [
'mapping_id', 'endpoint', 'endpoint_name', 'name', 'description',
'mapping_type', 'mapping_type_display', 'source_field',
'target_field', 'transformation_rules', 'is_required',
'default_value', 'is_active', 'created_at', 'updated_at'
]
read_only_fields = ['mapping_id', 'created_at', 'updated_at']
class IntegrationExecutionSerializer(serializers.ModelSerializer):
"""Serializer for IntegrationExecution model"""
endpoint_name = serializers.CharField(source='endpoint.name', read_only=True)
system_name = serializers.CharField(source='endpoint.system.name', read_only=True)
status_display = serializers.CharField(source='get_status_display', read_only=True)
duration_seconds = serializers.FloatField(read_only=True)
class Meta:
model = IntegrationExecution
fields = [
'execution_id', 'endpoint', 'endpoint_name', 'system_name',
'start_time', 'end_time', 'duration_seconds', 'status', 'status_display',
'request_data', 'response_data', 'error_message', 'retry_count',
'created_at', 'updated_at'
]
read_only_fields = ['execution_id', 'duration_seconds', 'created_at', 'updated_at']
class WebhookEndpointSerializer(serializers.ModelSerializer):
"""Serializer for WebhookEndpoint model"""
class Meta:
model = WebhookEndpoint
fields = [
'webhook_id', 'name', 'description', 'url_path', 'secret_key',
'allowed_ips', 'event_types', 'is_active', 'created_at', 'updated_at'
]
read_only_fields = ['webhook_id', 'created_at', 'updated_at']
class WebhookExecutionSerializer(serializers.ModelSerializer):
"""Serializer for WebhookExecution model"""
webhook_name = serializers.CharField(source='webhook.name', read_only=True)
status_display = serializers.CharField(source='get_status_display', read_only=True)
class Meta:
model = WebhookExecution
fields = [
'execution_id', 'webhook', 'webhook_name', 'event_type',
'payload', 'headers', 'source_ip', 'status', 'status_display',
'response_data', 'error_message', 'processed_at',
'created_at', 'updated_at'
]
read_only_fields = ['execution_id', 'created_at', 'updated_at']
class IntegrationLogSerializer(serializers.ModelSerializer):
"""Serializer for IntegrationLog model"""
level_display = serializers.CharField(source='get_level_display', read_only=True)
class Meta:
model = IntegrationLog
fields = [
'log_id', 'level', 'level_display', 'message', 'details',
'execution', 'webhook_execution', 'created_at', 'updated_at'
]
read_only_fields = ['log_id', 'created_at', 'updated_at']
class IntegrationStatsSerializer(serializers.Serializer):
"""Serializer for integration statistics"""
total_systems = serializers.IntegerField()
active_systems = serializers.IntegerField()
total_endpoints = serializers.IntegerField()
executions_today = serializers.IntegerField()
successful_executions = serializers.IntegerField()
failed_executions = serializers.IntegerField()
avg_response_time = serializers.FloatField()
webhook_executions = serializers.IntegerField()
system_health = serializers.DictField()
execution_trends = serializers.ListField()
class SystemTestSerializer(serializers.Serializer):
"""Serializer for testing external systems"""
system_id = serializers.IntegerField()
test_endpoint = serializers.CharField(required=False, allow_blank=True)
def validate_system_id(self, value):
"""Validate that the system exists"""
try:
ExternalSystem.objects.get(id=value)
return value
except ExternalSystem.DoesNotExist:
raise serializers.ValidationError("Invalid system ID.")
class EndpointExecuteSerializer(serializers.Serializer):
"""Serializer for executing integration endpoints"""
endpoint_id = serializers.IntegerField()
request_data = serializers.JSONField(required=False)
override_timeout = serializers.IntegerField(required=False, min_value=1, max_value=300)
def validate_endpoint_id(self, value):
"""Validate that the endpoint exists and is active"""
try:
endpoint = IntegrationEndpoint.objects.get(id=value)
if not endpoint.is_active:
raise serializers.ValidationError("Endpoint is not active.")
return value
except IntegrationEndpoint.DoesNotExist:
raise serializers.ValidationError("Invalid endpoint ID.")
class WebhookCreateSerializer(serializers.Serializer):
"""Serializer for creating webhooks"""
name = serializers.CharField()
description = serializers.CharField(required=False, allow_blank=True)
event_types = serializers.ListField(
child=serializers.CharField(),
min_length=1
)
allowed_ips = serializers.ListField(
child=serializers.IPAddressField(),
required=False
)
def validate_event_types(self, value):
"""Validate event types"""
valid_events = [
'PATIENT_CREATED', 'PATIENT_UPDATED', 'APPOINTMENT_SCHEDULED',
'LAB_RESULT_AVAILABLE', 'BILLING_INVOICE_CREATED', 'ALERT_TRIGGERED'
]
for event in value:
if event not in valid_events:
raise serializers.ValidationError(f"Invalid event type: {event}")
return value
class DataSyncSerializer(serializers.Serializer):
"""Serializer for data synchronization"""
system_id = serializers.IntegerField()
sync_type = serializers.ChoiceField(choices=['FULL', 'INCREMENTAL'])
entity_types = serializers.ListField(
child=serializers.CharField(),
min_length=1
)
start_date = serializers.DateTimeField(required=False)
end_date = serializers.DateTimeField(required=False)
def validate_entity_types(self, value):
"""Validate entity types"""
valid_entities = [
'PATIENTS', 'APPOINTMENTS', 'LAB_RESULTS', 'MEDICATIONS',
'BILLING', 'INVENTORY', 'EMPLOYEES'
]
for entity in value:
if entity not in valid_entities:
raise serializers.ValidationError(f"Invalid entity type: {entity}")
return value
def validate(self, data):
"""Validate sync parameters"""
if data['sync_type'] == 'INCREMENTAL':
if not data.get('start_date'):
raise serializers.ValidationError(
"Start date is required for incremental sync."
)
if data.get('start_date') and data.get('end_date'):
if data['end_date'] <= data['start_date']:
raise serializers.ValidationError("End date must be after start date.")
return data
class MappingTestSerializer(serializers.Serializer):
"""Serializer for testing data mappings"""
mapping_id = serializers.IntegerField()
test_data = serializers.JSONField()
def validate_mapping_id(self, value):
"""Validate that the mapping exists and is active"""
try:
mapping = DataMapping.objects.get(id=value)
if not mapping.is_active:
raise serializers.ValidationError("Data mapping is not active.")
return value
except DataMapping.DoesNotExist:
raise serializers.ValidationError("Invalid mapping ID.")
class SystemHealthCheckSerializer(serializers.Serializer):
"""Serializer for system health checks"""
system_ids = serializers.ListField(
child=serializers.IntegerField(),
required=False
)
include_endpoints = serializers.BooleanField(default=True)
def validate_system_ids(self, value):
"""Validate system IDs"""
if value:
valid_systems = ExternalSystem.objects.filter(id__in=value).count()
if valid_systems != len(value):
raise serializers.ValidationError("Some system IDs are invalid.")
return value
class IntegrationConfigSerializer(serializers.Serializer):
"""Serializer for integration configuration"""
system_id = serializers.IntegerField()
configuration = serializers.JSONField()
test_connection = serializers.BooleanField(default=True)
def validate_system_id(self, value):
"""Validate that the system exists"""
try:
ExternalSystem.objects.get(id=value)
return value
except ExternalSystem.DoesNotExist:
raise serializers.ValidationError("Invalid system ID.")
class BulkExecutionSerializer(serializers.Serializer):
"""Serializer for bulk endpoint execution"""
endpoint_ids = serializers.ListField(
child=serializers.IntegerField(),
min_length=1,
max_length=10
)
request_data = serializers.JSONField(required=False)
parallel_execution = serializers.BooleanField(default=True)
def validate_endpoint_ids(self, value):
"""Validate endpoint IDs"""
active_endpoints = IntegrationEndpoint.objects.filter(
id__in=value,
is_active=True
).count()
if active_endpoints != len(value):
raise serializers.ValidationError("Some endpoint IDs are invalid or inactive.")
return value