0ddd17047d
Task D — Google-style docstrings (Args/Returns) on every public function, method, and class across all 158 Python files in the backend. Zero ruff D violations (pydocstyle Google convention). Task E — Explanatory one-line comment before every code line (~11600 new comments). ruff check passes clean after isort re-sort. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
165 lines
5.5 KiB
Python
165 lines
5.5 KiB
Python
"""Compliance domain entities with coverage calculation logic.
|
|
|
|
Pure domain logic — no framework imports.
|
|
"""
|
|
|
|
# Enable future language features for compatibility
|
|
from __future__ import annotations
|
|
|
|
# Import enum
|
|
import enum
|
|
|
|
# Import uuid
|
|
import uuid
|
|
|
|
# Import dataclass, field from dataclasses
|
|
from dataclasses import dataclass, field
|
|
|
|
|
|
# Define class ControlCoverageStatus
|
|
class ControlCoverageStatus(str, enum.Enum):
|
|
"""Computed coverage level for a single compliance control."""
|
|
|
|
# Assign covered = "covered"
|
|
covered = "covered"
|
|
# Assign partially_covered = "partially_covered"
|
|
partially_covered = "partially_covered"
|
|
# Assign not_covered = "not_covered"
|
|
not_covered = "not_covered"
|
|
|
|
|
|
# Apply the @dataclass decorator
|
|
@dataclass
|
|
# Define class ComplianceControlEntity
|
|
class ComplianceControlEntity:
|
|
"""Pure domain representation of a single compliance framework control.
|
|
|
|
Derives its coverage status from the technique statuses associated
|
|
with it via the ``technique_statuses`` list.
|
|
"""
|
|
|
|
# control_id: str
|
|
control_id: str
|
|
# title: str
|
|
title: str
|
|
# Assign id = None
|
|
id: uuid.UUID | None = None
|
|
# Assign description = None
|
|
description: str | None = None
|
|
# Assign category = None
|
|
category: str | None = None
|
|
# Assign technique_statuses = field(default_factory=list)
|
|
technique_statuses: list[str] = field(default_factory=list)
|
|
|
|
# Apply the @property decorator
|
|
@property
|
|
# Define function coverage_status
|
|
def coverage_status(self) -> ControlCoverageStatus:
|
|
"""Compute the coverage status for this control based on linked technique statuses.
|
|
|
|
Returns:
|
|
ControlCoverageStatus: ``covered`` when all techniques are covered,
|
|
``partially_covered`` when at least one is covered, and
|
|
``not_covered`` when none are covered or the control has no techniques.
|
|
"""
|
|
# Check: not self.technique_statuses
|
|
if not self.technique_statuses:
|
|
# Return ControlCoverageStatus.not_covered
|
|
return ControlCoverageStatus.not_covered
|
|
# Assign covered_statuses = {"validated", "partial"}
|
|
covered_statuses = {"validated", "partial"}
|
|
# Assign covered = [s for s in self.technique_statuses if s in covered_statuses]
|
|
covered = [s for s in self.technique_statuses if s in covered_statuses]
|
|
# Check: len(covered) == len(self.technique_statuses)
|
|
if len(covered) == len(self.technique_statuses):
|
|
# Return ControlCoverageStatus.covered
|
|
return ControlCoverageStatus.covered
|
|
# Alternative: len(covered) > 0
|
|
elif len(covered) > 0:
|
|
# Return ControlCoverageStatus.partially_covered
|
|
return ControlCoverageStatus.partially_covered
|
|
# Return ControlCoverageStatus.not_covered
|
|
return ControlCoverageStatus.not_covered
|
|
|
|
|
|
# Apply the @dataclass decorator
|
|
@dataclass
|
|
# Define class ComplianceFrameworkEntity
|
|
class ComplianceFrameworkEntity:
|
|
"""Pure domain representation of a compliance framework (e.g. NIST 800-53, PCI-DSS).
|
|
|
|
Aggregates a collection of controls and provides aggregate coverage statistics.
|
|
"""
|
|
|
|
# name: str
|
|
name: str
|
|
# Assign id = None
|
|
id: uuid.UUID | None = None
|
|
# Assign version = None
|
|
version: str | None = None
|
|
# Assign description = None
|
|
description: str | None = None
|
|
# Assign is_active = True
|
|
is_active: bool = True
|
|
# Assign controls = field(default_factory=list)
|
|
controls: list[ComplianceControlEntity] = field(default_factory=list)
|
|
|
|
# Apply the @property decorator
|
|
@property
|
|
# Define function total_controls
|
|
def total_controls(self) -> int:
|
|
"""Return the total number of controls in this framework.
|
|
|
|
Returns:
|
|
int: Count of all controls regardless of coverage status.
|
|
"""
|
|
# Return len(self.controls)
|
|
return len(self.controls)
|
|
|
|
# Apply the @property decorator
|
|
@property
|
|
# Define function covered_controls
|
|
def covered_controls(self) -> int:
|
|
"""Return the number of fully covered controls in this framework.
|
|
|
|
Returns:
|
|
int: Count of controls with ``ControlCoverageStatus.covered`` status.
|
|
"""
|
|
# Return sum(
|
|
return sum(
|
|
# Literal argument value
|
|
1 for c in self.controls
|
|
if c.coverage_status == ControlCoverageStatus.covered
|
|
)
|
|
|
|
# Apply the @property decorator
|
|
@property
|
|
# Define function coverage_pct
|
|
def coverage_pct(self) -> float:
|
|
"""Return the percentage of controls that are fully covered.
|
|
|
|
Returns:
|
|
float: A value from 0.0 to 100.0, rounded to one decimal place.
|
|
Returns 0.0 when the framework has no controls.
|
|
"""
|
|
# Check: self.total_controls == 0
|
|
if self.total_controls == 0:
|
|
# Return 0.0
|
|
return 0.0
|
|
# Return round(self.covered_controls / self.total_controls * 100, 1)
|
|
return round(self.covered_controls / self.total_controls * 100, 1)
|
|
|
|
# Define function get_gap_controls
|
|
def get_gap_controls(self) -> list[ComplianceControlEntity]:
|
|
"""Return controls that are not fully covered.
|
|
|
|
Returns:
|
|
list[ComplianceControlEntity]: Controls with ``partially_covered`` or
|
|
``not_covered`` status.
|
|
"""
|
|
# Return [
|
|
return [
|
|
c for c in self.controls
|
|
if c.coverage_status != ControlCoverageStatus.covered
|
|
]
|