# [DEF:backend.src.services.clean_release.report_builder:Module] # @TIER: CRITICAL # @SEMANTICS: clean-release, report, audit, counters, violations # @PURPOSE: Build and persist compliance reports with consistent counter invariants. # @LAYER: Domain # @RELATION: DEPENDS_ON -> backend.src.models.clean_release # @RELATION: DEPENDS_ON -> backend.src.services.clean_release.repository # @INVARIANT: blocking_violations_count never exceeds violations_count. # @TEST_CONTRACT: ComplianceCheckRun,List[ComplianceViolation] -> ComplianceReport # @TEST_FIXTURE: blocked_with_two_violations -> file:backend/tests/fixtures/clean_release/fixtures_clean_release.json # @TEST_EDGE: empty_violations_for_blocked -> BLOCKED run with zero blocking violations raises ValueError # @TEST_EDGE: counter_mismatch -> blocking counter cannot exceed total violations counter # @TEST_EDGE: missing_operator_summary -> non-terminal run prevents report creation and summary generation # @TEST_INVARIANT: blocking_count_le_total_count -> VERIFIED_BY: [counter_mismatch, empty_violations_for_blocked] from __future__ import annotations from datetime import datetime, timezone from uuid import uuid4 from typing import List from ...models.clean_release import CheckFinalStatus, ComplianceCheckRun, ComplianceReport, ComplianceViolation from .repository import CleanReleaseRepository class ComplianceReportBuilder: def __init__(self, repository: CleanReleaseRepository): self.repository = repository def build_report_payload(self, check_run: ComplianceCheckRun, violations: List[ComplianceViolation]) -> ComplianceReport: if check_run.final_status == CheckFinalStatus.RUNNING: raise ValueError("Cannot build report for non-terminal run") violations_count = len(violations) blocking_violations_count = sum(1 for v in violations if v.blocked_release) if check_run.final_status == CheckFinalStatus.BLOCKED and blocking_violations_count <= 0: raise ValueError("Blocked run requires at least one blocking violation") summary = ( "Compliance passed with no blocking violations" if check_run.final_status == CheckFinalStatus.COMPLIANT else f"Blocked with {blocking_violations_count} blocking violation(s)" ) return ComplianceReport( report_id=f"CCR-{uuid4()}", check_run_id=check_run.check_run_id, candidate_id=check_run.candidate_id, generated_at=datetime.now(timezone.utc), final_status=check_run.final_status, operator_summary=summary, structured_payload_ref=f"inmemory://check-runs/{check_run.check_run_id}/report", violations_count=violations_count, blocking_violations_count=blocking_violations_count, ) def persist_report(self, report: ComplianceReport) -> ComplianceReport: return self.repository.save_report(report) # [/DEF:backend.src.services.clean_release.report_builder:Module]