Files
adaptive-pricing/projects/coulomb-pricing/observatory/membership_analytics.py
tegwick 0a38def5a5 Complete Economic Observatory MVP (ADAPTIVE-WP-0002)
Add file-based Bubble, Stripe, and OpenRouter importers; usage attribution,
cost allocation, pricing simulator, credit wallets, and recommendations in the
dashboard API. Document whynot-design UI workflow and archive the finished
workplan with all ten tasks marked done.
2026-06-22 23:23:31 +02:00

48 lines
1.4 KiB
Python

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",
}