Files
agentic-soc-platform/backend/apps/cases/models.py

128 lines
5.5 KiB
Python

from django.conf import settings
from django.db import models
from apps.common.models import BaseModel
from apps.common.readable_ids import save_with_readable_id
class CaseSeverity(models.TextChoices):
UNKNOWN = "Unknown"
INFORMATIONAL = "Informational"
LOW = "Low"
MEDIUM = "Medium"
HIGH = "High"
CRITICAL = "Critical"
class CaseImpact(models.TextChoices):
UNKNOWN = "Unknown"
LOW = "Low"
MEDIUM = "Medium"
HIGH = "High"
CRITICAL = "Critical"
class CasePriority(models.TextChoices):
UNKNOWN = "Unknown"
LOW = "Low"
MEDIUM = "Medium"
HIGH = "High"
CRITICAL = "Critical"
class CaseConfidence(models.TextChoices):
UNKNOWN = "Unknown"
LOW = "Low"
MEDIUM = "Medium"
HIGH = "High"
class CaseStatus(models.TextChoices):
NEW = "New"
IN_PROGRESS = "In Progress"
ON_HOLD = "On Hold"
RESOLVED = "Resolved"
CLOSED = "Closed"
class CaseVerdict(models.TextChoices):
UNKNOWN = "Unknown"
FALSE_POSITIVE = "False Positive"
TRUE_POSITIVE = "True Positive"
DISREGARD = "Disregard"
SUSPICIOUS = "Suspicious"
BENIGN = "Benign"
TEST = "Test"
INSUFFICIENT_DATA = "Insufficient Data"
SECURITY_RISK = "Security Risk"
MANAGED_EXTERNALLY = "Managed Externally"
DUPLICATE = "Duplicate"
OTHER = "Other"
class CaseCategory(models.TextChoices):
DLP = "DLP", "DLP"
EMAIL = "Email"
OT = "OT", "OT"
PROXY = "Proxy"
UEBA = "UEBA", "UEBA"
TI = "ThreatIntelligence", "TI"
IAM = "IAM", "IAM"
EDR = "EDR", "EDR"
NDR = "NDR", "NDR"
CLOUD = "Cloud"
SIEM = "SIEM", "SIEM"
WAF = "WAF", "WAF"
OTHER = "Other"
class Case(BaseModel):
case_id = models.CharField(max_length=32, unique=True, editable=False, db_index=True, blank=True, default="", help_text="Record ID e.g. case_000001 (记录 ID e.g. case_000001,系统自动生成,无需手动赋值)")
title = models.CharField(max_length=500, help_text="Case title (案件标题)")
severity = models.CharField(max_length=20, choices=CaseSeverity, blank=True, default="", help_text="Analyst-assessed severity (严重程度)")
impact = models.CharField(max_length=20, choices=CaseImpact, blank=True, default="", help_text="Analyst-assessed impact (影响)")
priority = models.CharField(max_length=20, choices=CasePriority, blank=True, default="", help_text="Response priority (响应优先级)")
confidence = models.CharField(max_length=20, choices=CaseConfidence, blank=True, default="", help_text="Analyst-assessed confidence (分析师评估置信度)")
description = models.TextField(blank=True, default="", help_text="Case description (案件描述)")
category = models.CharField(max_length=30, choices=CaseCategory, blank=True, default="", help_text="Case category (案件类别)")
tags = models.JSONField(default=list, blank=True, help_text="Case tags (案件标签)")
status = models.CharField(max_length=20, choices=CaseStatus, default=CaseStatus.NEW, help_text="Case handling status (案件处理状态)")
verdict = models.CharField(max_length=30, choices=CaseVerdict, blank=True, default="", help_text="Final verdict (最终判定结果)")
summary = models.TextField(blank=True, default="", help_text="Closure summary (结案摘要)")
assignee = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="assigned_cases",
help_text="Current assigned analyst handling the case (当前正在处理案件的分析师)",
)
acknowledged_time = models.DateTimeField(null=True, blank=True, help_text="L1 first acknowledged time (L1 首次接手时间)")
closed_time = models.DateTimeField(null=True, blank=True, help_text="case close time (事件关闭时间)")
correlation_uid = models.CharField(max_length=255, blank=True, default="", db_index=True, help_text="Case correlation ID (案件关联 ID)")
# AI fields
severity_ai = models.CharField(max_length=20, choices=CaseSeverity, blank=True, default="", help_text="AI-assessed severity (AI 评估严重程度)")
confidence_ai = models.CharField(max_length=20, choices=CaseConfidence, blank=True, default="", help_text="AI-assessed confidence (AI 评估置信度)")
impact_ai = models.CharField(max_length=20, choices=CaseImpact, blank=True, default="", help_text="AI-assessed impact (AI 评估影响)")
priority_ai = models.CharField(max_length=20, choices=CasePriority, blank=True, default="", help_text="AI-assessed response priority (AI 评估响应优先级)")
verdict_ai = models.CharField(max_length=30, choices=CaseVerdict, blank=True, default="", help_text="AI-generated final verdict (AI 生成的最终判定结果)")
investigation_report_ai_json = models.TextField(blank=True, default="", help_text="AI-generated investigation report JSON Format (AI 生成的调查报告 JSON 格式)")
def save(self, *args, **kwargs):
return save_with_readable_id(self, "case_id", "case", *args, **kwargs)
class Meta:
db_table = "cases"
ordering = ["-created_at"]
indexes = [
models.Index(fields=["-created_at", "-id"], name="case_created_id_idx"),
models.Index(fields=["status", "severity"], name="case_status_severity_idx"),
models.Index(fields=["updated_at"], name="case_updated_at_idx"),
models.Index(fields=["acknowledged_time"], name="case_ack_time_idx"),
models.Index(fields=["closed_time"], name="case_closed_time_idx"),
]
def __str__(self):
return self.title or str(self.id)