import uuid from sqlalchemy import Column, String, Text, DateTime, ForeignKey, Enum, Index, JSON from sqlalchemy.sql import func from sqlalchemy.orm import relationship from app.core.database import Base import enum class AuditAction(str, enum.Enum): CREATE = "create" UPDATE = "update" DELETE = "delete" RESTORE = "restore" LOGIN = "login" LOGOUT = "logout" class SensitivityLevel(str, enum.Enum): LOW = "low" MEDIUM = "medium" HIGH = "high" CRITICAL = "critical" # Event type to sensitivity level mapping EVENT_SENSITIVITY = { "task.create": SensitivityLevel.LOW, "task.update": SensitivityLevel.LOW, "task.delete": SensitivityLevel.MEDIUM, "task.assign": SensitivityLevel.LOW, "task.blocker": SensitivityLevel.MEDIUM, "project.create": SensitivityLevel.MEDIUM, "project.update": SensitivityLevel.MEDIUM, "project.delete": SensitivityLevel.HIGH, "user.login": SensitivityLevel.LOW, "user.logout": SensitivityLevel.LOW, "user.permission_change": SensitivityLevel.CRITICAL, "attachment.upload": SensitivityLevel.LOW, "attachment.download": SensitivityLevel.LOW, "attachment.delete": SensitivityLevel.MEDIUM, } # Events that should trigger alerts ALERT_EVENTS = {"project.delete", "user.permission_change"} class AuditLog(Base): __tablename__ = "pjctrl_audit_logs" id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) event_type = Column(String(50), nullable=False) resource_type = Column(String(50), nullable=False) resource_id = Column(String(36), nullable=True) user_id = Column(String(36), ForeignKey("pjctrl_users.id", ondelete="SET NULL"), nullable=True) action = Column( Enum("create", "update", "delete", "restore", "login", "logout", name="audit_action_enum"), nullable=False ) changes = Column(JSON, nullable=True) request_metadata = Column(JSON, nullable=True) sensitivity_level = Column( Enum("low", "medium", "high", "critical", name="sensitivity_level_enum"), default="low", nullable=False ) checksum = Column(String(64), nullable=False) created_at = Column(DateTime, server_default=func.now(), nullable=False) # Relationships user = relationship("User", foreign_keys=[user_id]) alerts = relationship("AuditAlert", back_populates="audit_log", cascade="all, delete-orphan") __table_args__ = ( Index("idx_audit_user", "user_id", "created_at"), Index("idx_audit_resource", "resource_type", "resource_id", "created_at"), Index("idx_audit_time", "created_at"), )