From 7b84d34ea63501e4dd006dee533b8e1bda7794c5 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 22 Jun 2026 02:36:42 +0200 Subject: [PATCH] Record actual Stripe payment costs for tegwick membership Update payment_records to 8.99 EUR gross, 0.44 EUR fees, 8.55 EUR net payout to binky-hedgehog. Link member tegwick in membership ledger and add Stripe reference catalog. --- projects/coulomb-pricing/README.md | 3 +- .../data/infrastructure/stripe.json | 13 ++ projects/coulomb-pricing/data/membership.json | 9 +- .../coulomb-pricing/data/payment_records.json | 126 ++++++++++++++++-- .../coulomb-pricing/observatory/dashboard.py | 2 +- projects/coulomb-pricing/observatory/load.py | 2 + .../coulomb-pricing/observatory/models.py | 2 + .../reports/economics-2026-06.md | 42 +++--- .../coulomb-pricing/tests/test_economics.py | 32 +++-- 9 files changed, 183 insertions(+), 48 deletions(-) create mode 100644 projects/coulomb-pricing/data/infrastructure/stripe.json diff --git a/projects/coulomb-pricing/README.md b/projects/coulomb-pricing/README.md index 41880fb..e40a109 100644 --- a/projects/coulomb-pricing/README.md +++ b/projects/coulomb-pricing/README.md @@ -24,7 +24,8 @@ computes all totals programmatically (`ledger.py` → `economics.py`). **Current reality:** infrastructure from January 2025 — domains **€6.75/mo**, coulombcore hosting **€13.99/mo** (from Jan 2025), railiance01 hosting -**€8.99/mo** (from Mar 2026). Sole member payments from November 2025. Customer +**€8.99/mo** (from Mar 2026). Member **tegwick** pays **€8.99/mo** (Stripe fee +**€0.44**, net payout **€8.55** to binky-hedgehog) from November 2025. Customer cost-pass-through billing is not active. ### Commands diff --git a/projects/coulomb-pricing/data/infrastructure/stripe.json b/projects/coulomb-pricing/data/infrastructure/stripe.json new file mode 100644 index 0000000..9ff117f --- /dev/null +++ b/projects/coulomb-pricing/data/infrastructure/stripe.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "currency": "EUR", + "payout_account": "binky-hedgehog", + "membership": { + "product": "coulomb.social-membership", + "gross_monthly_eur": "8.99", + "fee_monthly_eur": "0.44", + "net_payout_monthly_eur": "8.55", + "member_username": "tegwick" + }, + "note": "Reference from actual Stripe payouts. Payment rows live in payment_records.json." +} \ No newline at end of file diff --git a/projects/coulomb-pricing/data/membership.json b/projects/coulomb-pricing/data/membership.json index f0ba1c4..4bfb963 100644 --- a/projects/coulomb-pricing/data/membership.json +++ b/projects/coulomb-pricing/data/membership.json @@ -3,14 +3,15 @@ "snapshot_date": "2026-06-22", "members": [ { - "id": "member-founder", + "id": "member-tegwick", + "username": "tegwick", "external_id": null, "status": "active", "joined_at": "2025-11-03", "plan_id": "flat-899-eur-monthly", - "source": "manual", - "note": "Sole paying member; payments from November 2025" + "source": "stripe", + "note": "Sole paying member; coulomb.social membership 8.99 EUR/mo" } ], - "note": "Infrastructure costs run from January 2025; member payments from November 2025." + "note": "Infrastructure costs from January 2025; member payments from November 2025." } \ No newline at end of file diff --git a/projects/coulomb-pricing/data/payment_records.json b/projects/coulomb-pricing/data/payment_records.json index e893eb1..b1ed7ce 100644 --- a/projects/coulomb-pricing/data/payment_records.json +++ b/projects/coulomb-pricing/data/payment_records.json @@ -1,14 +1,118 @@ { - "version": 1, + "version": 2, "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} + { + "id": "pay-2025-11", + "period": "2025-11", + "gross_amount": "8.99", + "fees_amount": "0.44", + "refunds_amount": "0.00", + "net_amount": "8.55", + "currency": "EUR", + "source": "stripe", + "member_count": 1, + "member_username": "tegwick", + "product": "coulomb.social-membership", + "payout_account": "binky-hedgehog" + }, + { + "id": "pay-2025-12", + "period": "2025-12", + "gross_amount": "8.99", + "fees_amount": "0.44", + "refunds_amount": "0.00", + "net_amount": "8.55", + "currency": "EUR", + "source": "stripe", + "member_count": 1, + "member_username": "tegwick", + "product": "coulomb.social-membership", + "payout_account": "binky-hedgehog" + }, + { + "id": "pay-2026-01", + "period": "2026-01", + "gross_amount": "8.99", + "fees_amount": "0.44", + "refunds_amount": "0.00", + "net_amount": "8.55", + "currency": "EUR", + "source": "stripe", + "member_count": 1, + "member_username": "tegwick", + "product": "coulomb.social-membership", + "payout_account": "binky-hedgehog" + }, + { + "id": "pay-2026-02", + "period": "2026-02", + "gross_amount": "8.99", + "fees_amount": "0.44", + "refunds_amount": "0.00", + "net_amount": "8.55", + "currency": "EUR", + "source": "stripe", + "member_count": 1, + "member_username": "tegwick", + "product": "coulomb.social-membership", + "payout_account": "binky-hedgehog" + }, + { + "id": "pay-2026-03", + "period": "2026-03", + "gross_amount": "8.99", + "fees_amount": "0.44", + "refunds_amount": "0.00", + "net_amount": "8.55", + "currency": "EUR", + "source": "stripe", + "member_count": 1, + "member_username": "tegwick", + "product": "coulomb.social-membership", + "payout_account": "binky-hedgehog" + }, + { + "id": "pay-2026-04", + "period": "2026-04", + "gross_amount": "8.99", + "fees_amount": "0.44", + "refunds_amount": "0.00", + "net_amount": "8.55", + "currency": "EUR", + "source": "stripe", + "member_count": 1, + "member_username": "tegwick", + "product": "coulomb.social-membership", + "payout_account": "binky-hedgehog" + }, + { + "id": "pay-2026-05", + "period": "2026-05", + "gross_amount": "8.99", + "fees_amount": "0.44", + "refunds_amount": "0.00", + "net_amount": "8.55", + "currency": "EUR", + "source": "stripe", + "member_count": 1, + "member_username": "tegwick", + "product": "coulomb.social-membership", + "payout_account": "binky-hedgehog" + }, + { + "id": "pay-2026-06", + "period": "2026-06", + "gross_amount": "8.99", + "fees_amount": "0.44", + "refunds_amount": "0.00", + "net_amount": "8.55", + "currency": "EUR", + "source": "stripe", + "member_count": 1, + "member_username": "tegwick", + "product": "coulomb.social-membership", + "payout_account": "binky-hedgehog" + } ], - "note": "Member payment ledger from November 2025. Stripe sync replaces manual entries in Sprint 3." -} \ No newline at end of file + "note": "Stripe payment ledger for tegwick coulomb.social membership (8.99 EUR gross, 0.44 EUR fees, 8.55 EUR net payout to binky-hedgehog)." +} diff --git a/projects/coulomb-pricing/observatory/dashboard.py b/projects/coulomb-pricing/observatory/dashboard.py index 14920a3..1a7bd21 100644 --- a/projects/coulomb-pricing/observatory/dashboard.py +++ b/projects/coulomb-pricing/observatory/dashboard.py @@ -119,7 +119,7 @@ _Revenue source: {snapshot.revenue_source}_ - Product model (`data/product.json`) - Budget (`data/budget.json`) - Expense records (`data/expense_records.json`) — source of truth for costs -- Infrastructure catalog (`data/infrastructure/`) — domain and VPS reference data +- Infrastructure catalog (`data/infrastructure/`) — domain, VPS, and Stripe reference data - Payment records (`data/payment_records.json`) - Membership (`data/membership.json`) - Requirements (`REQUIREMENTS.md`) diff --git a/projects/coulomb-pricing/observatory/load.py b/projects/coulomb-pricing/observatory/load.py index 7e6ffbd..d2704a9 100644 --- a/projects/coulomb-pricing/observatory/load.py +++ b/projects/coulomb-pricing/observatory/load.py @@ -109,6 +109,8 @@ def load_payment_records(data_dir: Path | None = None) -> list[PaymentRecord]: currency=item["currency"], source=item["source"], member_count=item.get("member_count", 0), + member_username=item.get("member_username"), + payout_account=item.get("payout_account"), ) for item in items ] diff --git a/projects/coulomb-pricing/observatory/models.py b/projects/coulomb-pricing/observatory/models.py index 112d3c9..b966d74 100644 --- a/projects/coulomb-pricing/observatory/models.py +++ b/projects/coulomb-pricing/observatory/models.py @@ -55,6 +55,8 @@ class PaymentRecord: currency: str source: str member_count: int = 0 + member_username: str | None = None + payout_account: str | None = None @dataclass(frozen=True) diff --git a/projects/coulomb-pricing/reports/economics-2026-06.md b/projects/coulomb-pricing/reports/economics-2026-06.md index da263bc..adaf1f6 100644 --- a/projects/coulomb-pricing/reports/economics-2026-06.md +++ b/projects/coulomb-pricing/reports/economics-2026-06.md @@ -16,27 +16,27 @@ | Active members | 1 | | Member payments (gross) | 8.99 EUR | | Infrastructure cost | 29.73 EUR | -| Payment processing cost | 0.38 EUR | -| Total platform cost | 30.11 EUR | -| Platform cost per member | 30.11 EUR | -| Period gross margin | -21.12 EUR | -| Period gross margin % | -234.9% | -| Period net liquidity | -21.12 EUR (burning) | +| Payment processing cost | 0.44 EUR | +| Total platform cost | 30.17 EUR | +| Platform cost per member | 30.17 EUR | +| Period gross margin | -21.18 EUR | +| Period gross margin % | -235.6% | +| Period net liquidity | -21.18 EUR (burning) | _Period net liquidity = net member payments − infrastructure cost (processing fees already netted from payments)._ -_Revenue source: manual_ +_Revenue source: stripe_ ## Liquidity & Budget (through 2026-06) | Metric | Value | |--------|------:| | Initial budget | 1000.00 EUR | -| Cumulative member payments (net) | 68.88 EUR | +| Cumulative member payments (net) | 68.40 EUR | | Cumulative infrastructure cost | 409.28 EUR | -| Cumulative payment processing | 3.04 EUR | -| Cumulative total platform cost | 412.32 EUR | -| Cumulative net liquidity | -340.40 EUR (burning) | -| Remaining budget | 659.60 EUR (within budget) | +| Cumulative payment processing | 3.52 EUR | +| Cumulative total platform cost | 412.80 EUR | +| Cumulative net liquidity | -340.88 EUR (burning) | +| Remaining budget | 659.12 EUR (within budget) | | Months tracked | 18 | ## Monthly History @@ -53,14 +53,14 @@ _Revenue source: manual_ | 2025-08 | 0 | 0.00 | 20.74 | 0.00 | 20.74 | -20.74 | | 2025-09 | 0 | 0.00 | 20.74 | 0.00 | 20.74 | -20.74 | | 2025-10 | 0 | 0.00 | 20.74 | 0.00 | 20.74 | -20.74 | -| 2025-11 | 1 | 8.99 | 20.74 | 0.38 | 21.12 | -12.13 | -| 2025-12 | 1 | 8.99 | 20.74 | 0.38 | 21.12 | -12.13 | -| 2026-01 | 1 | 8.99 | 20.74 | 0.38 | 21.12 | -12.13 | -| 2026-02 | 1 | 8.99 | 20.74 | 0.38 | 21.12 | -12.13 | -| 2026-03 | 1 | 8.99 | 29.73 | 0.38 | 30.11 | -21.12 | -| 2026-04 | 1 | 8.99 | 29.73 | 0.38 | 30.11 | -21.12 | -| 2026-05 | 1 | 8.99 | 29.73 | 0.38 | 30.11 | -21.12 | -| 2026-06 | 1 | 8.99 | 29.73 | 0.38 | 30.11 | -21.12 | +| 2025-11 | 1 | 8.99 | 20.74 | 0.44 | 21.18 | -12.19 | +| 2025-12 | 1 | 8.99 | 20.74 | 0.44 | 21.18 | -12.19 | +| 2026-01 | 1 | 8.99 | 20.74 | 0.44 | 21.18 | -12.19 | +| 2026-02 | 1 | 8.99 | 20.74 | 0.44 | 21.18 | -12.19 | +| 2026-03 | 1 | 8.99 | 29.73 | 0.44 | 30.17 | -21.18 | +| 2026-04 | 1 | 8.99 | 29.73 | 0.44 | 30.17 | -21.18 | +| 2026-05 | 1 | 8.99 | 29.73 | 0.44 | 30.17 | -21.18 | +| 2026-06 | 1 | 8.99 | 29.73 | 0.44 | 30.17 | -21.18 | ## Pricing Model Registry @@ -75,7 +75,7 @@ _Revenue source: manual_ - Product model (`data/product.json`) - Budget (`data/budget.json`) - Expense records (`data/expense_records.json`) — source of truth for costs -- Infrastructure catalog (`data/infrastructure/`) — domain and VPS reference data +- Infrastructure catalog (`data/infrastructure/`) — domain, VPS, and Stripe reference data - Payment records (`data/payment_records.json`) - Membership (`data/membership.json`) - Requirements (`REQUIREMENTS.md`) diff --git a/projects/coulomb-pricing/tests/test_economics.py b/projects/coulomb-pricing/tests/test_economics.py index c62a538..f112d5b 100644 --- a/projects/coulomb-pricing/tests/test_economics.py +++ b/projects/coulomb-pricing/tests/test_economics.py @@ -46,7 +46,7 @@ def test_monthly_ledger_starts_january_2025() -> None: assert march.infrastructure_cost == Decimal("20.74") assert march.payment_processing_cost == Decimal("0.00") assert june.infrastructure_cost == Decimal("29.73") - assert june.payment_processing_cost == Decimal("0.38") + assert june.payment_processing_cost == Decimal("0.44") assert june.gross_revenue == Decimal("8.99") @@ -60,9 +60,9 @@ def test_build_snapshot_june_2026_domain_only_infrastructure() -> None: snapshot = build_snapshot("2026-06", product, models, members, payments, ledger) assert snapshot.monthly_infrastructure_cost == Decimal("29.73") - assert snapshot.monthly_payment_processing_cost == Decimal("0.38") - assert snapshot.monthly_total_platform_cost == Decimal("30.11") - assert snapshot.period_net_liquidity == Decimal("-21.12") + assert snapshot.monthly_payment_processing_cost == Decimal("0.44") + assert snapshot.monthly_total_platform_cost == Decimal("30.17") + assert snapshot.period_net_liquidity == Decimal("-21.18") assert snapshot.liquidity_status == "burning" @@ -74,11 +74,11 @@ def test_liquidity_summary_with_actual_domain_costs() -> None: summary = build_liquidity_summary(budget, payments, ledger, "2026-06") assert summary.cumulative_infrastructure_cost == Decimal("409.28") - assert summary.cumulative_payment_processing_cost == Decimal("3.04") - assert summary.cumulative_total_platform_cost == Decimal("412.32") - assert summary.cumulative_member_payments == Decimal("68.88") - assert summary.cumulative_net_liquidity == Decimal("-340.40") - assert summary.remaining_budget == Decimal("659.60") + assert summary.cumulative_payment_processing_cost == Decimal("3.52") + assert summary.cumulative_total_platform_cost == Decimal("412.80") + assert summary.cumulative_member_payments == Decimal("68.40") + assert summary.cumulative_net_liquidity == Decimal("-340.88") + assert summary.remaining_budget == Decimal("659.12") assert summary.liquidity_status == "burning" assert summary.months_tracked == 18 @@ -95,11 +95,23 @@ def test_build_monthly_ledger_matches_loader() -> None: ) +def test_payment_records_match_stripe_actuals_for_tegwick() -> None: + payments = load_payment_records(DATA_DIR) + nov = next(p for p in payments if p.period == "2025-11") + + assert nov.gross_amount == Decimal("8.99") + assert nov.fees_amount == Decimal("0.44") + assert nov.net_amount == Decimal("8.55") + assert nov.member_username == "tegwick" + assert nov.payout_account == "binky-hedgehog" + assert nov.source == "stripe" + + def test_dashboard_notes_expense_record_source() -> None: from observatory.dashboard import generate_dashboard report = generate_dashboard(DATA_DIR, "2026-06") assert "expense and payment record ledgers" in report assert "409.28" in report - assert "659.60" in report + assert "659.12" in report assert "coulomb.social" not in report # dashboard shows aggregates, not domain names \ No newline at end of file