Refactor economics to expense-record ledger with correct Bubble cost

Replace pre-aggregated costs.json with expense_records.json (48 line-item
records) and payment_records.json. All monthly and cumulative totals are
computed deterministically in observatory/ledger.py. Correct Bubble.io to
$32/mo (since Feb 2025) — infrastructure €69.44/mo not €72.20.
This commit is contained in:
2026-06-22 02:03:22 +02:00
parent ea2c2c6403
commit 31db9f8f31
12 changed files with 843 additions and 299 deletions

View File

@@ -1,72 +0,0 @@
{
"version": 2,
"fx_rates": {
"USD/EUR": "0.92"
},
"rate_card": [
{
"id": "bubble-subscription",
"name": "Bubble.io platform",
"category": "fixed",
"amount": "35.00",
"currency": "USD",
"cadence": "monthly",
"allocation": "flat"
},
{
"id": "domains",
"name": "Domains",
"category": "fixed",
"amount": "15.00",
"currency": "EUR",
"cadence": "monthly",
"allocation": "flat"
},
{
"id": "operational-overhead",
"name": "Operational overhead",
"category": "fixed",
"amount": "25.00",
"currency": "EUR",
"cadence": "monthly",
"allocation": "flat"
},
{
"id": "stripe-percentage",
"name": "Stripe percentage fee",
"category": "variable",
"amount": "0.015",
"currency": "ratio",
"cadence": "per_transaction",
"allocation": "percent_of_gross_revenue"
},
{
"id": "stripe-fixed",
"name": "Stripe fixed fee",
"category": "variable",
"amount": "0.25",
"currency": "EUR",
"cadence": "per_transaction",
"allocation": "per_active_member"
}
],
"monthly_history": [
{"period": "2025-03", "infrastructure_cost": "72.20", "payment_processing_cost": "0.00", "active_members": 0, "gross_revenue": "0.00"},
{"period": "2025-04", "infrastructure_cost": "72.20", "payment_processing_cost": "0.00", "active_members": 0, "gross_revenue": "0.00"},
{"period": "2025-05", "infrastructure_cost": "72.20", "payment_processing_cost": "0.00", "active_members": 0, "gross_revenue": "0.00"},
{"period": "2025-06", "infrastructure_cost": "72.20", "payment_processing_cost": "0.00", "active_members": 0, "gross_revenue": "0.00"},
{"period": "2025-07", "infrastructure_cost": "72.20", "payment_processing_cost": "0.00", "active_members": 0, "gross_revenue": "0.00"},
{"period": "2025-08", "infrastructure_cost": "72.20", "payment_processing_cost": "0.00", "active_members": 0, "gross_revenue": "0.00"},
{"period": "2025-09", "infrastructure_cost": "72.20", "payment_processing_cost": "0.00", "active_members": 0, "gross_revenue": "0.00"},
{"period": "2025-10", "infrastructure_cost": "72.20", "payment_processing_cost": "0.00", "active_members": 0, "gross_revenue": "0.00"},
{"period": "2025-11", "infrastructure_cost": "72.20", "payment_processing_cost": "0.38", "active_members": 1, "gross_revenue": "8.99"},
{"period": "2025-12", "infrastructure_cost": "72.20", "payment_processing_cost": "0.38", "active_members": 1, "gross_revenue": "8.99"},
{"period": "2026-01", "infrastructure_cost": "72.20", "payment_processing_cost": "0.38", "active_members": 1, "gross_revenue": "8.99"},
{"period": "2026-02", "infrastructure_cost": "72.20", "payment_processing_cost": "0.38", "active_members": 1, "gross_revenue": "8.99"},
{"period": "2026-03", "infrastructure_cost": "72.20", "payment_processing_cost": "0.38", "active_members": 1, "gross_revenue": "8.99"},
{"period": "2026-04", "infrastructure_cost": "72.20", "payment_processing_cost": "0.38", "active_members": 1, "gross_revenue": "8.99"},
{"period": "2026-05", "infrastructure_cost": "72.20", "payment_processing_cost": "0.38", "active_members": 1, "gross_revenue": "8.99"},
{"period": "2026-06", "infrastructure_cost": "72.20", "payment_processing_cost": "0.38", "active_members": 1, "gross_revenue": "8.99"}
],
"note": "Infrastructure costs are operator cash outflows. Payment processing is tracked separately and already deducted from net member payments — do not double-count in liquidity."
}

