""" Security/deployment models — signing_keys, key_rotation_log, config_versions, deployment_events. Maps to AGENT.md DBML: Lines 675-734. """ from django.conf import settings from django.db import models from core.models import BaseModel class ConfigVersion(models.Model): """Tracks configuration version deployments.""" version = models.CharField(max_length=50, primary_key=True) checksum = models.CharField(max_length=64, blank=True, default="") applied_at = models.DateTimeField(auto_now_add=True) class Meta: db_table = "config_versions" def __str__(self) -> str: return self.version class DeploymentEvent(BaseModel): """Records deployment lifecycle events.""" class Status(models.TextChoices): STARTED = "started", "Started" COMPLETED = "completed", "Completed" FAILED = "failed", "Failed" ROLLED_BACK = "rolled_back", "Rolled Back" version = models.CharField(max_length=50) status = models.CharField(max_length=20, choices=Status.choices, default=Status.STARTED) started_at = models.DateTimeField(null=True, blank=True) finished_at = models.DateTimeField(null=True, blank=True) class Meta: db_table = "deployment_events" ordering = ["-created_at"] def __str__(self) -> str: return f"Deploy {self.version} ({self.get_status_display()})" class SigningKey(BaseModel): """Cryptographic signing keys for tokens/webhooks.""" public_key = models.TextField() private_ref = models.CharField(max_length=255) algorithm = models.CharField(max_length=20, default="RS256") active = models.BooleanField(default=True) rotated_at = models.DateTimeField(auto_now_add=True) class Meta: db_table = "signing_keys" def __str__(self) -> str: return f"Key {self.pk} ({self.algorithm})" class KeyRotationLog(BaseModel): """Tracks signing key rotation events.""" key = models.ForeignKey( SigningKey, on_delete=models.CASCADE, related_name="rotation_logs", ) rotated_by = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name="key_rotations", ) rotated_at = models.DateTimeField(auto_now_add=True) class Meta: db_table = "key_rotation_log" ordering = ["-rotated_at"] def __str__(self) -> str: return f"Rotation of {self.key_id}"