from app.models.attribution_record import AttributionRecord class ROICalculator: INDUSTRY_AVG_CITATION_VALUE = 50.0 def calculate_roi( self, subscription_cost: float, score_delta: float, attribution_records: list[AttributionRecord], ) -> dict: value_generated = score_delta * self.INDUSTRY_AVG_CITATION_VALUE if subscription_cost > 0: roi_percentage = round( (value_generated - subscription_cost) / subscription_cost * 100, 2 ) else: roi_percentage = 0.0 break_even_delta = self.estimate_break_even(subscription_cost) return { "roi_percentage": roi_percentage, "value_generated": round(value_generated, 2), "cost": subscription_cost, "break_even_delta": round(break_even_delta, 2), } def generate_ab_comparison( self, before_score: float, after_score: float, before_dimensions: dict, after_dimensions: dict, ) -> dict: overall_delta = round(after_score - before_score, 2) dimensions = [] all_names = set(list(before_dimensions.keys()) + list(after_dimensions.keys())) for name in all_names: b = before_dimensions.get(name, {}).get("score", 0) a = after_dimensions.get(name, {}).get("score", 0) delta = round(a - b, 2) dimensions.append({ "name": name, "before": b, "after": a, "delta": delta, "improved": delta > 0, }) return { "overall_before": before_score, "overall_after": after_score, "overall_delta": overall_delta, "dimensions": dimensions, } def estimate_break_even(self, subscription_cost: float) -> float: if self.INDUSTRY_AVG_CITATION_VALUE == 0: return 0.0 return subscription_cost / self.INDUSTRY_AVG_CITATION_VALUE