# Palladium

**TEI (Total Economic Impact) Calculator** — The strategic artifact that protects the business case.

Palladium is a Jupyter notebook + Streamlit toolkit for building Total Economic Impact analyses. It connects to [Athena](https://athena.nttdata.com) for data persistence, performs financial calculations (NPV, ROI, payback period), and exports structured data for the report generation pipeline.

> *In Greek mythology, the Palladium was a sacred artifact of Athena that protected Troy. Whoever possessed it held strategic advantage. In our ecosystem, Palladium protects the deal — transforming discovery inputs into a financial case no CFO can ignore.*

## Architecture

```
┌──────────────────────────────────────────────────────────────────┐
│  Palladium                                                        │
│                                                                   │
│   studies/202602_AmazonConnect/      ← one folder per TEI study   │
│   studies/YYYYMM_<Vendor>/                                        │
│         ├─ notebooks/  ─┐                                         │
│         ├─ seed_data.py │                                         │
│         └─ config.py    │                                         │
│                         ▼                                         │
│                  ┌──────────────┐    ┌──────────────┐             │
│                  │     core/    │ ←─ │      app/    │             │
│                  │ shared logic │    │  Streamlit   │             │
│                  └──────┬───────┘    └──────┬───────┘             │
│                         │                   │                     │
│                         ▼                   ▼                     │
│                   tei_client → ───────────────────►  Athena API   │
│                   calculations                                    │
│                   export ──────────────────────────► export.json  │
│                   notebook_helpers                                │
│                   cli                                             │
└──────────────────────────────────────────────────────────────────┘
```

### Components

| Component | Purpose |
|-----------|---------|
| **`core/tei_client`** | Python API client for Athena's TEI endpoints |
| **`core/calculations`** | Financial logic — NPV, ROI, payback, risk adjustment, scenarios |
| **`core/export`** | Builds the structured JSON envelope consumed by the report pipeline |
| **`core/notebook_helpers`** | Pandas tables, Plotly charts, IPython display widgets |
| **`core/cli`** | `python -m palladium` command-line interface |
| **`app/`** | Streamlit data-entry UI with version management — *study-agnostic* |
| **`studies/`** | One folder per TEI engagement (notebooks, seed data, config, source PDF) |

---

## Quick Start — Jupyter Lab first

Palladium is a **Jupyter Lab-first** environment. Everything starts from a
notebook; the Streamlit app and CLI are companions, not prerequisites.

```bash
git clone https://github.com/nttdata/palladium.git
cd palladium
make setup     # venv + deps + editable install (one time)
make lab       # launches Jupyter Lab
```

Then open **`00_setup.ipynb`** at the repo root. It will:

1. Prompt for your Athena API key (hidden input) and save it to `.env`
2. Test the connection
3. Show what report templates and tools exist in the instance

Current target instance: **https://athena.ouranos.helu.ca** (Ouranos sandbox —
no production data, safe to experiment).

From any notebook, setup is one import:

```python
from core.bootstrap import init

pal = init(study="202602_AmazonConnect")   # loads .env, connects, imports study
pal.client.list_reports()
pal.seed_data.BENEFITS
```

### Configuration

All credentials and IDs live in `<repo>/.env` (gitignored). `00_setup.ipynb`
writes it for you; to do it by hand:

```bash
# .env
ATHENA_BASE_URL=https://athena.ouranos.helu.ca
ATHENA_API_KEY=your-api-key-here
# written by the provisioning notebook:
PALLADIUM_REPORT_PUBLIC_ID=...
PALLADIUM_TOOL_PUBLIC_ID=...
PALLADIUM_PROPOSAL_ID=...        # or PALLADIUM_ENGAGEMENT_ID — a TEI tool
                                 # attaches to exactly one of the two
```

### Verify Connection

In a notebook: `init()` prints the connection status. From a shell:

```bash
python -m palladium test
```

---

## Usage

### Run a study end-to-end

Each study lives in `studies/<slug>/`. The reference study is the
February 2026 Forrester *Total Economic Impact™ Of Amazon Connect*:

```bash
make lab    # then browse to studies/202602_AmazonConnect/notebooks/
```

