generated from coulomb/repo-seed
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.
This commit is contained in:
48
projects/coulomb-pricing/observatory/membership_analytics.py
Normal file
48
projects/coulomb-pricing/observatory/membership_analytics.py
Normal file
@@ -0,0 +1,48 @@
|
||||
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",
|
||||
}
|
||||
Reference in New Issue
Block a user