"""Seuils métier configurables via config.yaml (optionnel) ou variables d'environnement. Recherche, dans l'ordre : argument explicite -> variable d'env CONFIG_PATH -> config.yaml à la racine du module -> valeurs par défaut. """ from dataclasses import dataclass from pathlib import Path import logging import os logger = logging.getLogger(__name__) MODULE_ROOT = Path(__file__).resolve().parent.parent @dataclass class RuleConfig: consistency_tolerance: float = 0.02 match_tolerance: float = 0.03 liters_upper_bound: float = 500.0 price_min: float = 200.0 price_max: float = 2000.0 business_confidence_threshold: float = 0.5 blur_threshold: float = 80.0 dark_threshold: float = 40.0 bright_threshold: float = 240.0 def load_config(path: str | None = None) -> RuleConfig: candidate = path or os.environ.get("CONFIG_PATH") or str(MODULE_ROOT / "config.yaml") candidate_path = Path(candidate) if not candidate_path.is_file(): return RuleConfig() try: import yaml with open(candidate_path, "r", encoding="utf-8") as f: data = yaml.safe_load(f) or {} except Exception as e: logger.warning(f"Impossible de charger {candidate_path} : {e}. Utilisation des valeurs par défaut.") return RuleConfig() rules_data = data.get("rules", data) if isinstance(data, dict) else {} defaults = RuleConfig() known_fields = defaults.__dataclass_fields__.keys() kwargs = {k: v for k, v in rules_data.items() if k in known_fields} return RuleConfig(**{**defaults.__dict__, **kwargs})