from __future__ import annotations from .models import MembershipRecord def _period_prefix(date: str | None) -> str | None: if not date or len(date) < 7: return None return date[:7] def build_membership_analytics( members: list[MembershipRecord], period: str, history: list[str], ) -> dict: active = sum(1 for member in members if member.status == "active") new_members = sum(1 for member in members if _period_prefix(member.joined_at) == period) churned = sum(1 for member in members if _period_prefix(member.churned_at) == period) prior_period = None sorted_periods = sorted(history) if period in sorted_periods: index = sorted_periods.index(period) if index > 0: prior_period = sorted_periods[index - 1] prior_active = active if prior_period: prior_active = sum( 1 for member in members if member.status == "active" and _period_prefix(member.joined_at) <= prior_period ) growth_rate = None if prior_active: growth_rate = round(((active - prior_active) / prior_active) * 100, 1) return { "period": period, "total_members": len(members), "active_members": active, "new_members": new_members, "churned_members": churned, "growth_rate_pct": growth_rate, "snapshot_source": "membership.json", }