""" ISMS Governance models (ISO 27001 Kapitel 4-6) — extracted from compliance/db/models.py. Covers the documentation and planning side of the ISMS: scope, context, policies, security objectives, and the Statement of Applicability. The audit execution side (findings, CAPA, management reviews, internal audits, audit trail, readiness checks) lives in ``isms_audit_models.py``. Re-exported from ``compliance.db.models`` for backwards compatibility. DO NOT change __tablename__, column names, or relationship strings — the database schema is frozen. """ import uuid import enum from datetime import datetime, date, timezone from sqlalchemy import ( Column, String, Text, Integer, Boolean, DateTime, Date, ForeignKey, Enum, JSON, Index, ) from classroom_engine.database import Base # ============================================================================ # SHARED GOVERNANCE ENUMS # ============================================================================ class ApprovalStatusEnum(str, enum.Enum): """Approval status for ISMS documents.""" DRAFT = "draft" UNDER_REVIEW = "under_review" APPROVED = "approved" SUPERSEDED = "superseded" # ============================================================================ # MODELS # ============================================================================ class ISMSScopeDB(Base): """ ISMS Scope Definition (ISO 27001 Kapitel 4.3) Defines the boundaries and applicability of the ISMS. This is MANDATORY for certification. """ __tablename__ = 'compliance_isms_scope' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) version = Column(String(20), nullable=False, default="1.0") # Scope definition scope_statement = Column(Text, nullable=False) # Main scope text included_locations = Column(JSON) # List of locations included_processes = Column(JSON) # List of processes included_services = Column(JSON) # List of services/products excluded_items = Column(JSON) # Explicitly excluded items exclusion_justification = Column(Text) # Why items are excluded # Boundaries organizational_boundary = Column(Text) # Legal entity, departments physical_boundary = Column(Text) # Locations, networks technical_boundary = Column(Text) # Systems, applications # Approval status = Column(Enum(ApprovalStatusEnum), default=ApprovalStatusEnum.DRAFT) approved_by = Column(String(100)) approved_at = Column(DateTime) approval_signature = Column(String(64)) # SHA-256 hash # Validity effective_date = Column(Date) review_date = Column(Date) # Next mandatory review # Timestamps created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc)) updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) created_by = Column(String(100)) updated_by = Column(String(100)) __table_args__ = ( Index('ix_isms_scope_status', 'status'), ) def __repr__(self): return f"" class ISMSContextDB(Base): """ ISMS Context (ISO 27001 Kapitel 4.1, 4.2) Documents internal/external issues and interested parties. """ __tablename__ = 'compliance_isms_context' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) version = Column(String(20), nullable=False, default="1.0") # 4.1 Internal issues internal_issues = Column(JSON) # List of {"issue": "", "impact": "", "treatment": ""} # 4.1 External issues external_issues = Column(JSON) # List of {"issue": "", "impact": "", "treatment": ""} # 4.2 Interested parties interested_parties = Column(JSON) # List of {"party": "", "requirements": [], "relevance": ""} # Legal/regulatory requirements regulatory_requirements = Column(JSON) # DSGVO, AI Act, etc. contractual_requirements = Column(JSON) # Customer contracts # Analysis swot_strengths = Column(JSON) swot_weaknesses = Column(JSON) swot_opportunities = Column(JSON) swot_threats = Column(JSON) # Approval status = Column(Enum(ApprovalStatusEnum), default=ApprovalStatusEnum.DRAFT) approved_by = Column(String(100)) approved_at = Column(DateTime) # Review last_reviewed_at = Column(DateTime) next_review_date = Column(Date) # Timestamps created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc)) updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) def __repr__(self): return f"" class ISMSPolicyDB(Base): """ ISMS Policies (ISO 27001 Kapitel 5.2) Information security policy and sub-policies. """ __tablename__ = 'compliance_isms_policies' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) policy_id = Column(String(30), unique=True, nullable=False, index=True) # e.g., "POL-ISMS-001" # Policy details title = Column(String(200), nullable=False) policy_type = Column(String(50), nullable=False) # "master", "operational", "technical" description = Column(Text) policy_text = Column(Text, nullable=False) # Full policy content # Scope applies_to = Column(JSON) # Roles, departments, systems # Document control version = Column(String(20), nullable=False, default="1.0") status = Column(Enum(ApprovalStatusEnum), default=ApprovalStatusEnum.DRAFT) # Approval chain authored_by = Column(String(100)) reviewed_by = Column(String(100)) approved_by = Column(String(100)) # Must be top management approved_at = Column(DateTime) approval_signature = Column(String(64)) # Validity effective_date = Column(Date) review_frequency_months = Column(Integer, default=12) next_review_date = Column(Date) # References parent_policy_id = Column(String(36), ForeignKey('compliance_isms_policies.id')) related_controls = Column(JSON) # List of control_ids # Document path document_path = Column(String(500)) # Link to full document # Timestamps created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc)) updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) __table_args__ = ( Index('ix_policy_type_status', 'policy_type', 'status'), ) def __repr__(self): return f"" class SecurityObjectiveDB(Base): """ Security Objectives (ISO 27001 Kapitel 6.2) Measurable information security objectives. """ __tablename__ = 'compliance_security_objectives' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) objective_id = Column(String(30), unique=True, nullable=False, index=True) # e.g., "OBJ-001" # Objective definition title = Column(String(200), nullable=False) description = Column(Text) category = Column(String(50)) # "availability", "confidentiality", "integrity", "compliance" # SMART criteria specific = Column(Text) # What exactly measurable = Column(Text) # How measured achievable = Column(Text) # Is it realistic relevant = Column(Text) # Why important time_bound = Column(Text) # Deadline # Metrics kpi_name = Column(String(100)) kpi_target = Column(String(100)) # Target value kpi_current = Column(String(100)) # Current value kpi_unit = Column(String(50)) # %, count, score measurement_frequency = Column(String(50)) # monthly, quarterly # Responsibility owner = Column(String(100)) accountable = Column(String(100)) # RACI: Accountable # Status status = Column(String(30), default="active") # active, achieved, not_achieved, cancelled progress_percentage = Column(Integer, default=0) # Timeline target_date = Column(Date) achieved_date = Column(Date) # Linked items related_controls = Column(JSON) related_risks = Column(JSON) # Approval approved_by = Column(String(100)) approved_at = Column(DateTime) # Timestamps created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc)) updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) __table_args__ = ( Index('ix_objective_status', 'status'), Index('ix_objective_category', 'category'), ) def __repr__(self): return f"" class StatementOfApplicabilityDB(Base): """ Statement of Applicability (SoA) - ISO 27001 Anhang A Mapping Documents which Annex A controls are applicable and why. This is MANDATORY for certification. """ __tablename__ = 'compliance_soa' id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) # ISO 27001:2022 Annex A reference annex_a_control = Column(String(20), nullable=False, index=True) # e.g., "A.5.1" annex_a_title = Column(String(300), nullable=False) annex_a_category = Column(String(100)) # "Organizational", "People", "Physical", "Technological" # Applicability decision is_applicable = Column(Boolean, nullable=False) applicability_justification = Column(Text, nullable=False) # MUST be documented # Implementation status implementation_status = Column(String(30), default="planned") # planned, partial, implemented, not_implemented implementation_notes = Column(Text) # Mapping to our controls breakpilot_control_ids = Column(JSON) # List of our control_ids that address this coverage_level = Column(String(20), default="full") # full, partial, planned # Evidence evidence_description = Column(Text) evidence_ids = Column(JSON) # Links to EvidenceDB # Risk-based justification (for exclusions) risk_assessment_notes = Column(Text) # If not applicable, explain why compensating_controls = Column(Text) # If partial, explain compensating measures # Approval reviewed_by = Column(String(100)) reviewed_at = Column(DateTime) approved_by = Column(String(100)) approved_at = Column(DateTime) # Version tracking version = Column(String(20), default="1.0") # Timestamps created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc)) updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) __table_args__ = ( Index('ix_soa_annex_control', 'annex_a_control', unique=True), Index('ix_soa_applicable', 'is_applicable'), Index('ix_soa_status', 'implementation_status'), ) def __repr__(self): return f"" __all__ = [ "ApprovalStatusEnum", "ISMSScopeDB", "ISMSContextDB", "ISMSPolicyDB", "SecurityObjectiveDB", "StatementOfApplicabilityDB", ]