Implement comparable LTV engine and close WP-0005

This commit is contained in:
codex
2026-07-02 22:50:16 +02:00
parent 656bbb81a5
commit 386c8a46fe
13 changed files with 1060 additions and 68 deletions

View File

@@ -24,6 +24,10 @@ def test_dashboard_payload_contains_live_ledger_totals() -> None:
assert payload["membership_analytics"]["active_members"] == 1
assert payload["usage"]["record_count"] == 1
assert len(payload["pricing_simulations"]["scenarios"]) == 3
assert len(payload["pricing_simulations"]["profile_comparisons"]) == 2
assert payload["pricing_simulations"]["primary_profile_id"] == "solo-builder"
assert payload["pricing_simulations"]["required_improvement_factor"] == "1.05"
assert payload["pricing_simulations"]["reference_model_id"] is not None
assert len(payload["boundary_validation"]["model_results"]) == 3
assert payload["boundary_validation"]["policy"]["target_margin_pct"] == "15"
assert any(

View File

@@ -0,0 +1,69 @@
from __future__ import annotations
from pathlib import Path
from observatory.economics import build_snapshot
from observatory.load import (
load_ltv_scenarios,
load_membership,
load_monthly_ledger,
load_payment_records,
load_pricing_models,
load_product,
)
from observatory.simulator import build_pricing_simulations
from observatory.usage import load_usage_records
DATA_DIR = Path(__file__).resolve().parent.parent / "data"
def _snapshot(period: str = "2026-06"):
product = load_product(DATA_DIR)
models = load_pricing_models(DATA_DIR)
members = load_membership(DATA_DIR)
payments = load_payment_records(DATA_DIR)
ledger = load_monthly_ledger(DATA_DIR)
return build_snapshot(period, product, models, members, payments, ledger)
def test_simulations_include_reference_model_and_profile_comparisons() -> None:
snapshot = _snapshot()
models = load_pricing_models(DATA_DIR)
simulations = build_pricing_simulations(
snapshot,
models,
snapshot.cost_per_member,
usage_records=load_usage_records(DATA_DIR),
scenario_catalog=load_ltv_scenarios(DATA_DIR),
)
assert simulations["primary_profile_id"] == "solo-builder"
assert simulations["reference_model_id"] is not None
assert simulations["best_ltv_scenario_id"] is not None
assert len(simulations["profile_comparisons"]) == 2
assert simulations["scenarios"][0]["average_comparable_customer_lifetime_value"] is not None
assert simulations["scenarios"][0]["sensitivity"]
def test_small_team_profile_has_reference_and_non_passing_candidates() -> None:
snapshot = _snapshot()
models = load_pricing_models(DATA_DIR)
simulations = build_pricing_simulations(
snapshot,
models,
snapshot.cost_per_member,
usage_records=load_usage_records(DATA_DIR),
scenario_catalog=load_ltv_scenarios(DATA_DIR),
)
small_team = next(
item for item in simulations["profile_comparisons"] if item["profile"]["id"] == "small-team"
)
assert small_team["reference_model_id"] is not None
assert small_team["best_valid_model_id"] is not None
assert any(
not comparison["passes_required_improvement"]
for comparison in small_team["comparisons"]
if comparison["model_id"] != small_team["reference_model_id"]
)

View File

@@ -8,6 +8,7 @@ from observatory.api import build_dashboard_payload
from observatory.credits import build_credit_summary, load_credit_wallets
from observatory.economics import build_snapshot
from observatory.load import (
load_ltv_scenarios,
load_membership,
load_monthly_ledger,
load_payment_records,
@@ -58,10 +59,18 @@ def test_cost_allocation_includes_ai_variable_cost() -> None:
def test_pricing_simulator_compares_candidate_models() -> None:
snapshot = _snapshot()
models = load_pricing_models(DATA_DIR)
simulations = build_pricing_simulations(snapshot, models, Decimal("0.06"))
simulations = build_pricing_simulations(
snapshot,
models,
Decimal("0.06"),
usage_records=load_usage_records(DATA_DIR),
scenario_catalog=load_ltv_scenarios(DATA_DIR),
)
assert len(simulations["scenarios"]) == 3
assert simulations["active_scenario_id"] == "flat-899-eur-monthly"
assert simulations["best_ltv_scenario_id"] is not None
assert simulations["reference_model_id"] is not None
def test_credit_summary_tracks_remaining_allowance() -> None:
@@ -93,4 +102,4 @@ def test_dashboard_payload_includes_mvp_sections() -> None:
assert "cost_allocation" in payload
assert "pricing_simulations" in payload
assert "credit_wallets" in payload
assert "recommendations" in payload
assert "recommendations" in payload