"""TestDetectionResult — tracks which detection rules triggered during a test. When the Blue Team evaluates a test, they mark each associated detection rule as triggered / not triggered / not applicable, along with notes. """ import uuid from datetime import datetime from sqlalchemy import Column, String, Text, Boolean, DateTime, ForeignKey, Index, UniqueConstraint from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import relationship from app.database import Base class TestDetectionResult(Base): """ Per-test, per-rule evaluation result. - ``triggered`` = True: rule detected the attack - ``triggered`` = False: rule did NOT detect the attack - ``triggered`` = None: not yet evaluated """ __tablename__ = "test_detection_results" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) test_id = Column( UUID(as_uuid=True), ForeignKey("tests.id", ondelete="CASCADE"), nullable=False, ) detection_rule_id = Column( UUID(as_uuid=True), ForeignKey("detection_rules.id", ondelete="CASCADE"), nullable=False, ) triggered = Column(Boolean, nullable=True) # None = not evaluated notes = Column(Text, nullable=True) evaluated_by = Column( UUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True, ) evaluated_at = Column(DateTime, nullable=True) # Relationships test = relationship("Test") detection_rule = relationship("DetectionRule") evaluator = relationship("User", foreign_keys=[evaluated_by]) __table_args__ = ( Index('ix_tdr_test', 'test_id'), Index('ix_tdr_rule', 'detection_rule_id'), UniqueConstraint('test_id', 'detection_rule_id', name='uq_tdr_test_rule'), )