Restore operator platform costs (Bubble, domains, Stripe) with monthly history from March 2025 and member payments from November 2025. Track €1,000 starting budget, cumulative burn, and remaining liquidity in the economics dashboard. Document LQ requirements in REQUIREMENTS.md.
84 lines
No EOL
2.9 KiB
Python
84 lines
No EOL
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
from decimal import Decimal
|
|
from pathlib import Path
|
|
|
|
from observatory.economics import (
|
|
active_members,
|
|
build_liquidity_summary,
|
|
build_snapshot,
|
|
monthly_cost_from_rate_card,
|
|
)
|
|
from observatory.load import (
|
|
load_budget,
|
|
load_cost_rate_card,
|
|
load_membership,
|
|
load_monthly_platform_costs,
|
|
load_pricing_models,
|
|
load_product,
|
|
load_revenue,
|
|
)
|
|
|
|
DATA_DIR = Path(__file__).resolve().parent.parent / "data"
|
|
|
|
|
|
def test_active_members_counts_only_active_status() -> None:
|
|
members = load_membership(DATA_DIR)
|
|
assert active_members(members) == 1
|
|
|
|
|
|
def test_rate_card_matches_documented_platform_cost_without_revenue() -> None:
|
|
rate_card, fx_rates = load_cost_rate_card(DATA_DIR)
|
|
total = monthly_cost_from_rate_card(rate_card, fx_rates, Decimal("0"), 0)
|
|
assert total == Decimal("72.20")
|
|
|
|
|
|
def test_rate_card_matches_platform_cost_with_one_member() -> None:
|
|
rate_card, fx_rates = load_cost_rate_card(DATA_DIR)
|
|
total = monthly_cost_from_rate_card(rate_card, fx_rates, Decimal("8.99"), 1)
|
|
assert total == Decimal("72.58")
|
|
|
|
|
|
def test_build_snapshot_june_2026_shows_liquidity_burn() -> None:
|
|
product = load_product(DATA_DIR)
|
|
models = load_pricing_models(DATA_DIR)
|
|
members = load_membership(DATA_DIR)
|
|
revenue = load_revenue(DATA_DIR)
|
|
monthly_costs = load_monthly_platform_costs(DATA_DIR)
|
|
|
|
snapshot = build_snapshot("2026-06", product, models, members, revenue, monthly_costs)
|
|
|
|
assert snapshot.active_members == 1
|
|
assert snapshot.monthly_revenue == Decimal("8.99")
|
|
assert snapshot.monthly_platform_cost == Decimal("72.58")
|
|
assert snapshot.period_net_liquidity == Decimal("-63.97")
|
|
assert snapshot.liquidity_status == "burning"
|
|
assert snapshot.gross_margin == Decimal("-63.59")
|
|
|
|
|
|
def test_liquidity_summary_tracks_budget_burn_through_june_2026() -> None:
|
|
budget = load_budget(DATA_DIR)
|
|
revenue = load_revenue(DATA_DIR)
|
|
monthly_costs = load_monthly_platform_costs(DATA_DIR)
|
|
|
|
summary = build_liquidity_summary(budget, revenue, monthly_costs, "2026-06")
|
|
|
|
assert summary.initial_budget == Decimal("1000.00")
|
|
assert summary.cumulative_platform_cost == Decimal("1158.24")
|
|
assert summary.cumulative_member_payments == Decimal("68.88")
|
|
assert summary.cumulative_net_liquidity == Decimal("-1089.36")
|
|
assert summary.remaining_budget == Decimal("-89.36")
|
|
assert summary.liquidity_status == "burning"
|
|
assert summary.months_tracked == 16
|
|
|
|
|
|
def test_dashboard_renders_liquidity_sections() -> None:
|
|
from observatory.dashboard import generate_dashboard
|
|
|
|
report = generate_dashboard(DATA_DIR, "2026-06")
|
|
assert "Liquidity & Budget" in report
|
|
assert "Monthly History" in report
|
|
assert "2025-03" in report
|
|
assert "2025-11" in report
|
|
assert "remaining budget" not in report.lower() or "Remaining budget" in report
|
|
assert "-89.36" in report |