from datetime import datetime, timezone from app.modules.impl_tracker.domain.entities import ImplProgress from app.modules.impl_tracker.infrastructure.code_scanner import scan_code_directory from app.modules.project.domain.entities import Project from app.modules.scanner.domain.entities import ScanResult class ImplTrackerService: def __init__(self) -> None: self._cache: dict[str, list[ImplProgress]] = {} self._manual_overrides: dict[str, dict[str, float]] = {} # project_id -> {module_id: percentage} def evaluate(self, project: Project, scan_result: ScanResult) -> list[ImplProgress]: progress_list: list[ImplProgress] = [] now = datetime.now(timezone.utc) if not project.code_dir: # No code dir -> all modules at 0% for mod in scan_result.modules: progress_list.append(ImplProgress( module_id=mod.module_id, percentage=0.0, source="auto", evaluated_at=now, )) else: code_structure = scan_code_directory(project.code_dir, scan_result) for mod in scan_result.modules: if mod.module_id in code_structure.matched_modules: percentage = 50.0 # Basic: module directory exists else: percentage = 0.0 progress_list.append(ImplProgress( module_id=mod.module_id, percentage=percentage, source="auto", evaluated_at=now, )) # Apply manual overrides overrides = self._manual_overrides.get(project.id, {}) for p in progress_list: if p.module_id in overrides: p.percentage = overrides[p.module_id] p.source = "manual" self._cache[project.id] = progress_list return progress_list def get_progress(self, project_id: str) -> list[ImplProgress] | None: return self._cache.get(project_id) def set_manual_progress(self, project_id: str, module_id: str, percentage: float) -> None: if project_id not in self._manual_overrides: self._manual_overrides[project_id] = {} self._manual_overrides[project_id][module_id] = percentage # Update cache if exists if project_id in self._cache: for p in self._cache[project_id]: if p.module_id == module_id: p.percentage = percentage p.source = "manual" p.evaluated_at = datetime.now(timezone.utc)