""" SecurityEvent model — structured security event log. Maps to AGENT.md DBML: `security_events` table (Lines 254-260). """ from django.conf import settings from django.db import models from core.models import BaseModel class SecurityEvent(BaseModel): """ Records security-relevant events for a user. Used for security alerts and anomaly detection. Events are append-only — never updated or deleted. """ class EventType(models.TextChoices): PASSWORD_CHANGE = "password_change", "Password Changed" PASSWORD_RESET = "password_reset", "Password Reset" EMAIL_CHANGE = "email_change", "Email Changed" MFA_ENABLE = "mfa_enable", "MFA Enabled" MFA_DISABLE = "mfa_disable", "MFA Disabled" LOGIN_SUCCESS = "login_success", "Login Success" LOGIN_FAILURE = "login_failure", "Login Failure" DEVICE_NEW = "device_new", "New Device Detected" SESSION_REVOKE = "session_revoke", "Session Revoked" ACCOUNT_LOCKED = "account_locked", "Account Locked" ACCOUNT_SUSPENDED = "account_suspended", "Account Suspended" user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="security_events", ) event_type = models.CharField( max_length=50, choices=EventType.choices, ) metadata = models.JSONField( default=dict, blank=True, help_text="Additional event-specific data (IP, device info, etc.).", ) class Meta: db_table = "security_events" ordering = ["-created_at"] indexes = [ models.Index(fields=["user", "-created_at"]), models.Index(fields=["event_type", "-created_at"]), ] def __str__(self) -> str: return f"{self.get_event_type_display()} — {self.user_id}"