| Notebook | Purpose |
|----------|---------|
| `00_provision.ipynb` | **Run first** — creates the report template + fields, lets you select the CRM client and the Proposal/Engagement to attach to (pulling the client's profile to avoid re-entry), creates the tool, seeds the published values, calculates, and verifies the totals |
| `01_benefits.ipynb` | Quantify and risk-adjust benefit categories |
| `02_costs.ipynb` | Document implementation and ongoing costs |
| `03_business_case.ipynb` | Financial summary, scenario analysis, visualizations |
| `04_export.ipynb` | Generate report-ready JSON for the html2docx pipeline |

The Amazon Connect notebooks reproduce the published study totals within
rounding: **NPV $78.7M • ROI 342% • Payback <6 months**.

### Streamlit application (study-agnostic)

Interactive UI for data entry and version management. Works for any TEI
study because field definitions come from Athena at runtime:

```bash
streamlit run app/main.py
```

### CLI

```bash
# Test connection
python -m palladium test

# List TEI tool instances
python -m palladium list

# List available report templates
python -m palladium reports

# Show financial summary for a tool
python -m palladium summary <public_id>

# Trigger server-side recalculation
python -m palladium calculate <public_id>

# Export for the report pipeline
python -m palladium export <public_id> -o export.json
```

### Tests

```bash
pytest tests/ -v
```

50 tests cover the API client (mocked HTTP), the financial math, and the
export envelope shape. The Amazon Connect seed data is asserted against
the published Forrester totals.

---

## Adding a new study

```bash
cp -r studies/202602_AmazonConnect studies/202612_GenesysCloud
cd studies/202612_GenesysCloud
```

1. **`README.md`** — update the title, source citation, key numbers.
2. **`seed_data.py`** — replace `BENEFITS` and `COSTS` with the new study's rows.
3. **`config.py`** — set `STUDY_SLUG`, leave `TOOL_PUBLIC_ID` blank until provisioned.
4. **`docs/`** — drop the source PDF here.
5. Open the notebooks; the imports (`core.calculations`, `core.notebook_helpers`,
   `core.tei_client`) are study-agnostic. Update the markdown narrative.

The shared `core/` package and the `app/` Streamlit UI need no changes —
they introspect the TEI Report template via the API.

---

## TEI Methodology

Palladium implements the Forrester TEI™ framework.

### Benefit Categories

Benefits are quantified across categories, risk-adjusted, and discounted to present value:

| Category | Examples |
|----------|----------|
| **Cost Savings** | Legacy license elimination, reduced headcount, lower telecom |
| **Productivity** | Reduced handle time, faster training, automated QA |
| **Revenue** | Improved retention, better conversion, new channel revenue |
| **Risk Reduction** | Compliance automation, reduced legal exposure, audit readiness |

### Risk Adjustment

Each benefit carries a risk-adjustment factor (0–50%) reflecting implementation uncertainty.
A 20% risk adjustment on a $10M benefit yields a risk-adjusted value of $8M.
**Costs** are risk-adjusted **upward** by the same factor (higher risk → higher modelled cost).

### Financial Metrics

| Metric | Description |
|--------|-------------|
| **NPV** | Net Present Value — total risk-adjusted benefits minus costs, discounted |
| **ROI** | Return on Investment — `(benefits − costs) / costs × 100` |
| **Payback** | Months until cumulative benefits exceed cumulative costs |

The initial investment (year 0) is **not** discounted. Year-N cashflows are
discounted at the end of the year: `PV = CF_n / (1 + r)^n`. This matches
the Forrester methodology used in the published studies.

### Scenario Analysis

Three scenarios model uncertainty in adoption and realization
(see `core.calculations.SCENARIOS`):

| Scenario | Adoption | Risk delta | Effect |
|----------|----------|------------|--------|
| Conservative | 80% | +10pp on benefits | Lower benefits, higher modelled cost |
| Moderate | 100% | 0 | Base case (= published study) |
| Aggressive | 115% | –5pp on benefits | Higher benefits, lower padding on cost |

---

## Project Structure

```
palladium/
├── 00_setup.ipynb                     # ← START HERE: credentials + connection
├── Makefile                           # make setup / lab / app / test
├── core/                              # Shared, study-agnostic Python package
│   ├── bootstrap.py                   # one-import notebook setup (init, save_credentials)
│   ├── tei_client/                    # Athena API client
│   │   ├── client.py                  # TEIClient with all /api/v1/tei/ methods
│   │   └── models.py                  # Optional dataclasses for typed access
│   ├── calculations/                  # Pure-python financial math
│   │   ├── npv.py
│   │   ├── roi.py
│   │   ├── payback.py
│   │   └── scenarios.py
│   ├── export/
│   │   └── report_data.py             # JSON envelope for the report pipeline
│   ├── notebook_helpers/
│   │   ├── tables.py                  # Pandas dataframe builders
│   │   ├── charts.py                  # Plotly figures
│   │   └── display.py                 # IPython KPI cards, alerts
│   └── cli/
│       └── main.py                    # `python -m palladium ...`
├── palladium/                         # CLI shim (just exposes `python -m palladium`)
│   └── __main__.py
├── app/                               # Streamlit UI — works with any TEI study
│   ├── main.py                        # entry point
│   ├── views/                         # benefits, costs, summary, versions (NOT `pages/` — avoids Streamlit auto-multipage)
│   └── components/                    # tables, charts
├── studies/                           # One folder per TEI engagement
│   ├── 202512_GenesysCX/              # CX Cloud (Genesys + Salesforce) TEI
│   │   ├── README.md                  # NPV $10.8M · ROI 266% + AI-token line
│   │   ├── config.py / seed_data.py   # study-scoped PALLADIUM_GENESYSCX_* keys
│   │   └── notebooks/                 # 00_provision, 01_business_case
│   └── 202602_AmazonConnect/
│       ├── README.md
│       ├── config.py                  # TOOL_PUBLIC_ID, REPORT_PUBLIC_ID
│       ├── seed_data.py               # 5 benefits + 3 costs from the PDF
│       ├── notebooks/
│       │   ├── 00_provision.ipynb     # creates template+tool in Athena, seeds & verifies
│       │   ├── 01_benefits.ipynb
│       │   ├── 02_costs.ipynb
│       │   ├── 03_business_case.ipynb
│       │   └── 04_export.ipynb
│       ├── exports/                   # generated; .gitignored
│       └── docs/
│           └── 202602_TEI Report Amazon Connect.pdf
├── tests/                             # 50 tests for core/
│   ├── test_client.py
│   ├── test_calculations.py
│   └── test_export.py
├── Athena API.yaml                    # OpenAPI reference
├── .env.example
├── requirements.txt
├── pyproject.toml
└── README.md
```

---

## Athena Integration

Palladium connects to Athena's TEI module for data persistence and cross-tool reporting.

### API Endpoints Used

All endpoints are under `/api/v1/tei/` and require `Authorization: Api-Key {key}`.

| Endpoint | Purpose |
|----------|---------|
| `GET /api/v1/tei/reports/` | List available TEI report templates |
| `GET /api/v1/tei/reports/{public_id}/` | Get a report template |
| `GET /api/v1/tei/reports/{public_id}/fields/` | Get field definitions for a template |
| `POST /api/v1/tei/tools/` | Create a new TEI tool instance |
| `GET /api/v1/tei/tools/{public_id}/` | Get instance metadata |
| `PATCH /api/v1/tei/tools/{public_id}/` | Update name/status |
| `GET /api/v1/tei/tools/{public_id}/values/` | Get current field values |
| `PUT /api/v1/tei/tools/{public_id}/values/` | Bulk-update values |
| `PATCH /api/v1/tei/tools/{public_id}/values/{field_key}/` | Patch a single value |
| `POST /api/v1/tei/tools/{public_id}/calculate/` | Trigger calculation |
| `GET /api/v1/tei/tools/{public_id}/summary/` | Get financial summary |
| `GET /api/v1/tei/tools/{public_id}/versions/` | List version snapshots |
| `POST /api/v1/tei/tools/{public_id}/versions/` | Save a new version |
| `GET /api/v1/tei/tools/{public_id}/versions/{n}/` | Get a specific version |
| `GET /api/v1/tei/tools/{public_id}/export/` | Export for the report pipeline |
| `GET /api/v1/tei/summary/` | Aggregate NPV across all tools |

### Object model

| Athena object | Notes |
|---|---|
| **Opportunity** | Top-level sales record. Owns one or more **Proposals**. |
| **Proposal** | A specific bid/offer to a client. **A TEI tool is linked to a Proposal.** |
| **Engagement** | Optional — for active client engagements. A TEI tool may also link here. |
| **TEIReport** | Template (e.g. *Amazon Connect 2026*) — defines fields, discount rate, analysis horizon. |
| **TEITool** | Instance of a Report bound to a Proposal — holds values, summaries, versions. |

### Authentication

```
Authorization: Api-Key {your-api-key}
```

API keys are provisioned in Athena's admin interface per user/service account.

### Methodology conventions (Palladium ↔ Athena)

Two places where the Forrester methodology and the Athena TEI API differ, and
how Palladium bridges them:

| Topic | Athena behaviour | Palladium convention |
|---|---|---|
| **Cost risk adjustment** | Costs are never risk-adjusted server-side | Cost values are pushed pre-multiplied by `(1 + risk_adj)`; field-level adjustment stays 0 |
| **Year-0 "Initial" costs** | No year-0 concept; non-annual values are folded into Year 1 | Each cost gets a companion non-annual `<key>_initial` field. `TEIClient` folds them back into an `initial` key on read. Athena discounts these as Year 1 (Forrester doesn't discount Year 0) — expect ≈0.15% drift on cost PV |

---

## Report Pipeline Integration

Palladium's export produces structured JSON consumed by the LLM report generation pipeline:

```
Palladium Export (JSON)
    │
    ▼
Peitho — LLM generates HTML (following HTML_DOCUMENT_FORMAT.md)
    │
    ▼
html2docx converts to native Word
    │
    ▼
Professional TEI Report (.docx)
```

The export envelope (`core.export.build_report_data`) includes:
- All benefit categories with risk-adjusted values
- All cost categories with yearly breakdown (and Initial column)
- Financial summary (NPV, ROI, payback, yearly cashflow)
- Conservative / moderate / aggressive scenario analysis
- Metadata (study slug, proposal, engagement, generator stamp)
- The raw Athena `/export/` payload for reference

---

## Version Management

Palladium manages version history through both the API and the Streamlit UI:

1. **Save Version** — Snapshots current values + summary with a descriptive note
2. **View History** — All versions with headline metrics (NPV, ROI)
3. **Compare Versions** — Side-by-side diff of value changes between any two versions
4. **Restore Version** — Load a previous version's values as the current state

Version notes should capture:
- Assumptions made and their sources
- Which scenario the version represents
- What changed since the previous version
- Client confirmations or corrections

---

## Development

### Running Tests

```bash
pytest tests/ -v
```

Tests are designed to run without an Athena connection — HTTP is mocked
and the calculation suite uses the Amazon Connect seed data to verify the
Forrester numbers reproduce within rounding.

### Code Style

```bash
ruff check .
ruff format .
```

### Adding a New Benefit Category

1. Define the field in Athena's TEI Report admin (field name, type, category, defaults)
2. The field automatically appears in Palladium via the API — no client changes
3. Update notebook prose if category-specific commentary is needed
4. If the report template exposes a new structure, extend the envelope in
   `core/export/report_data.py`

---

## Dependencies

| Package | Version | Purpose |
|---------|---------|---------|
| `requests` | ≥2.31 | HTTP client for Athena API |
| `python-dotenv` | ≥1.0 | Environment configuration |
| `jupyter` | ≥1.0 | Notebook environment |
| `streamlit` | ≥1.30 | Data entry application |
| `pandas` | ≥2.0 | Data manipulation |
| `plotly` | ≥5.18 | Interactive visualizations |
| `numpy` | ≥1.26 | Financial calculations |
| `pytest` | ≥7.4 | Testing |
| `ruff` | ≥0.1 | Linting and formatting |

---

## Related Projects

| Project | Relationship |
|---------|-------------|
| **Athena** | Platform API — data persistence, cross-tool reporting |
| **Peitho** | Document generation — consumes Palladium's export JSON |
| **html2docx** | Converts LLM-generated HTML to native Word documents |
