Skip to content

Commit e941f94

Browse files
Calculate commited metrics based on bucket timestamp
1 parent 7f6a3b1 commit e941f94

3 files changed

Lines changed: 51 additions & 3 deletions

File tree

server/polar/metrics/metrics.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def get_sql_expression(
108108
func.coalesce(Subscription.ended_at, Subscription.ends_at),
109109
)
110110
)
111-
< i.sql_date_trunc(now),
111+
< i.sql_date_trunc(t),
112112
)
113113
)
114114

@@ -231,7 +231,7 @@ def get_sql_expression(
231231
func.coalesce(Subscription.ended_at, Subscription.ends_at),
232232
)
233233
)
234-
< i.sql_date_trunc(now),
234+
< i.sql_date_trunc(t),
235235
)
236236
),
237237
0,

server/polar/metrics/queries.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ def get_active_subscriptions_cte(
295295
func.coalesce(Subscription.ended_at, Subscription.ends_at),
296296
)
297297
)
298-
< interval.sql_date_trunc(now),
298+
< interval.sql_date_trunc(timestamp_column),
299299
),
300300
)
301301
),

server/tests/metrics/test_service.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from polar.integrations.tinybird.service import DATASOURCE_EVENTS, _event_to_tinybird
2121
from polar.kit.db.postgres import create_async_engine, create_async_sessionmaker
2222
from polar.kit.time_queries import TimeInterval
23+
from polar.metrics.schemas import MetricsResponse
2324
from polar.metrics.service import metrics as metrics_service
2425
from polar.models import (
2526
Customer,
@@ -3402,6 +3403,53 @@ async def test_committed_mrr(
34023403
assert mar.monthly_recurring_revenue == 100_00
34033404
assert mar.committed_monthly_recurring_revenue == 100_00
34043405

3406+
async def test_committed_mrr_is_stable_across_now_values(
3407+
self,
3408+
metrics_harness: MetricsHarness,
3409+
metrics_session: AsyncSession,
3410+
) -> None:
3411+
case = QUERY_CASES_BY_LABEL["committed_mrr"]
3412+
org_ctx = metrics_harness.organizations[case.org_key]
3413+
auth_subject = _metrics_auth_subject(
3414+
metrics_harness.user,
3415+
metrics_harness.unauthorized_user,
3416+
org_ctx.organization,
3417+
case.auth_type,
3418+
)
3419+
3420+
async def get_metrics(now: datetime) -> MetricsResponse:
3421+
return await metrics_service.get_metrics(
3422+
metrics_session,
3423+
auth_subject,
3424+
start_date=case.start_date,
3425+
end_date=case.end_date,
3426+
timezone=ZoneInfo(case.timezone),
3427+
interval=case.interval,
3428+
organization_id=[org_ctx.organization.id]
3429+
if case.organization_id_filter or case.auth_type == "user"
3430+
else None,
3431+
product_id=[org_ctx.product_ids[k] for k in case.product_keys] or None,
3432+
billing_type=list(case.billing_types) or None,
3433+
customer_id=[org_ctx.customer_ids[k] for k in case.customer_keys]
3434+
or None,
3435+
metrics=list(case.metrics) if case.metrics is not None else None,
3436+
now=now,
3437+
)
3438+
3439+
early_metrics = await get_metrics(datetime(2024, 2, 15, tzinfo=UTC))
3440+
later_metrics = await get_metrics(datetime(2024, 4, 15, tzinfo=UTC))
3441+
3442+
assert len(early_metrics.periods) == len(later_metrics.periods) == 3
3443+
3444+
for early_period, later_period in zip(
3445+
early_metrics.periods, later_metrics.periods, strict=True
3446+
):
3447+
assert early_period.timestamp == later_period.timestamp
3448+
assert (
3449+
early_period.committed_monthly_recurring_revenue
3450+
== later_period.committed_monthly_recurring_revenue
3451+
)
3452+
34053453
async def test_trial_excluded_from_mrr(
34063454
self,
34073455
metrics_harness: MetricsHarness,

0 commit comments

Comments
 (0)