Files
Robert Helewka a420af230b Migrate Amazon Connect TEI study to the Mercury Notebook Pattern
studies/202602_AmazonConnect -> studies/202602_TEI_Amazon_Connect,
rebuilt as pattern Variant 4 (TEI composite reproduction):

- teicalc/ self-contained engine (stdlib-only): Forrester's tables as
  the never-edited verbatim anchor, NPV/ROI/payback + risk adjustment
  transplanted from core/calculations, ClientDrivers overlay (contacts/
  agents/fixed driver map, growth re-base, identity at composite scale),
  scenario stress with core-identical semantics
- one deliverable notebook (business_case.ipynb): widget-pair sidebar
  drivers, published-vs-overlay KPI columns, cash-flow/waterfall/scenario
  charts, verification gate, backstage JSON data appendix
- gate + tests reproduce the published totals within PDF rounding:
  NPV $78.7M / ROI 342% / payback <6 months (engine $78,713,492 /
  342.48% / 0.7 months); 27 study tests, headless nbconvert green,
  stage simulation leak-free, exports carry the appendix
- old Athena workflow (00_provision..04_export, config.py, seed_data.py)
  deleted; git history preserves it; root test fixture repointed to
  teicalc.anchor
- docs: study README rewritten; root README points new studies at
  template/MercuryNotebook; pattern doc stale ctm-token-calculator paths
  now cite studies/202607_CTM_GenesysCX; Variant 4 cites this study as
  its realized reference

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 14:29:46 -04:00

76 lines
2.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Scenario pins — hand-checked composite results per scenario, clamp
behaviour, and copy semantics."""
import pytest
from teicalc import (
BENEFITS_VERBATIM,
COSTS_VERBATIM,
SCENARIOS,
apply_scenario,
compute_summary,
)
def _summary(scenario):
return compute_summary(
apply_scenario(BENEFITS_VERBATIM, scenario),
apply_scenario(COSTS_VERBATIM, scenario),
0.10,
)
def test_scenario_definitions():
assert SCENARIOS == {
"conservative": {"adoption": 0.80, "risk_delta": 0.10},
"moderate": {"adoption": 1.00, "risk_delta": 0.00},
"aggressive": {"adoption": 1.15, "risk_delta": -0.05},
}
def test_moderate_is_identity():
got = _summary("moderate")
want = compute_summary(BENEFITS_VERBATIM, COSTS_VERBATIM, 0.10)
assert got["benefits_pv"] == pytest.approx(want["benefits_pv"], abs=0.01)
assert got["costs_pv"] == pytest.approx(want["costs_pv"], abs=0.01)
def test_conservative_pins():
s = _summary("conservative")
assert s["benefits_pv"] == pytest.approx(71_672_867.65, abs=1)
assert s["costs_pv"] == pytest.approx(17_437_916.34, abs=1)
assert s["npv"] == pytest.approx(54_234_951.31, abs=1)
assert s["roi_pct"] == pytest.approx(311.02, abs=0.01)
assert s["payback_months"] == pytest.approx(0.763, abs=0.001)
def test_aggressive_pins():
s = _summary("aggressive")
assert s["benefits_pv"] == pytest.approx(123_911_705.40, abs=1)
assert s["costs_pv"] == pytest.approx(27_682_368.61, abs=1)
assert s["npv"] == pytest.approx(96_229_336.79, abs=1)
assert s["roi_pct"] == pytest.approx(347.62, abs=0.01)
assert s["payback_months"] == pytest.approx(0.705, abs=0.001)
def test_risk_delta_clamps_at_zero():
"""Conservative subtracts 0.10 from cost risk; usage (0.05) clamps to 0."""
rows = apply_scenario(COSTS_VERBATIM, "conservative")
usage = next(r for r in rows if r["field_key"] == "amazon_connect_usage")
assert usage["risk_adjustment"] == 0.0
impl = next(r for r in rows if r["field_key"] == "implementation_migration")
assert impl["risk_adjustment"] == pytest.approx(0.0) # 0.10 0.10
assert impl["initial"] == pytest.approx(1_087_500 * 0.80) # adoption scales initial
def test_unknown_scenario_raises():
with pytest.raises(KeyError):
apply_scenario(BENEFITS_VERBATIM, "wildly_optimistic")
def test_inputs_not_mutated():
apply_scenario(BENEFITS_VERBATIM, "aggressive")
apply_scenario(COSTS_VERBATIM, "conservative")
assert BENEFITS_VERBATIM[0]["year_values"]["1"] == 13_911_040
assert COSTS_VERBATIM[1]["initial"] == 1_087_500