from dataclasses import dataclass, field from typing import Optional, Tuple, List @dataclass class FeedbackMessage: category: str message: str severity: str # "warning", "error", "success" @dataclass class QualityFeedback: messages: List[FeedbackMessage] = field(default_factory=list) is_acceptable: bool = True def add(self, category: str, message: str, severity: str = "warning"): self.messages.append(FeedbackMessage(category, message, severity)) if severity == "error": self.is_acceptable = False @dataclass class FingerQualityResult: # Raw scores blur_score: float illumination_score: float coverage_ratio: float orientation_angle_deg: float # angle of main axis w.r.t. x-axis # Per-metric pass/fail blur_pass: bool illumination_pass: bool coverage_pass: bool orientation_pass: bool # Overall quality_score: float # 0–1 overall_pass: bool # Debug / geometry bbox: Optional[Tuple[int, int, int, int]] # x, y, w, h contour_area: float # NEW: Feedback bundled into the same result JSON feedback: Optional[QualityFeedback] = None