Spaces:
Sleeping
Sleeping
| """ | |
| INCIDENTS API - Support Request Management | |
| Endpoints for: | |
| 1. Create incidents (customer reports issue) | |
| 2. List/get incidents with filters | |
| 3. Update/resolve/cancel incidents | |
| 4. Incident statistics | |
| Authorization: | |
| - platform_admin: Full access | |
| - project_manager: Their projects only | |
| - dispatcher: Their contractor's projects | |
| - client_admin: View only | |
| """ | |
| from fastapi import APIRouter, Depends, status, Query | |
| from sqlalchemy.orm import Session | |
| from typing import List, Optional | |
| from uuid import UUID | |
| from math import ceil | |
| from app.api.deps import get_db, get_current_user | |
| from app.models.user import User | |
| from app.services.incident_service import IncidentService | |
| from app.schemas.incident import * | |
| router = APIRouter() | |
| # ============================================ | |
| # CREATE INCIDENTS | |
| # ============================================ | |
| def create_incident( | |
| data: IncidentCreate, | |
| db: Session = Depends(get_db), | |
| current_user: User = Depends(get_current_user) | |
| ): | |
| """ | |
| Create incident (support request from customer). | |
| **Authorization:** PM, Dispatcher, Platform Admin | |
| **Workflow:** | |
| 1. Customer reports problem with existing service | |
| 2. Support creates incident with status='open' | |
| 3. Can be promoted to ticket for field technician dispatch | |
| **Example:** | |
| ```json | |
| { | |
| "customer_id": "uuid-here", | |
| "subscription_id": "uuid-here", | |
| "project_id": "uuid-here", | |
| "incident_type": "no_service", | |
| "issue_description": "Customer reports no internet for 2 days", | |
| "priority": "urgent" | |
| } | |
| ``` | |
| """ | |
| incident = IncidentService.create_incident( | |
| db=db, | |
| data=data, | |
| current_user=current_user | |
| ) | |
| # Populate response | |
| response = IncidentResponse.from_orm(incident) | |
| if incident.customer: | |
| response.customer_name = incident.customer.customer_name | |
| if incident.project: | |
| response.project_name = incident.project.title | |
| return response | |
| # ============================================ | |
| # GET INCIDENTS | |
| # ============================================ | |
| def get_incident( | |
| incident_id: UUID, | |
| db: Session = Depends(get_db), | |
| current_user: User = Depends(get_current_user) | |
| ): | |
| """ | |
| Get incident details by ID. | |
| **Authorization:** PM, Dispatcher, Client Admin, Platform Admin | |
| """ | |
| incident = IncidentService.get_incident( | |
| db=db, | |
| incident_id=incident_id, | |
| current_user=current_user | |
| ) | |
| # Populate response | |
| response = IncidentResponse.from_orm(incident) | |
| if incident.customer: | |
| response.customer_name = incident.customer.customer_name | |
| if incident.project: | |
| response.project_name = incident.project.title | |
| return response | |
| def list_incidents( | |
| project_id: Optional[UUID] = Query(None, description="Filter by project"), | |
| customer_id: Optional[UUID] = Query(None, description="Filter by customer"), | |
| status: Optional[str] = Query(None, description="Filter by status (open, ticket_created, resolved, closed, cancelled)"), | |
| priority: Optional[str] = Query(None, description="Filter by priority (low, normal, high, urgent)"), | |
| incident_type: Optional[str] = Query(None, description="Filter by incident type"), | |
| page: int = Query(1, ge=1, description="Page number"), | |
| page_size: int = Query(50, ge=1, le=100, description="Items per page"), | |
| db: Session = Depends(get_db), | |
| current_user: User = Depends(get_current_user) | |
| ): | |
| """ | |
| List incidents with filters and pagination. | |
| **Authorization:** PM, Dispatcher, Client Admin, Platform Admin | |
| **Filters:** | |
| - project_id: Filter by project | |
| - customer_id: Filter by customer | |
| - status: open, ticket_created, resolved, closed, cancelled | |
| - priority: low, normal, high, urgent | |
| - incident_type: no_service, slow_speed, equipment_fault, etc. | |
| """ | |
| incidents, total = IncidentService.list_incidents( | |
| db=db, | |
| current_user=current_user, | |
| project_id=project_id, | |
| customer_id=customer_id, | |
| status=status, | |
| priority=priority, | |
| incident_type=incident_type, | |
| page=page, | |
| page_size=page_size | |
| ) | |
| # Populate responses | |
| incident_responses = [] | |
| for incident in incidents: | |
| response = IncidentResponse.from_orm(incident) | |
| if incident.customer: | |
| response.customer_name = incident.customer.customer_name | |
| if incident.project: | |
| response.project_name = incident.project.title | |
| incident_responses.append(response) | |
| return IncidentListResponse( | |
| incidents=incident_responses, | |
| total=total, | |
| page=page, | |
| page_size=page_size, | |
| total_pages=ceil(total / page_size) | |
| ) | |
| # ============================================ | |
| # UPDATE INCIDENTS | |
| # ============================================ | |
| def update_incident( | |
| incident_id: UUID, | |
| data: IncidentUpdate, | |
| db: Session = Depends(get_db), | |
| current_user: User = Depends(get_current_user) | |
| ): | |
| """ | |
| Update incident details (open incidents only). | |
| **Authorization:** PM, Dispatcher, Platform Admin | |
| """ | |
| incident = IncidentService.update_incident( | |
| db=db, | |
| incident_id=incident_id, | |
| data=data, | |
| current_user=current_user | |
| ) | |
| # Populate response | |
| response = IncidentResponse.from_orm(incident) | |
| if incident.customer: | |
| response.customer_name = incident.customer.customer_name | |
| if incident.project: | |
| response.project_name = incident.project.title | |
| return response | |
| # ============================================ | |
| # INCIDENT RESOLUTION | |
| # ============================================ | |
| def resolve_incident( | |
| incident_id: UUID, | |
| data: IncidentResolve, | |
| db: Session = Depends(get_db), | |
| current_user: User = Depends(get_current_user) | |
| ): | |
| """ | |
| Mark incident as resolved. | |
| **Authorization:** PM, Dispatcher, Platform Admin | |
| Typically called when support ticket completes. | |
| """ | |
| incident = IncidentService.resolve_incident( | |
| db=db, | |
| incident_id=incident_id, | |
| data=data, | |
| current_user=current_user | |
| ) | |
| # Populate response | |
| response = IncidentResponse.from_orm(incident) | |
| if incident.customer: | |
| response.customer_name = incident.customer.customer_name | |
| if incident.project: | |
| response.project_name = incident.project.title | |
| return response | |
| def cancel_incident( | |
| incident_id: UUID, | |
| data: IncidentCancel, | |
| db: Session = Depends(get_db), | |
| current_user: User = Depends(get_current_user) | |
| ): | |
| """ | |
| Cancel incident (false alarm or customer withdrew complaint). | |
| **Authorization:** PM, Dispatcher, Platform Admin | |
| """ | |
| incident = IncidentService.cancel_incident( | |
| db=db, | |
| incident_id=incident_id, | |
| data=data, | |
| current_user=current_user | |
| ) | |
| # Populate response | |
| response = IncidentResponse.from_orm(incident) | |
| if incident.customer: | |
| response.customer_name = incident.customer.customer_name | |
| if incident.project: | |
| response.project_name = incident.project.title | |
| return response | |