from __future__ import annotations from decimal import Decimal, ROUND_HALF_UP from typing import Any TWOPLACES = Decimal("0.01") def _money(value: Decimal) -> Decimal: return value.quantize(TWOPLACES, rounding=ROUND_HALF_UP) def load_usage_records(data_dir) -> list[dict[str, Any]]: from pathlib import Path from .load import _read_json, default_data_dir root = data_dir or default_data_dir() path = Path(root) / "usage_records.json" if not path.exists(): return [] raw = _read_json(path) return list(raw.get("records", [])) def build_usage_summary(records: list[dict[str, Any]], period: str) -> dict: period_rows = [row for row in records if row.get("period") == period] by_member: dict[str, Decimal] = {} by_model: dict[str, Decimal] = {} total = Decimal("0") for row in period_rows: cost = Decimal(str(row.get("cost_eur", "0"))) total += cost member_id = row.get("member_id") or "unknown" model = row.get("model") or "unknown" by_member[member_id] = by_member.get(member_id, Decimal("0")) + cost by_model[model] = by_model.get(model, Decimal("0")) + cost active_members = len(by_member) or 1 return { "period": period, "total_ai_spend_eur": _money(total), "cost_per_active_user_eur": _money(total / active_members), "by_member": {key: _money(value) for key, value in sorted(by_member.items())}, "by_model": {key: _money(value) for key, value in sorted(by_model.items())}, "record_count": len(period_rows), }