Spaces:
Sleeping
Sleeping
| from flask import jsonify, request | |
| import logging | |
| from datetime import datetime | |
| from models.incident import Incident | |
| from models.workflow import Workflow | |
| from models.log import Log | |
| from utils.celery_tasks import process_incident_forms | |
| from models.user import User | |
| from models.department import Department | |
| from utils.pdf_utils import fill_markdown_form, extract_required_data, save_filled_form | |
| from db import get_gridfs | |
| from bson.objectid import ObjectId | |
| import os | |
| import openai | |
| # Configure logging | |
| logger = logging.getLogger(__name__) | |
| def get_incident(current_user, incident_id): | |
| """Get incident by ID""" | |
| try: | |
| # Find incident by ID | |
| incident = Incident.find_by_id(incident_id) | |
| if not incident: | |
| return jsonify({'message': 'Incident not found'}), 404 | |
| # Check if user has permission to access this incident | |
| # An Admin can access any incident in their department. | |
| # A regular user can only access their own incidents. | |
| is_admin = current_user.permissions == 'Admin' | |
| is_owner = str(incident.user_id) == str(current_user._id) | |
| in_department = str(incident.department_id) == str(current_user.department_id) | |
| if not in_department: | |
| return jsonify({'message': 'Cannot access incidents outside your department'}), 403 | |
| if not is_admin and not is_owner: | |
| return jsonify({'message': 'You do not have permission to access this incident'}), 403 | |
| # Return incident | |
| return jsonify({'incident': incident.to_dict()}), 200 | |
| except Exception as e: | |
| logger.error(f"Error getting incident: {str(e)}") | |
| return jsonify({'message': f'Error getting incident: {str(e)}'}), 500 | |
| def delete_incident(current_user, incident_id): | |
| """Delete incident by ID""" | |
| try: | |
| # Find incident by ID | |
| incident = Incident.find_by_id(incident_id) | |
| if not incident: | |
| return jsonify({'message': 'Incident not found'}), 404 | |
| # Check if user has access to this incident | |
| if not current_user.is_admin and str(incident.user_id) != str(current_user._id): | |
| return jsonify({'message': 'You do not have permission to delete this incident'}), 403 | |
| # Delete incident | |
| if incident.delete(): | |
| return jsonify({'message': 'Incident deleted successfully'}), 200 | |
| else: | |
| return jsonify({'message': 'Failed to delete incident'}), 500 | |
| except Exception as e: | |
| logger.error(f"Error deleting incident: {str(e)}") | |
| return jsonify({'message': f'Error deleting incident: {str(e)}'}), 500 | |
| def process_incident_sync(current_user, incident_id): | |
| """Process an incident synchronously (fill form with LLM)""" | |
| try: | |
| # Check if OpenAI API key is set | |
| api_key = os.environ.get('OPENAI_API_KEY') | |
| if not api_key: | |
| logger.error("OPENAI_API_KEY environment variable is not set") | |
| return jsonify({'message': 'OpenAI API key not configured'}), 500 | |
| # Create OpenAI client - removed any proxies parameter | |
| client = openai.OpenAI(api_key=api_key) | |
| # Find incident by ID | |
| incident = Incident.find_by_id(incident_id) | |
| if not incident: | |
| return jsonify({'message': 'Incident not found'}), 404 | |
| # Check if user has permission to process this incident | |
| # An Admin can process any incident in their department. | |
| # A regular user can only process their own incidents. | |
| is_admin = current_user.permissions == 'Admin' | |
| is_owner = str(incident.user_id) == str(current_user._id) | |
| in_department = str(incident.department_id) == str(current_user.department_id) | |
| # Check permissions based on role | |
| if not in_department: | |
| # Should generally not happen if incidents are fetched correctly, but good failsafe | |
| return jsonify({'message': 'Cannot process incidents outside your department'}), 403 | |
| if not is_admin and not is_owner: | |
| return jsonify({'message': 'You do not have permission to process this incident'}), 403 | |
| # Get the workflow for this incident | |
| workflow = Workflow.find_by_id(incident.workflow_id) | |
| if not workflow: | |
| return jsonify({'message': 'Workflow not found for this incident'}), 404 | |
| # Check if workflow has a template | |
| if not workflow.markdown_template: | |
| return jsonify({'message': 'No form template found for this workflow'}), 404 | |
| # Extract required data from incident | |
| logger.info(f"Extracting required data for incident {incident_id}") | |
| required_data = extract_required_data(incident.activity_text, workflow.data_requirements) | |
| # Store the extracted data in the incident | |
| incident.extracted_data = required_data | |
| # Fill markdown form | |
| logger.info(f"Filling form for incident {incident_id}") | |
| filled_markdown = fill_markdown_form(workflow.markdown_template, required_data) | |
| # Update incident status | |
| incident.status = "completed" | |
| if incident.save(): | |
| return jsonify({ | |
| 'message': 'Incident processed successfully', | |
| 'incident': incident.to_dict(), | |
| 'filled_markdown': filled_markdown | |
| }), 200 | |
| else: | |
| return jsonify({'message': 'Failed to update incident'}), 500 | |
| except Exception as e: | |
| logger.error(f"Error processing incident {incident_id}: {str(e)}") | |
| return jsonify({'message': f'Error processing incident: {str(e)}'}), 500 | |
| def get_user_incidents(current_user): | |
| """Get all incidents for the current user""" | |
| try: | |
| # Find incidents by user ID | |
| incidents = Incident.find_by_user(current_user._id) | |
| # Convert incidents to dict | |
| incidents_dict = [incident.to_dict() for incident in incidents] | |
| return jsonify({'incidents': incidents_dict}), 200 | |
| except Exception as e: | |
| logger.error(f"Error getting user incidents: {str(e)}") | |
| return jsonify({'message': f'Error getting user incidents: {str(e)}'}), 500 | |
| def get_department_incidents(current_user): | |
| """Get all incidents for the user's department""" | |
| incidents = Incident.find_by_department(current_user.department_id) | |
| return jsonify({'incidents': [incident.to_dict() for incident in incidents]}), 200 | |
| def get_workflow_incidents(current_user, workflow_id): | |
| """Get all incidents for a specific workflow""" | |
| # Check if workflow exists and belongs to user's department | |
| workflow = Workflow.find_by_id(workflow_id) | |
| if not workflow: | |
| return jsonify({'message': 'Workflow not found'}), 404 | |
| if str(workflow.department_id) != str(current_user.department_id): | |
| return jsonify({'message': 'Access denied to workflows from other departments'}), 403 | |
| incidents = Incident.find_by_workflow(workflow_id) | |
| return jsonify({'incidents': [incident.to_dict() for incident in incidents]}), 200 | |
| def get_incidents_by_date_range(current_user): | |
| """Get incidents by date range""" | |
| data = request.get_json() | |
| # Check if required fields are present | |
| if 'start_date' not in data or 'end_date' not in data: | |
| return jsonify({'message': 'Start date and end date are required'}), 400 | |
| try: | |
| # Parse date strings | |
| start_date = datetime.strptime(data['start_date'], '%Y-%m-%d').date() | |
| end_date = datetime.strptime(data['end_date'], '%Y-%m-%d').date() | |
| # Get incidents by date range | |
| incidents = Incident.find_by_date_range(current_user.department_id, start_date, end_date) | |
| return jsonify({'incidents': [incident.to_dict() for incident in incidents]}), 200 | |
| except ValueError: | |
| return jsonify({'message': 'Invalid date format. Please use YYYY-MM-DD'}), 400 | |
| except Exception as e: | |
| logger.error(f"Error fetching incidents by date range: {str(e)}") | |
| return jsonify({'message': f'Error fetching incidents: {str(e)}'}), 500 | |
| def reprocess_incident(current_user, incident_id): | |
| """Reprocess an incident to generate forms""" | |
| # Check if user has admin permissions | |
| if current_user.permissions != 'Admin': | |
| return jsonify({'message': 'Admin permissions required'}), 403 | |
| incident = Incident.find_by_id(incident_id) | |
| if not incident: | |
| return jsonify({'message': 'Incident not found'}), 404 | |
| # Check if user has access to this incident | |
| if str(incident.department_id) != str(current_user.department_id): | |
| return jsonify({'message': 'Access denied to incidents from other departments'}), 403 | |
| try: | |
| # Update incident status | |
| incident.update_status("processing") | |
| # Queue incident for processing | |
| process_incident_forms.delay(str(incident._id)) | |
| return jsonify({ | |
| 'message': 'Incident reprocessing started', | |
| 'incident': incident.to_dict() | |
| }), 200 | |
| except Exception as e: | |
| logger.error(f"Error reprocessing incident {incident_id}: {str(e)}") | |
| incident.update_status("failed") | |
| return jsonify({'message': f'Error reprocessing incident: {str(e)}'}), 500 | |
| def create_incident_from_activity(current_user): | |
| """Create an incident from activity data and workflow ID""" | |
| try: | |
| data = request.get_json() | |
| # Check if required fields are present | |
| required_fields = ['activity', 'workflow_id', 'date', 'log_text'] | |
| for field in required_fields: | |
| if field not in data: | |
| return jsonify({'message': f'Missing required field: {field}'}), 400 | |
| # Validate date format | |
| try: | |
| if isinstance(data['date'], str): | |
| date = datetime.strptime(data['date'], '%Y-%m-%d').date() | |
| else: | |
| date = data['date'] | |
| except ValueError: | |
| return jsonify({'message': 'Invalid date format. Please use YYYY-MM-DD'}), 400 | |
| # Check if workflow exists and user has access | |
| workflow = Workflow.find_by_id(data['workflow_id']) | |
| if not workflow: | |
| return jsonify({'message': 'Workflow not found'}), 404 | |
| # Check if user has access to this workflow | |
| if str(workflow.department_id) != str(current_user.department_id): | |
| return jsonify({'message': 'Access denied to workflows from other departments'}), 403 | |
| # Create log entry first if log_id is not provided | |
| log_id = data.get('log_id') | |
| if not log_id: | |
| log = Log( | |
| user_id=current_user._id, | |
| department_id=current_user.department_id, | |
| log_date=date, | |
| log_text=data['log_text'] | |
| ) | |
| if log.save(): | |
| log_id = log._id | |
| # Create the incident | |
| incident = Incident( | |
| department_id=current_user.department_id, | |
| user_id=current_user._id, | |
| workflow_id=ObjectId(data['workflow_id']), | |
| description=data['activity'].get('activity', 'No description'), | |
| date=date, | |
| activity_text=data['activity'].get('text', ''), | |
| log_id=log_id, | |
| status="pending" | |
| ) | |
| if incident.save(): | |
| # Add incident to log if log exists | |
| if log_id: | |
| log = Log.find_by_id(log_id) | |
| if log: | |
| log.add_incident(incident._id) | |
| return jsonify({ | |
| 'message': 'Incident created successfully', | |
| 'incident': incident.to_dict() | |
| }), 201 | |
| else: | |
| return jsonify({'message': 'Failed to create incident'}), 500 | |
| except Exception as e: | |
| logger.error(f"Error creating incident from activity: {str(e)}") | |
| return jsonify({'message': f'Error creating incident: {str(e)}'}), 500 |