feat: Add Academy, Whistleblower, Incidents SDK modules, pitch-deck, blog and CI/CD config
Some checks failed
ci/woodpecker/push/integration Pipeline failed
ci/woodpecker/push/main Pipeline failed
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Some checks failed
ci/woodpecker/push/integration Pipeline failed
ci/woodpecker/push/main Pipeline failed
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
- Academy, Whistleblower, Incidents frontend pages with API proxies and types - Vendor compliance API proxy route - Go backend handlers and models for all new SDK modules - Investor pitch-deck app with interactive slides - Blog section with DSGVO, AI Act, NIS2, glossary articles - MkDocs documentation site - CI/CD pipelines (Woodpecker, GitHub Actions), security scanning config - Planning and implementation documentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
305
ai-compliance-sdk/internal/incidents/models.go
Normal file
305
ai-compliance-sdk/internal/incidents/models.go
Normal file
@@ -0,0 +1,305 @@
|
||||
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"
|
||||
}
|
||||
Reference in New Issue
Block a user