generated from coulomb/repo-seed
observatory stuff
This commit is contained in:
@@ -11,12 +11,15 @@ from .load import (
|
||||
latest_period,
|
||||
load_budget,
|
||||
load_expense_records,
|
||||
load_market_signals,
|
||||
load_membership,
|
||||
load_monthly_ledger,
|
||||
load_payment_records,
|
||||
load_pricing_models,
|
||||
load_product,
|
||||
load_value_range,
|
||||
)
|
||||
from .pricing_context import build_cost_floor, build_market_price_view, build_value_range_view
|
||||
|
||||
|
||||
def _serialize(value: Any) -> Any:
|
||||
@@ -72,6 +75,9 @@ def build_dashboard_payload(data_dir: Path | None = None, period: str | None = N
|
||||
}
|
||||
)
|
||||
|
||||
value_range_raw = load_value_range(root)
|
||||
market_raw = load_market_signals(root)
|
||||
|
||||
return _serialize(
|
||||
{
|
||||
"design_reference": "https://claude.ai/design/p/fb2eef8c-c1fc-4c75-bff4-3782552e5511",
|
||||
@@ -85,6 +91,9 @@ def build_dashboard_payload(data_dir: Path | None = None, period: str | None = N
|
||||
"members": members,
|
||||
"payments": payments,
|
||||
"expense_record_count": len(expenses),
|
||||
"cost_floor": build_cost_floor(snapshot, models),
|
||||
"value_range": build_value_range_view(value_range_raw, snapshot, product, models),
|
||||
"market_price": build_market_price_view(market_raw),
|
||||
"infrastructure": {
|
||||
"domains": _load_json_catalog(root, "domains.json"),
|
||||
"virtual_servers": _load_json_catalog(root, "virtual_servers.json"),
|
||||
|
||||
@@ -116,6 +116,14 @@ def load_payment_records(data_dir: Path | None = None) -> list[PaymentRecord]:
|
||||
]
|
||||
|
||||
|
||||
def load_value_range(data_dir: Path | None = None) -> dict:
|
||||
return _read_json((data_dir or default_data_dir()) / "value_range.json")
|
||||
|
||||
|
||||
def load_market_signals(data_dir: Path | None = None) -> dict:
|
||||
return _read_json((data_dir or default_data_dir()) / "market_signals.json")
|
||||
|
||||
|
||||
def load_membership(data_dir: Path | None = None) -> list[MembershipRecord]:
|
||||
raw = _read_json((data_dir or default_data_dir()) / "membership.json")
|
||||
return [
|
||||
|
||||
93
projects/coulomb-pricing/observatory/pricing_context.py
Normal file
93
projects/coulomb-pricing/observatory/pricing_context.py
Normal file
@@ -0,0 +1,93 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from decimal import Decimal, ROUND_HALF_UP
|
||||
|
||||
from .economics import active_pricing_model
|
||||
from .models import EconomicsSnapshot, PricingModel, Product
|
||||
|
||||
TWOPLACES = Decimal("0.01")
|
||||
|
||||
|
||||
def _quantize(value: Decimal) -> Decimal:
|
||||
return value.quantize(TWOPLACES, rounding=ROUND_HALF_UP)
|
||||
|
||||
|
||||
def build_cost_floor(
|
||||
snapshot: EconomicsSnapshot,
|
||||
models: list[PricingModel],
|
||||
) -> dict:
|
||||
active = next((m for m in models if m.status == "active"), None)
|
||||
return {
|
||||
"period": snapshot.period,
|
||||
"currency": snapshot.currency,
|
||||
"monthly_infrastructure_cost": snapshot.monthly_infrastructure_cost,
|
||||
"monthly_payment_processing_cost": snapshot.monthly_payment_processing_cost,
|
||||
"monthly_total_platform_cost": snapshot.monthly_total_platform_cost,
|
||||
"cost_per_member": snapshot.cost_per_member,
|
||||
"active_members": snapshot.active_members,
|
||||
"monthly_revenue": snapshot.monthly_revenue,
|
||||
"gross_margin": snapshot.gross_margin,
|
||||
"gross_margin_pct": snapshot.gross_margin_pct,
|
||||
"active_price": active.access_fee_amount if active else Decimal("0"),
|
||||
"active_model_id": active.id if active else None,
|
||||
"active_model_name": active.name if active else None,
|
||||
}
|
||||
|
||||
|
||||
def build_value_range_view(
|
||||
raw: dict,
|
||||
snapshot: EconomicsSnapshot,
|
||||
product: Product,
|
||||
models: list[PricingModel],
|
||||
) -> dict:
|
||||
model = active_pricing_model(models, product)
|
||||
current = model.access_fee_amount
|
||||
segments = []
|
||||
lows: list[Decimal] = []
|
||||
highs: list[Decimal] = []
|
||||
for item in raw.get("segments", []):
|
||||
low = Decimal(str(item["low_eur"]))
|
||||
high = Decimal(str(item["high_eur"]))
|
||||
lows.append(low)
|
||||
highs.append(high)
|
||||
segments.append(
|
||||
{
|
||||
**item,
|
||||
"headroom_to_high_eur": _quantize(high - current),
|
||||
"below_floor": current < low,
|
||||
}
|
||||
)
|
||||
|
||||
aggregate_low = min(lows) if lows else current
|
||||
aggregate_high = max(highs) if highs else current
|
||||
|
||||
return {
|
||||
"currency": raw.get("currency", snapshot.currency),
|
||||
"product_id": raw.get("product_id", product.id),
|
||||
"current_price_eur": current,
|
||||
"aggregate_low_eur": aggregate_low,
|
||||
"aggregate_high_eur": aggregate_high,
|
||||
"cost_per_member_eur": snapshot.cost_per_member,
|
||||
"segments": segments,
|
||||
"value_drivers": raw.get("value_drivers", []),
|
||||
"notes": raw.get("notes", ""),
|
||||
}
|
||||
|
||||
|
||||
def build_market_price_view(raw: dict) -> dict:
|
||||
alternatives = list(raw.get("alternatives", []))
|
||||
prices = [
|
||||
Decimal(str(item["price_monthly_eur"]))
|
||||
for item in alternatives
|
||||
if item.get("price_monthly_eur") not in (None, "", "0", "0.00")
|
||||
]
|
||||
return {
|
||||
"currency": raw.get("currency", "EUR"),
|
||||
"last_reviewed": raw.get("last_reviewed"),
|
||||
"alternative_count": len(alternatives),
|
||||
"priced_alternative_count": len(prices),
|
||||
"market_low_eur": min(prices) if prices else None,
|
||||
"market_high_eur": max(prices) if prices else None,
|
||||
"alternatives": alternatives,
|
||||
"notes": raw.get("notes", ""),
|
||||
}
|
||||
Reference in New Issue
Block a user