""" Serializers for Collaboration & War Rooms models """ from rest_framework import serializers from django.contrib.auth import get_user_model from ..models import ( WarRoom, ConferenceBridge, IncidentCommandRole, TimelineEvent, WarRoomMessage, IncidentDecision, MessageReaction, ChatFile, ChatCommand, ChatBot ) from incident_intelligence.serializers.incident import IncidentSerializer from security.serializers.security import UserSerializer User = get_user_model() class WarRoomSerializer(serializers.ModelSerializer): """Serializer for WarRoom model""" incident = IncidentSerializer(read_only=True) incident_id = serializers.UUIDField(write_only=True) allowed_users = UserSerializer(many=True, read_only=True) allowed_user_ids = serializers.ListField( child=serializers.UUIDField(), write_only=True, required=False ) created_by = UserSerializer(read_only=True) created_by_id = serializers.UUIDField(write_only=True, required=False) class Meta: model = WarRoom fields = [ 'id', 'name', 'description', 'incident', 'incident_id', 'status', 'privacy_level', 'slack_channel_id', 'teams_channel_id', 'discord_channel_id', 'allowed_users', 'allowed_user_ids', 'required_clearance_level', 'message_count', 'last_activity', 'active_participants', 'created_by', 'created_by_id', 'created_at', 'updated_at', 'archived_at' ] read_only_fields = ['id', 'created_at', 'updated_at', 'message_count', 'last_activity', 'active_participants'] def create(self, validated_data): """Create war room with allowed users""" allowed_user_ids = validated_data.pop('allowed_user_ids', []) war_room = WarRoom.objects.create(**validated_data) # Add allowed users if allowed_user_ids: users = User.objects.filter(id__in=allowed_user_ids) war_room.allowed_users.set(users) return war_room def update(self, instance, validated_data): """Update war room with allowed users""" allowed_user_ids = validated_data.pop('allowed_user_ids', None) # Update war room fields for attr, value in validated_data.items(): setattr(instance, attr, value) instance.save() # Update allowed users if provided if allowed_user_ids is not None: users = User.objects.filter(id__in=allowed_user_ids) instance.allowed_users.set(users) return instance class ConferenceBridgeSerializer(serializers.ModelSerializer): """Serializer for ConferenceBridge model""" incident = IncidentSerializer(read_only=True) incident_id = serializers.UUIDField(write_only=True) war_room = WarRoomSerializer(read_only=True) war_room_id = serializers.UUIDField(write_only=True, required=False) invited_participants = UserSerializer(many=True, read_only=True) invited_participant_ids = serializers.ListField( child=serializers.UUIDField(), write_only=True, required=False ) active_participants = UserSerializer(many=True, read_only=True) created_by = UserSerializer(read_only=True) created_by_id = serializers.UUIDField(write_only=True, required=False) class Meta: model = ConferenceBridge fields = [ 'id', 'name', 'description', 'incident', 'incident_id', 'war_room', 'war_room_id', 'bridge_type', 'status', 'meeting_id', 'meeting_url', 'dial_in_number', 'access_code', 'scheduled_start', 'scheduled_end', 'actual_start', 'actual_end', 'invited_participants', 'invited_participant_ids', 'active_participants', 'max_participants', 'recording_enabled', 'recording_url', 'transcription_enabled', 'transcription_url', 'integration_config', 'created_by', 'created_by_id', 'created_at', 'updated_at' ] read_only_fields = ['id', 'created_at', 'updated_at', 'actual_start', 'actual_end', 'active_participants'] def create(self, validated_data): """Create conference bridge with invited participants""" invited_participant_ids = validated_data.pop('invited_participant_ids', []) conference = ConferenceBridge.objects.create(**validated_data) # Add invited participants if invited_participant_ids: users = User.objects.filter(id__in=invited_participant_ids) conference.invited_participants.set(users) return conference def update(self, instance, validated_data): """Update conference bridge with invited participants""" invited_participant_ids = validated_data.pop('invited_participant_ids', None) # Update conference fields for attr, value in validated_data.items(): setattr(instance, attr, value) instance.save() # Update invited participants if provided if invited_participant_ids is not None: users = User.objects.filter(id__in=invited_participant_ids) instance.invited_participants.set(users) return instance class IncidentCommandRoleSerializer(serializers.ModelSerializer): """Serializer for IncidentCommandRole model""" incident = IncidentSerializer(read_only=True) incident_id = serializers.UUIDField(write_only=True) war_room = WarRoomSerializer(read_only=True) war_room_id = serializers.UUIDField(write_only=True, required=False) assigned_user = UserSerializer(read_only=True) assigned_user_id = serializers.UUIDField(write_only=True, required=False) reassigned_by = UserSerializer(read_only=True) created_by = UserSerializer(read_only=True) created_by_id = serializers.UUIDField(write_only=True, required=False) class Meta: model = IncidentCommandRole fields = [ 'id', 'incident', 'incident_id', 'war_room', 'war_room_id', 'role_type', 'assigned_user', 'assigned_user_id', 'status', 'responsibilities', 'decision_authority', 'assigned_at', 'reassigned_at', 'reassigned_by', 'assignment_notes', 'decisions_made', 'communications_sent', 'last_activity', 'created_by', 'created_by_id', 'created_at', 'updated_at' ] read_only_fields = [ 'id', 'assigned_at', 'reassigned_at', 'reassigned_by', 'decisions_made', 'communications_sent', 'last_activity', 'created_at', 'updated_at' ] class TimelineEventSerializer(serializers.ModelSerializer): """Serializer for TimelineEvent model""" incident = IncidentSerializer(read_only=True) incident_id = serializers.UUIDField(write_only=True) related_user = UserSerializer(read_only=True) related_user_id = serializers.UUIDField(write_only=True, required=False) created_by = UserSerializer(read_only=True) created_by_id = serializers.UUIDField(write_only=True, required=False) class Meta: model = TimelineEvent fields = [ 'id', 'incident', 'incident_id', 'event_type', 'title', 'description', 'source_type', 'event_time', 'created_at', 'related_user', 'related_user_id', 'event_data', 'tags', 'is_critical_event', 'postmortem_notes', 'created_by', 'created_by_id' ] read_only_fields = ['id', 'created_at'] class MessageReactionSerializer(serializers.ModelSerializer): """Serializer for MessageReaction model""" user = UserSerializer(read_only=True) class Meta: model = MessageReaction fields = ['id', 'user', 'emoji', 'created_at'] read_only_fields = ['id', 'created_at'] class ChatFileSerializer(serializers.ModelSerializer): """Serializer for ChatFile model""" uploaded_by = UserSerializer(read_only=True) class Meta: model = ChatFile fields = [ 'id', 'message', 'filename', 'original_filename', 'file_type', 'file_size', 'mime_type', 'file_path', 'file_url', 'data_classification', 'is_encrypted', 'file_hash', 'uploaded_by', 'uploaded_at', 'access_log' ] read_only_fields = ['id', 'uploaded_at', 'access_log'] class ChatCommandSerializer(serializers.ModelSerializer): """Serializer for ChatCommand model""" executed_by = UserSerializer(read_only=True) class Meta: model = ChatCommand fields = [ 'id', 'message', 'command_type', 'command_text', 'parameters', 'executed_by', 'executed_at', 'execution_status', 'execution_result', 'error_message', 'automation_execution' ] read_only_fields = ['id', 'executed_at'] class ChatBotSerializer(serializers.ModelSerializer): """Serializer for ChatBot model""" class Meta: model = ChatBot fields = [ 'id', 'name', 'bot_type', 'description', 'is_active', 'auto_respond', 'response_triggers', 'knowledge_base', 'created_at', 'updated_at' ] read_only_fields = ['id', 'created_at', 'updated_at'] class WarRoomMessageSerializer(serializers.ModelSerializer): """Serializer for WarRoomMessage model""" war_room = WarRoomSerializer(read_only=True) war_room_id = serializers.UUIDField(write_only=True) sender = UserSerializer(read_only=True) sender_id = serializers.UUIDField(write_only=True, required=False) reply_to = serializers.PrimaryKeyRelatedField( queryset=WarRoomMessage.objects.all(), required=False ) pinned_by = UserSerializer(read_only=True) mentioned_users = UserSerializer(many=True, read_only=True) mentioned_user_ids = serializers.ListField( child=serializers.UUIDField(), write_only=True, required=False ) reactions = MessageReactionSerializer(many=True, read_only=True) chat_files = ChatFileSerializer(many=True, read_only=True) chat_commands = ChatCommandSerializer(many=True, read_only=True) reactions_summary = serializers.SerializerMethodField() class Meta: model = WarRoomMessage fields = [ 'id', 'war_room', 'war_room_id', 'message_type', 'content', 'sender', 'sender_id', 'sender_name', 'is_edited', 'edited_at', 'is_pinned', 'pinned_at', 'pinned_by', 'reply_to', 'attachments', 'mentioned_users', 'mentioned_user_ids', 'notification_sent', 'external_message_id', 'external_data', 'is_encrypted', 'encryption_key_id', 'reactions', 'reactions_summary', 'chat_files', 'chat_commands', 'created_at', 'updated_at' ] read_only_fields = [ 'id', 'is_edited', 'edited_at', 'pinned_at', 'pinned_by', 'notification_sent', 'created_at', 'updated_at' ] def get_reactions_summary(self, obj): """Get reactions summary for the message""" return obj.get_reactions_summary() def create(self, validated_data): """Create message with mentioned users""" mentioned_user_ids = validated_data.pop('mentioned_user_ids', []) message = WarRoomMessage.objects.create(**validated_data) # Add mentioned users if mentioned_user_ids: users = User.objects.filter(id__in=mentioned_user_ids) message.mentioned_users.set(users) return message class IncidentDecisionSerializer(serializers.ModelSerializer): """Serializer for IncidentDecision model""" incident = IncidentSerializer(read_only=True) incident_id = serializers.UUIDField(write_only=True) command_role = IncidentCommandRoleSerializer(read_only=True) command_role_id = serializers.UUIDField(write_only=True) approved_by = UserSerializer(read_only=True) implemented_by = UserSerializer(read_only=True) class Meta: model = IncidentDecision fields = [ 'id', 'incident', 'incident_id', 'command_role', 'command_role_id', 'decision_type', 'title', 'description', 'rationale', 'status', 'requires_approval', 'approved_by', 'approved_at', 'implementation_notes', 'implemented_at', 'implemented_by', 'impact_assessment', 'success_metrics', 'created_at', 'updated_at' ] read_only_fields = [ 'id', 'approved_by', 'approved_at', 'implemented_at', 'implemented_by', 'created_at', 'updated_at' ] class WarRoomSummarySerializer(serializers.ModelSerializer): """Simplified serializer for WarRoom list views""" incident_title = serializers.CharField(source='incident.title', read_only=True) incident_severity = serializers.CharField(source='incident.severity', read_only=True) participant_count = serializers.SerializerMethodField() class Meta: model = WarRoom fields = [ 'id', 'name', 'incident_title', 'incident_severity', 'status', 'privacy_level', 'message_count', 'last_activity', 'participant_count', 'created_at' ] def get_participant_count(self, obj): """Get count of allowed users""" return obj.allowed_users.count() class TimelineEventSummarySerializer(serializers.ModelSerializer): """Simplified serializer for TimelineEvent list views""" incident_title = serializers.CharField(source='incident.title', read_only=True) related_user_name = serializers.CharField(source='related_user.username', read_only=True) class Meta: model = TimelineEvent fields = [ 'id', 'incident_title', 'event_type', 'title', 'description', 'source_type', 'event_time', 'related_user_name', 'is_critical_event', 'created_at' ]