feat: add locale formatting config and update notebook outputs

Add configurable locale/display formatting environment variables
(`PALLADIUM_CURRENCY_SYMBOL`, `PALLADIUM_THOUSANDS_SEP`,
`PALLADIUM_DECIMAL_SEP`) to support regional number formatting in the
Streamlit app. Update `.env.example` with documentation for these new
variables.

Also refresh `00_setup.ipynb` with current execution outputs reflecting
a live Athena connection with report templates, a selected client
(Global Guardian Insurance, ID=2), and resolved NameError in assumption
override cells.
This commit is contained in:
2026-06-10 11:54:28 -04:00
parent 253ff38118
commit ecd164ee6d
13 changed files with 839 additions and 111 deletions

View File

@@ -24,6 +24,7 @@ if str(_ROOT) not in sys.path:
import streamlit as st
from core.tei_client import AthenaAPIError, TEIClient
from app.utils import icon, inject_icons
st.set_page_config(
page_title="Palladium — TEI Calculator",
@@ -32,6 +33,7 @@ st.set_page_config(
)
@st.cache_resource(show_spinner=False)
def get_client() -> TEIClient:
return TEIClient()
@@ -75,7 +77,9 @@ def _crm_engagements(_client: TEIClient, client_name: str) -> list[dict]:
def sidebar_tool_picker(client: TEIClient) -> dict | None:
"""Sidebar: pick an existing TEI tool or create one from a report template."""
st.sidebar.title("🛡️ Palladium")
st.sidebar.markdown(
f"{icon('shield-fill')} **Palladium**", unsafe_allow_html=True
)
st.sidebar.caption("TEI Calculator")
tools = _safe_call(client.list_tools) or []
@@ -163,15 +167,20 @@ def sidebar_tool_picker(client: TEIClient) -> dict | None:
st.sidebar.markdown(f"**Public ID**: `{tool.get('id')}`")
st.sidebar.markdown(f"**Status**: {tool.get('status', '?')}")
st.sidebar.markdown(f"**Version**: {tool.get('current_version', 0)}")
if st.sidebar.button("🔄 Recalculate"):
if st.sidebar.button("Recalculate"):
_safe_call(client.calculate, tool["id"])
st.toast("Recalculated.", icon="")
st.toast("Recalculated.", icon=None)
st.cache_data.clear()
return tool
def main() -> None:
st.title("Palladium — TEI Calculator")
inject_icons()
st.markdown(
f"<h1 style='margin-bottom:0'>{icon('shield-fill')} Palladium — TEI Calculator</h1>",
unsafe_allow_html=True,
)
try:
client = get_client()
except ValueError as e:
@@ -186,14 +195,19 @@ def main() -> None:
st.info("Pick or create a TEI tool from the sidebar to begin.")
return
# Tab navigation — matches `app/pages/*` modules but kept as tabs so all
# Tab navigation — matches `app/views/*` modules but kept as tabs so all
# views share the chosen tool/state without re-querying.
tabs = st.tabs(["📊 Summary", "💰 Benefits", "💸 Costs", "🕒 Versions"])
#
# NOTE: the directory is `app/views/`, NOT `app/pages/`. Streamlit treats a
# `pages/` directory next to the entrypoint as auto-discovered multipage
# scripts, which would render blank since these modules only define
# `render()` and have no top-level output.
tabs = st.tabs(["Summary", "Benefits", "Costs", "Versions"])
from app.pages import benefits as benefits_page
from app.pages import costs as costs_page
from app.pages import summary as summary_page
from app.pages import versions as versions_page
from app.views import benefits as benefits_page
from app.views import costs as costs_page
from app.views import summary as summary_page
from app.views import versions as versions_page
with tabs[0]:
summary_page.render(client, tool)