View File

@@ -0,0 +1,489 @@
{
"version": 1,
"fx_rates": {
"USD/EUR": "0.92"
},
"records": [
{
"id": "exp-bubble-2025-03",
"period": "2025-03",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2025-03",
"period": "2025-03",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2025-03",
"period": "2025-03",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2025-04",
"period": "2025-04",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2025-04",
"period": "2025-04",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2025-04",
"period": "2025-04",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2025-05",
"period": "2025-05",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2025-05",
"period": "2025-05",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2025-05",
"period": "2025-05",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2025-06",
"period": "2025-06",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2025-06",
"period": "2025-06",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2025-06",
"period": "2025-06",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2025-07",
"period": "2025-07",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2025-07",
"period": "2025-07",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2025-07",
"period": "2025-07",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2025-08",
"period": "2025-08",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2025-08",
"period": "2025-08",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2025-08",
"period": "2025-08",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2025-09",
"period": "2025-09",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2025-09",
"period": "2025-09",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2025-09",
"period": "2025-09",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2025-10",
"period": "2025-10",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2025-10",
"period": "2025-10",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2025-10",
"period": "2025-10",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2025-11",
"period": "2025-11",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2025-11",
"period": "2025-11",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2025-11",
"period": "2025-11",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2025-12",
"period": "2025-12",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2025-12",
"period": "2025-12",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2025-12",
"period": "2025-12",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2026-01",
"period": "2026-01",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2026-01",
"period": "2026-01",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2026-01",
"period": "2026-01",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2026-02",
"period": "2026-02",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2026-02",
"period": "2026-02",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2026-02",
"period": "2026-02",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2026-03",
"period": "2026-03",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2026-03",
"period": "2026-03",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2026-03",
"period": "2026-03",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2026-04",
"period": "2026-04",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2026-04",
"period": "2026-04",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2026-04",
"period": "2026-04",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2026-05",
"period": "2026-05",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2026-05",
"period": "2026-05",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2026-05",
"period": "2026-05",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-bubble-2026-06",
"period": "2026-06",
"vendor": "bubble.io",
"description": "Bubble.io Personal plan ($32/mo since Feb 2025)",
"cost_class": "infrastructure",
"amount": "32.00",
"currency": "USD",
"source": "manual"
},
{
"id": "exp-domains-2026-06",
"period": "2026-06",
"vendor": "domains",
"description": "Domain registrations",
"cost_class": "infrastructure",
"amount": "15.00",
"currency": "EUR",
"source": "manual"
},
{
"id": "exp-overhead-2026-06",
"period": "2026-06",
"vendor": "operational-overhead",
"description": "Operational overhead",
"cost_class": "infrastructure",
"amount": "25.00",
"currency": "EUR",
"source": "manual"
}
],
"note": "Source-of-truth expense ledger. Aggregations are computed by observatory/ledger.py \u2014 never hand-edited totals."
}

View File

@@ -1,14 +1,14 @@
{
"version": 1,
"entries": [
{"id": "rev-2025-11", "period": "2025-11", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "rev-2025-12", "period": "2025-12", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "rev-2026-01", "period": "2026-01", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "rev-2026-02", "period": "2026-02", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "rev-2026-03", "period": "2026-03", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "rev-2026-04", "period": "2026-04", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "rev-2026-05", "period": "2026-05", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "rev-2026-06", "period": "2026-06", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1}
"records": [
{"id": "pay-2025-11", "period": "2025-11", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "pay-2025-12", "period": "2025-12", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "pay-2026-01", "period": "2026-01", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "pay-2026-02", "period": "2026-02", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "pay-2026-03", "period": "2026-03", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "pay-2026-04", "period": "2026-04", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "pay-2026-05", "period": "2026-05", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1},
{"id": "pay-2026-06", "period": "2026-06", "gross_amount": "8.99", "fees_amount": "0.38", "refunds_amount": "0.00", "net_amount": "8.61", "currency": "EUR", "source": "manual", "member_count": 1}
],
"note": "Member payments begin November 2025. Stripe sync replaces manual entries in Sprint 3."
"note": "Member payment ledger from November 2025. Stripe sync replaces manual entries in Sprint 3."
}