package incidents import ( "time" "github.com/google/uuid" ) // ============================================================================ // Constants / Enums // ============================================================================ // IncidentCategory represents the category of a security/data breach incident type IncidentCategory string const ( IncidentCategoryDataBreach IncidentCategory = "data_breach" IncidentCategoryUnauthorizedAccess IncidentCategory = "unauthorized_access" IncidentCategoryDataLoss IncidentCategory = "data_loss" IncidentCategorySystemCompromise IncidentCategory = "system_compromise" IncidentCategoryPhishing IncidentCategory = "phishing" IncidentCategoryRansomware IncidentCategory = "ransomware" IncidentCategoryInsiderThreat IncidentCategory = "insider_threat" IncidentCategoryPhysicalBreach IncidentCategory = "physical_breach" IncidentCategoryOther IncidentCategory = "other" ) // IncidentStatus represents the status of an incident through its lifecycle type IncidentStatus string const ( IncidentStatusDetected IncidentStatus = "detected" IncidentStatusAssessment IncidentStatus = "assessment" IncidentStatusContainment IncidentStatus = "containment" IncidentStatusNotificationRequired IncidentStatus = "notification_required" IncidentStatusNotificationSent IncidentStatus = "notification_sent" IncidentStatusRemediation IncidentStatus = "remediation" IncidentStatusClosed IncidentStatus = "closed" ) // IncidentSeverity represents the severity level of an incident type IncidentSeverity string const ( IncidentSeverityCritical IncidentSeverity = "critical" IncidentSeverityHigh IncidentSeverity = "high" IncidentSeverityMedium IncidentSeverity = "medium" IncidentSeverityLow IncidentSeverity = "low" ) // MeasureType represents the type of corrective measure type MeasureType string const ( MeasureTypeImmediate MeasureType = "immediate" MeasureTypeLongTerm MeasureType = "long_term" ) // MeasureStatus represents the status of a corrective measure type MeasureStatus string const ( MeasureStatusPlanned MeasureStatus = "planned" MeasureStatusInProgress MeasureStatus = "in_progress" MeasureStatusCompleted MeasureStatus = "completed" ) // NotificationStatus represents the status of a notification (authority or data subject) type NotificationStatus string const ( NotificationStatusNotRequired NotificationStatus = "not_required" NotificationStatusPending NotificationStatus = "pending" NotificationStatusSent NotificationStatus = "sent" NotificationStatusConfirmed NotificationStatus = "confirmed" ) // ============================================================================ // Main Entities // ============================================================================ // Incident represents a security or data breach incident per DSGVO Art. 33/34 type Incident struct { ID uuid.UUID `json:"id"` TenantID uuid.UUID `json:"tenant_id"` // Incident info Title string `json:"title"` Description string `json:"description,omitempty"` Category IncidentCategory `json:"category"` Status IncidentStatus `json:"status"` Severity IncidentSeverity `json:"severity"` // Detection & reporting DetectedAt time.Time `json:"detected_at"` ReportedBy uuid.UUID `json:"reported_by"` // Affected scope AffectedDataCategories []string `json:"affected_data_categories"` // JSONB AffectedDataSubjectCount int `json:"affected_data_subject_count"` AffectedSystems []string `json:"affected_systems"` // JSONB // Assessments & notifications (JSONB embedded objects) RiskAssessment *RiskAssessment `json:"risk_assessment,omitempty"` AuthorityNotification *AuthorityNotification `json:"authority_notification,omitempty"` DataSubjectNotification *DataSubjectNotification `json:"data_subject_notification,omitempty"` // Resolution RootCause string `json:"root_cause,omitempty"` LessonsLearned string `json:"lessons_learned,omitempty"` // Timeline (JSONB array) Timeline []TimelineEntry `json:"timeline"` // Audit CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` ClosedAt *time.Time `json:"closed_at,omitempty"` } // RiskAssessment contains the risk assessment for an incident type RiskAssessment struct { Likelihood int `json:"likelihood"` // 1-5 Impact int `json:"impact"` // 1-5 RiskLevel string `json:"risk_level"` // critical, high, medium, low (auto-calculated) AssessedAt time.Time `json:"assessed_at"` AssessedBy uuid.UUID `json:"assessed_by"` Notes string `json:"notes,omitempty"` } // AuthorityNotification tracks the supervisory authority notification per DSGVO Art. 33 type AuthorityNotification struct { Status NotificationStatus `json:"status"` Deadline time.Time `json:"deadline"` // 72h from detected_at per Art. 33 SubmittedAt *time.Time `json:"submitted_at,omitempty"` AuthorityName string `json:"authority_name,omitempty"` ReferenceNumber string `json:"reference_number,omitempty"` ContactPerson string `json:"contact_person,omitempty"` Notes string `json:"notes,omitempty"` } // DataSubjectNotification tracks the data subject notification per DSGVO Art. 34 type DataSubjectNotification struct { Required bool `json:"required"` Status NotificationStatus `json:"status"` SentAt *time.Time `json:"sent_at,omitempty"` AffectedCount int `json:"affected_count"` NotificationText string `json:"notification_text,omitempty"` Channel string `json:"channel,omitempty"` // email, letter, website } // TimelineEntry represents a single event in the incident timeline type TimelineEntry struct { Timestamp time.Time `json:"timestamp"` Action string `json:"action"` UserID uuid.UUID `json:"user_id"` Details string `json:"details,omitempty"` } // IncidentMeasure represents a corrective or preventive measure for an incident type IncidentMeasure struct { ID uuid.UUID `json:"id"` IncidentID uuid.UUID `json:"incident_id"` Title string `json:"title"` Description string `json:"description,omitempty"` MeasureType MeasureType `json:"measure_type"` Status MeasureStatus `json:"status"` Responsible string `json:"responsible,omitempty"` DueDate *time.Time `json:"due_date,omitempty"` CompletedAt *time.Time `json:"completed_at,omitempty"` CreatedAt time.Time `json:"created_at"` } // IncidentStatistics contains aggregated incident statistics for a tenant type IncidentStatistics struct { TotalIncidents int `json:"total_incidents"` OpenIncidents int `json:"open_incidents"` ByStatus map[string]int `json:"by_status"` BySeverity map[string]int `json:"by_severity"` ByCategory map[string]int `json:"by_category"` NotificationsPending int `json:"notifications_pending"` AvgResolutionHours float64 `json:"avg_resolution_hours"` } // ============================================================================ // API Request/Response Types // ============================================================================ // CreateIncidentRequest is the API request for creating an incident type CreateIncidentRequest struct { Title string `json:"title" binding:"required"` Description string `json:"description,omitempty"` Category IncidentCategory `json:"category" binding:"required"` Severity IncidentSeverity `json:"severity" binding:"required"` DetectedAt *time.Time `json:"detected_at,omitempty"` // defaults to now AffectedDataCategories []string `json:"affected_data_categories,omitempty"` AffectedDataSubjectCount int `json:"affected_data_subject_count,omitempty"` AffectedSystems []string `json:"affected_systems,omitempty"` } // UpdateIncidentRequest is the API request for updating an incident type UpdateIncidentRequest struct { Title string `json:"title,omitempty"` Description string `json:"description,omitempty"` Category IncidentCategory `json:"category,omitempty"` Status IncidentStatus `json:"status,omitempty"` Severity IncidentSeverity `json:"severity,omitempty"` AffectedDataCategories []string `json:"affected_data_categories,omitempty"` AffectedDataSubjectCount *int `json:"affected_data_subject_count,omitempty"` AffectedSystems []string `json:"affected_systems,omitempty"` } // RiskAssessmentRequest is the API request for assessing risk type RiskAssessmentRequest struct { Likelihood int `json:"likelihood" binding:"required,min=1,max=5"` Impact int `json:"impact" binding:"required,min=1,max=5"` Notes string `json:"notes,omitempty"` } // SubmitAuthorityNotificationRequest is the API request for submitting authority notification type SubmitAuthorityNotificationRequest struct { AuthorityName string `json:"authority_name" binding:"required"` ContactPerson string `json:"contact_person,omitempty"` ReferenceNumber string `json:"reference_number,omitempty"` Notes string `json:"notes,omitempty"` } // NotifyDataSubjectsRequest is the API request for notifying data subjects type NotifyDataSubjectsRequest struct { NotificationText string `json:"notification_text" binding:"required"` Channel string `json:"channel" binding:"required"` // email, letter, website AffectedCount int `json:"affected_count,omitempty"` } // AddMeasureRequest is the API request for adding a corrective measure type AddMeasureRequest struct { Title string `json:"title" binding:"required"` Description string `json:"description,omitempty"` MeasureType MeasureType `json:"measure_type" binding:"required"` Responsible string `json:"responsible,omitempty"` DueDate *time.Time `json:"due_date,omitempty"` } // CloseIncidentRequest is the API request for closing an incident type CloseIncidentRequest struct { RootCause string `json:"root_cause" binding:"required"` LessonsLearned string `json:"lessons_learned,omitempty"` } // AddTimelineEntryRequest is the API request for adding a timeline entry type AddTimelineEntryRequest struct { Action string `json:"action" binding:"required"` Details string `json:"details,omitempty"` } // IncidentListResponse is the API response for listing incidents type IncidentListResponse struct { Incidents []Incident `json:"incidents"` Total int `json:"total"` } // IncidentFilters defines filters for listing incidents type IncidentFilters struct { Status IncidentStatus Severity IncidentSeverity Category IncidentCategory Limit int Offset int } // ============================================================================ // Helper Functions // ============================================================================ // CalculateRiskLevel calculates the risk level from likelihood and impact scores. // Risk score = likelihood * impact. Thresholds: // - critical: score >= 20 // - high: score >= 12 // - medium: score >= 6 // - low: score < 6 func CalculateRiskLevel(likelihood, impact int) string { score := likelihood * impact switch { case score >= 20: return "critical" case score >= 12: return "high" case score >= 6: return "medium" default: return "low" } } // Calculate72hDeadline calculates the 72-hour notification deadline per DSGVO Art. 33. // The supervisory authority must be notified within 72 hours of becoming aware of a breach. func Calculate72hDeadline(detectedAt time.Time) time.Time { return detectedAt.Add(72 * time.Hour) } // IsNotificationRequired determines whether authority notification is required // based on the assessed risk level. Notification is required for critical and high risk. func IsNotificationRequired(riskLevel string) bool { return riskLevel == "critical" || riskLevel == "high" }