TemHealth / app.py
vbzvibin's picture
Upload 32 files
3854e39 verified
import streamlit as st
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from ml_engine import CMSMLEngine
from agent_graph import build_robust_graph, save_graph_image
import os
import time
import io
from dotenv import load_dotenv
import importlib
import ml_engine as ml_module
# Load Env
load_dotenv()
# Page Configuration
st.set_page_config(
page_title="Temple Health | Unified Intelligence Hub",
page_icon="🏥",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS for Premium Design (Executive Edition)
st.markdown("""
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&display=swap');
html, body {
font-family: 'Inter', sans-serif;
color: #1e293b;
}
/* Light Sidebar Theme */
[data-testid="stSidebar"] {
background-color: #ffffff !important;
border-right: 1px solid #e2e8f0;
color: #1e293b;
}
[data-testid="stSidebar"] stMarkdown, [data-testid="stSidebar"] p {
color: #1e293b !important;
}
[data-testid="stSidebar"] .stRadio div[role="radiogroup"] label {
color: #1e293b !important;
}
h1, h2, h3, h4, .metric-label, .section-title {
font-family: 'Outfit', sans-serif;
}
.stApp {
background: #ffffff;
}
/* Executive Top KPI Cards */
.kpi-container {
display: flex;
gap: 20px;
margin-bottom: 30px;
}
.kpi-card {
flex: 1;
background: #ffffff;
border-radius: 12px;
padding: 20px;
border: 1px solid #e2e8f0;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
position: relative;
overflow: hidden;
}
.kpi-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
}
.kpi-red::before { background: #dc2626; }
.kpi-green::before { background: #10b981; }
.kpi-orange::before { background: #f59e0b; }
.kpi-gray::before { background: #64748b; }
.kpi-label { font-size: 0.8rem; color: #334155; font-weight: 600; }
.kpi-value { font-size: 1.8rem; font-weight: 700; color: #0f172a; margin: 4px 0; }
.kpi-delta { font-size: 0.75rem; font-weight: 700; }
/* Timeline Styling */
.timeline-container {
padding-left: 20px;
border-left: 2px solid #e2e8f0;
margin-left: 10px;
position: relative;
}
.timeline-item {
margin-bottom: 25px;
position: relative;
}
.timeline-dot {
position: absolute;
left: -29px;
top: 5px;
width: 16px;
height: 16px;
border-radius: 50%;
background: #fff;
border: 4px solid #3b82f6;
}
.timeline-date { font-size: 0.75rem; font-weight: 700; color: #dc2626; text-transform: uppercase; }
.timeline-title { font-size: 0.95rem; font-weight: 600; color: #0f172a; margin: 4px 0; }
.timeline-desc { font-size: 0.85rem; color: #334155; line-height: 1.4; font-weight: 500; }
.timeline-impact { font-size: 0.85rem; font-weight: 600; color: #dc2626; margin-top: 4px; }
/* Service Line Table Custom Styling */
.sl-row {
display: flex;
align-items: center;
padding: 15px 0;
border-bottom: 1px solid #f1f5f9;
font-size: 0.85rem;
}
.sl-name { flex: 2; font-weight: 600; color: #0f172a; }
.sl-sub { display: block; font-size: 0.75rem; font-weight: 500; color: #475569; }
.sl-exposure { flex: 2; display: flex; align-items: center; gap: 10px; }
.sl-opp { flex: 2; display: flex; align-items: center; gap: 10px; }
.sl-codes { flex: 1; text-align: center; font-weight: 600; }
.sl-risk { flex: 1; text-align: center; }
.sl-readiness { flex: 2; }
/* Custom Progress Bars */
.bar-bg { background: #f1f5f9; height: 6px; border-radius: 3px; flex-grow: 1; position: relative; }
.bar-fill { height: 100%; border-radius: 3px; }
.fill-red { background: #dc2626; }
.fill-green { background: #10b981; }
.fill-orange { background: #f59e0b; }
/* AI Action Cards - Image Match Edition */
.action-card {
background: #ffffff;
border: 1px solid #f1f5f9;
border-radius: 12px;
padding: 20px;
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 20px;
transition: all 0.2s ease;
position: relative;
}
.action-card:hover { border-color: #3b82f6; box-shadow: 0 4px 12px rgba(0,0,0,0.05); }
.action-sphere {
width: 24px;
height: 24px;
border-radius: 50%;
flex-shrink: 0;
box-shadow: inset -4px -4px 8px rgba(0,0,0,0.2), 2px 2px 4px rgba(0,0,0,0.1);
}
.sphere-red { background: radial-gradient(circle at 30% 30%, #ff5b5b, #dc2626); }
.sphere-orange { background: radial-gradient(circle at 30% 30%, #ffb347, #f59e0b); }
.action-content { flex-grow: 1; }
.action-title { font-size: 0.95rem; font-weight: 700; color: #0f172a; margin-bottom: 4px; }
.action-desc { font-size: 0.82rem; color: #334155; line-height: 1.4; margin-bottom: 8px; font-weight: 500; }
.action-meta { display: flex; align-items: center; gap: 15px; }
.action-impact-val { font-weight: 800; font-size: 0.85rem; color: #dc2626; }
.action-tag-pill {
padding: 4px 12px; border-radius: 8px; font-size: 0.7rem; font-weight: 700;
text-transform: uppercase; letter-spacing: 0.05em;
}
.tag-red { background: #fee2e2; color: #dc2626; }
.tag-yellow { background: #fef3c7; color: #d97706; }
.action-chevron { color: #cbd5e1; font-size: 1.2rem; }
.open-badge {
background: #fee2e2;
color: #dc2626;
padding: 2px 10px;
border-radius: 6px;
font-size: 0.7rem;
font-weight: 800;
border: 1px solid #fecaca;
}
/* Premium Claude-style Chat UX */
.chat-container {
max-width: 800px;
margin: 0 auto;
padding: 40px 20px 100px 20px;
}
.chat-bubble {
padding: 20px 24px;
border-radius: 20px;
margin-bottom: 24px;
line-height: 1.6;
font-size: 1rem;
box-shadow: 0 1px 4px rgba(0,0,0,0.03);
}
.assistant-bubble {
background: #ffffff;
border: 1px solid #e2e8f0;
color: #1e293b;
border-bottom-left-radius: 4px;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.user-bubble {
background: #f1f5f9;
color: #0f172a;
border: 1px solid #e2e8f0;
border-bottom-right-radius: 4px;
margin-left: 15%;
}
.stChatInputContainer {
padding-bottom: 40px !important;
background: transparent !important;
}
[data-testid="stChatInput"] {
border-radius: 28px !important;
border: 1px solid #e2e8f0 !important;
box-shadow: 0 4px 12px rgba(0,0,0,0.08) !important;
}
/* General Layout */
.section-box {
background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 16px;
padding: 25px;
height: 100%;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.section-title { font-size: 1.1rem; font-weight: 700; color: #0f172a; margin-bottom: 15px; }
/* Reasoning graph in sidebar */
.sidebar-graph-box {
background: #f8fafc;
border-radius: 12px;
padding: 12px;
border: 1px solid #e2e8f0;
margin-top: 10px;
overflow: hidden;
}
.sidebar-graph-box img {
max-height: 120px;
object-fit: contain;
}
/* Scrollbar Polish */
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: #f1f5f9; }
::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 3px; }
</style>
""", unsafe_allow_html=True)
# Initialize Engines
@st.cache_resource
def load_engines():
importlib.reload(ml_module)
from ml_engine import CMSMLEngine
engine = CMSMLEngine()
# Verification check to force reload if method missing
if not hasattr(engine, 'apply_cdm_patches'):
st.cache_resource.clear()
engine = CMSMLEngine()
graph = build_robust_graph()
return engine, graph
ml_engine, agent_graph = load_engines()
# Sidebar - Branding & Navigation
with st.sidebar:
st.image("https://upload.wikimedia.org/wikipedia/en/thumb/8/8e/Temple_University_Health_System_Logo.svg/1200px-Temple_University_Health_System_Logo.svg.png", width=200)
st.title("Intelligence Hub")
st.markdown("---")
# NAVIGATION
page = st.radio(
"Navigation",
["Executive Dashboard", "Risk Simulation Lab", "AI Strategic Advisor", "AI CDM Auto-Sync"],
index=0
)
st.markdown("---")
# CONDITIONAL SIDEBAR CONTENT: Reasoning Topology for Advisor
if page == "AI Strategic Advisor":
st.markdown('<div class="sidebar-graph-box">', unsafe_allow_html=True)
st.markdown('<div class="section-title" style="font-size:0.9rem; margin-bottom:10px;">🧠 Reasoning Topology</div>', unsafe_allow_html=True)
save_graph_image(agent_graph, "agent_workflow.png")
col1, col2, col3 = st.columns([1, 6, 1])
with col2:
st.image("agent_workflow.png", width=140)
st.markdown('<p style="font-size:0.75rem; color:#1e293b; text-align:center; font-weight:500;">Live trace of regulatory compliance reasoning paths.</p>', unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
st.markdown("---")
st.markdown("### 🏁 System Status")
st.markdown("- **Engine**: Active")
st.markdown("- **Data Context**: FY2025 CMS Rules")
st.markdown("- **Model Confidence**: 94%")
st.markdown("---")
if st.button("Clear History", key="clear_chat", use_container_width=True):
st.session_state.messages = []
st.session_state.thread_id = os.urandom(8).hex()
st.rerun()
if st.button("Re-train Engine", key="refresh_ai", use_container_width=True):
st.cache_resource.clear()
st.toast("Intelligence Engine Re-synchronized!")
st.rerun()
# --- PAGE ROUTING ---
def render_executive_hub():
exec_summary = ml_engine.get_executive_summary()
# 0. MASTER INTELLIGENCE GUIDE (Prominent explanation as requested)
with st.expander("📖 Unlocking Your Dashboard: Intelligence Guide", expanded=False):
st.markdown("""
### Welcome to the Temple Health Unified Intelligence Hub
This dashboard cross-references **$8.7M in clinical claims** against the **2025 CMS Regulatory Rules**.
Here is how to interpret the key sections:
* **🔴 Total Exposure Risk**: Your maximum potential loss if coding is not optimized for 2025 changes.
* **🟢 Recoverable Opportunity**: Missed revenue that can be captured via CDI improvements under the new rules.
* **🛡️ Compliance Maturity**: Formerly 'Readiness'. This score reflects how prepared your departments/coders are for the technical shifts in CMS weights.
* **🤖 AI Action Hub**: Machine-prioritized tasks to bridge the exposure-to-revenue gap.
*Click any **ⓘ Logic Detail** button throughout the hub to see specific formulas and strategic insights.*
""")
st.markdown("<br>", unsafe_allow_html=True)
c1, c2, c3, c4 = st.columns(4)
with c1:
st.markdown(f"""
<div class="kpi-card kpi-red">
<div class="kpi-label">Total Exposure Risk</div>
<div class="kpi-value">${exec_summary['total_exposure_risk']/1e6:.1f}M</div>
<div class="kpi-delta" style="color: #dc2626;">{exec_summary['exposure_delta']}</div>
</div>
""", unsafe_allow_html=True)
with st.popover("ⓘ Logic Detail", use_container_width=True):
st.markdown("### 🔴 Total Exposure Risk")
st.markdown("**Executive Insight**: This represents your 'at-risk' revenue. It is the total dollar value of claims predicted to be denied or audited based on 2025 CMS rule shifts.")
st.markdown("**Business Impact**: Highlights where financial leakage is most likely to occur due to documentation gaps.")
st.markdown("**Formula**: `Sum(Claim_Charges * Risk_Probability)` derived from the RandomForest model trained on historical denial patterns.")
with c2:
st.markdown(f"""
<div class="kpi-card kpi-green">
<div class="kpi-label">Recoverable Opportunity</div>
<div class="kpi-value">${exec_summary['recoverable_opportunity']/1e6:.1f}M</div>
<div class="kpi-delta" style="color: #10b981;">{exec_summary['opportunity_delta']}</div>
</div>
""", unsafe_allow_html=True)
with st.popover("ⓘ Logic Detail", use_container_width=True):
st.markdown("### 🟢 Recoverable Opportunity")
st.markdown("**Executive Insight**: This is 'found money'. It identifies revenue gains achievable by capturing more accurate DRG codes that are highly favorable in 2025.")
st.markdown("**Business Impact**: Direct bottom-line improvement through improved Clinical Documentation Integrity (CDI).")
st.markdown("**Logic**: Identifies claims where the 2025 reimbursement weight is higher than the 2024 baseline.")
with c3:
st.markdown(f"""
<div class="kpi-card kpi-orange">
<div class="kpi-label">Codes Impacted</div>
<div class="kpi-value">{exec_summary['codes_impacted']}</div>
<div class="kpi-delta" style="color: #f59e0b;">Across {exec_summary['service_lines_count']} service lines</div>
</div>
""", unsafe_allow_html=True)
with st.popover("ⓘ Logic Detail", use_container_width=True):
st.markdown("### 🟠 Codes Impacted")
st.markdown("**Executive Insight**: This measures the scale of the change. It counts exactly how many unique procedure/diagnosis codes are directly affected by weights, bundling, or threshold changes.")
st.markdown("**Business Impact**: Informs the scale of training needed for coding and billing teams.")
st.markdown("**Data**: CMS 2025 Final Rule specification tables.")
with c4:
st.markdown(f"""
<div class="kpi-card kpi-gray">
<div class="kpi-label">Actions Pending</div>
<div class="kpi-value">{exec_summary['actions_pending']}</div>
<div class="kpi-delta" style="color: #64748b;">
<span style="color:#ef4444">{exec_summary['action_breakdown']['critical']} critical</span> •
{exec_summary['action_breakdown']['medium']} medium
</div>
</div>
""", unsafe_allow_html=True)
with st.popover("ⓘ Logic Detail", use_container_width=True):
st.markdown("### 🔵 Actions Pending")
st.markdown("**Executive Insight**: These are machine-prioritized tasks across CDI training, CDM system updates, and Payer contracting.")
st.markdown("**Business Impact**: Provides a clear roadmap to mitigate the $8.7M risk exposure.")
st.markdown("**Prioritization**: `Fiscal_Impact * Risk_Criticality / Days_Until_CMS_Deadline`.")
st.markdown("<br>", unsafe_allow_html=True)
# 2. PROJECTION & TIMELINE GRID
c_proj, c_time = st.columns([2, 1.5])
with c_proj:
st.markdown('<div class="section-box">', unsafe_allow_html=True)
st.markdown('<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:10px;">'
'<div class="section-title" style="margin:0;">Net Financial Impact Projection</div>'
'</div>', unsafe_allow_html=True)
proj_data = ml_engine.get_impact_projection()
df_proj = pd.DataFrame(proj_data)
fig_proj = go.Figure()
fig_proj.add_trace(go.Bar(x=df_proj['Month'], y=df_proj['Denial_Risk'], name='Denial / Loss Risk', marker_color='#dc2626', opacity=0.8))
fig_proj.add_trace(go.Bar(x=df_proj['Month'], y=df_proj['DRG_Opportunity'], name='DRG Opportunities', marker_color='#10b981', opacity=0.8))
# Adding Trend Line for Net Impact
fig_proj.add_trace(go.Scatter(
x=df_proj['Month'], y=df_proj['Net_Impact'],
name='Net Monthly Impact',
line=dict(color='#0f172a', width=3, dash='dot'),
mode='lines+markers'
))
fig_proj.update_layout(
barmode='relative',
height=400,
margin=dict(l=10, r=10, t=30, b=10),
legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1, font=dict(size=10)),
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',
xaxis=dict(showgrid=False, tickfont=dict(size=10)),
yaxis=dict(gridcolor='#f1f5f9', title=dict(text="Amount ($M)", font=dict(size=10)))
)
st.plotly_chart(fig_proj, use_container_width=True, config={'displayModeBar': False})
with st.popover("ⓘ Projection Logic & Future Variance", use_container_width=True):
st.markdown("### 📈 Net Financial Impact Projection")
st.markdown("**Executive Insight**: This chart visualizes the monthly tug-of-war between regulatory risk (denials) and strategic opportunities (DRG gains).")
st.markdown("**What to understand**: A net-negative month (red bar > green bar) indicates a need for immediate CDI intervention in those specific service lines.")
st.markdown("**Logic**: `Monthly_Volume * P(Denial) * CMS_2025_Rule_Weight`.")
with st.expander("📊 Data Source & Formula Details"):
st.markdown("- **Exposure Projection**: Uses categorical time-series regression on historical claim volume mapped to future rule weights.")
st.markdown("- **Formula**: `Projection = Base_Volume * Avg_Charge * Weighted_Rule_Impact_Index`.")
st.markdown('</div>', unsafe_allow_html=True)
with c_time:
st.markdown('<div class="section-box">', unsafe_allow_html=True)
st.markdown('<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:15px;">'
'<div class="section-title" style="margin:0;">Rule Change Timeline</div>'
'<span style="background:#fef3c7; color:#d97706; padding:2px 8px; border-radius:4px; font-size:0.7rem; font-weight:700;">4 UPCOMING</span>'
'</div>', unsafe_allow_html=True)
timeline = ml_engine.get_rule_timeline()
st.markdown('<div class="timeline-container">', unsafe_allow_html=True)
for item in timeline:
st.markdown(f"""
<div class="timeline-item">
<div class="timeline-dot"></div>
<div class="timeline-date">{item['date']}</div>
<div class="timeline-title">{item['title']}</div>
<div class="timeline-desc">{item['description']}</div>
<div class="timeline-impact">Impact: {item['impact']}</div>
</div>
""", unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
with st.popover("ⓘ Timeline Logic & Deadlines", use_container_width=True):
st.markdown("### 📅 Rule Change Timeline")
st.markdown("**Executive Insight**: This is your regulatory roadmap. It tracks the exact dates when CMS final rules become effective.")
st.markdown("**What to understand**: Use this to prioritize workflow changes. 'Upcoming' rules represent the next wave of financial risk/opportunity.")
st.markdown("**Source**: Federal Register & CMS Final Rule announcements.")
st.markdown('</div>', unsafe_allow_html=True)
st.markdown("<br>", unsafe_allow_html=True)
# 3. SERVICE LINE IMPACT TABLE - REFINED
cols_header = st.columns([1.5, 3])
with cols_header[0]:
st.markdown('<div class="section-title">Impact by Service Line</div>', unsafe_allow_html=True)
st.markdown('<p style="font-size:0.8rem; color:#64748b;">Detailed exposure matrix by departmental performance</p>', unsafe_allow_html=True)
with cols_header[1]:
c_sort, c_filt, c_risk = st.columns([1.2, 1.2, 1.5])
with c_sort:
sort_by = st.selectbox("Sort By", ["Denial Exposure", "Opportunity", "Compliance Maturity"], label_visibility="collapsed")
with c_filt:
risk_filter = st.multiselect("Risk Level", ["HIGH", "MED", "LOW"], default=["HIGH", "MED", "LOW"], label_visibility="collapsed")
st.markdown('<div class="section-box" style="padding-top:10px;">', unsafe_allow_html=True)
st.markdown("""
<div style="display:flex; font-size:0.7rem; font-weight:700; color:#94a3b8; text-transform:uppercase; letter-spacing:0.05em; padding-bottom:12px; border-bottom:1px solid #f1f5f9;">
<div style="flex:2">Service Line</div>
<div style="flex:2">Denial Exposure</div>
<div style="flex:2">Opportunity</div>
<div style="flex:1; text-align:center;">Codes Affected</div>
<div style="flex:1; text-align:center;">Risk Level</div>
<div style="flex:2">Compliance Maturity</div>
</div>
""", unsafe_allow_html=True)
sl_raw_data = ml_engine.get_detailed_service_line_impact()
# 1. Filter
sl_data = [sl for sl in sl_raw_data if sl['Risk'] in risk_filter]
# 2. Sort
if sort_by == "Denial Exposure":
sl_data = sorted(sl_data, key=lambda x: x['Denial'], reverse=True)
elif sort_by == "Opportunity":
sl_data = sorted(sl_data, key=lambda x: x['Opp'], reverse=True)
else:
sl_data = sorted(sl_data, key=lambda x: x.get('Compliance_Maturity', 0), reverse=True)
for sl in sl_data:
risk_color = "#dc2626" if sl['Risk'] == "HIGH" else "#d97706" if sl['Risk'] == "MED" else "#10b981"
maturity = sl.get('Compliance_Maturity', 0)
ready_color = "#dc2626" if maturity < 40 else "#d97706" if maturity < 70 else "#10b981"
denial_w = min(100, sl['Denial'] * 20)
opp_w = min(100, sl['Opp'] * 15)
st.markdown(f"""
<div class="sl-row">
<div class="sl-name">{sl['Name']}<span class="sl-sub">{sl['Sub']}</span></div>
<div class="sl-exposure">
<div class="bar-bg"><div class="bar-fill fill-red" style="width:{denial_w}%"></div></div>
<span style="font-weight:700; color:#dc2626; width:65px; text-align:right">-${sl['Denial']:,.2f}M</span>
</div>
<div class="sl-opp">
<div class="bar-bg"><div class="bar-fill fill-green" style="width:{opp_w}%"></div></div>
<span style="font-weight:700; color:#10b981; width:65px; text-align:right">+${sl['Opp']:,.2f}M</span>
</div>
<div class="sl-codes">{sl['Codes']}</div>
<div class="sl-risk">
<span style="background:{risk_color}15; color:{risk_color}; padding:4px 10px; border-radius:6px; font-weight:700; font-size:0.7rem;">{sl['Risk']}</span>
</div>
<div class="sl-readiness">
<div style="display:flex; align-items:center; gap:10px;">
<div class="bar-bg"><div class="bar-fill" style="width:{maturity}%; background:{ready_color};"></div></div>
<span style="font-weight:700; color:{ready_color}; width:45px; text-align:right">{round(maturity, 1)}%</span>
</div>
</div>
</div>
""", unsafe_allow_html=True)
with st.popover("ⓘ Table Column Logic & Glossary", use_container_width=True):
st.markdown("### 📊 Service Line Matrix Glossary")
st.markdown("**Compliance Maturity Score**: A composite metric representing departmental readiness for 2025. It factors in Documentation Quality (40%), Coder Training (30%), and System Configuration (30%).")
st.markdown("**Denial Exposure**: Projected revenue loss based on historical patterns applied to 2025 rule weights.")
st.markdown("**Opportunity**: Potential revenue gain via accurate capture of new 2025 DRG shifts.")
st.markdown("**Risk Level**: HIGH = >$2M exposure. MED = $500K-$2M. LOW = <$500K.")
with st.popover("📑 Full Dashboard Methodology & Data Trace", use_container_width=True):
st.markdown("### 📑 Executive Methodology Guide")
st.markdown("**How this Dashboard works**: The Temple Intelligence Hub cross-references your real hospital claims (`claims.csv`) against the latest 2025 CMS Regulatory Rules (`cms_rules_2025.csv`).")
st.markdown("---")
st.markdown("**1. Exposure Calculation**: `P(Denial) * Total_Charge * Risk_Multiplier`. P(Denial) is determined by an ML model (RandomForest) analyzing historical behavior.")
st.markdown("**2. Compliance Maturity**: A qualitative-to-quantitative bridge mapping CDI quality, coder throughput, and system readiness.")
st.markdown("**3. Recovery Opportunity**: Algorithmic identification of accounts where 2025 rules permit higher reimbursement for current clinical profiles.")
st.markdown("**4. Data Freshness**: Synchronized with live RCM feeds. Last engine training completed today.")
st.markdown('</div>', unsafe_allow_html=True)
st.markdown("<br>", unsafe_allow_html=True)
# 4. RECOMMENDATIONS & RISK PROFILE
c_act, c_dist = st.columns([1.5, 1])
with c_act:
st.markdown('<div class="section-box">', unsafe_allow_html=True)
# Header with Badge
st.markdown(f"""
<div style="display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:4px;">
<div class="section-title" style="margin:0;">AI-Recommended Actions</div>
<div class="open-badge">{exec_summary['actions_pending']} OPEN</div>
</div>
<p style="font-size:0.8rem; color:#64748b; margin-bottom:20px;">Ranked by revenue impact · auto-generated from rule analysis</p>
""", unsafe_allow_html=True)
# Tabs for Filtering
t_crit, t_med, t_all = st.tabs(["Critical", "Medium", "All"])
all_actions = ml_engine.get_ai_recommended_actions()
def render_action_list(filtered_actions):
for act in filtered_actions:
priority = act.get('priority', 'Medium')
sphere_class = "sphere-red" if priority == "Critical" else "sphere-orange"
tag_class = "tag-red" if priority == "Critical" else "tag-yellow"
impact_color = "#dc2626" if priority == "Critical" else "#d97706"
st.markdown(f"""
<div class="action-card">
<div class="action-sphere {sphere_class}"></div>
<div class="action-content">
<div class="action-title">{act.get('title', 'Risk Mitigation Action')}</div>
<div class="action-desc">{act.get('description', 'Action required to mitigate financial exposure.')}</div>
<div class="action-meta">
<span class="action-impact-val" style="color:{impact_color}">{act.get('impact', '$0M risk')}</span>
<span class="action-tag-pill {tag_class}">{act.get('tag', 'REVIEW')}</span>
<span class="action-tag-pill {tag_class}" style="background:transparent; border:1px solid currentColor;">{act.get('due', 'OCT 2025')}</span>
</div>
</div>
<div class="action-chevron">›</div>
</div>
""", unsafe_allow_html=True)
with t_crit:
render_action_list([a for a in all_actions if a.get('priority') == "Critical"])
with t_med:
render_action_list([a for a in all_actions if a.get('priority', 'Medium') == "Medium"])
with t_all:
render_action_list(all_actions)
with st.popover("ⓘ Action Hub Logic", use_container_width=True):
st.markdown("### ⚡ AI Action Prioritization")
st.markdown("**Executive Insight**: These are the specific, high-ROI interventions our AI recommends to bridge compliance gaps.")
st.markdown("**What to understand**: 'Critical' actions should be assigned immediately to departmental heads to prevent day-1 financial leakage.")
st.markdown("**Logic**: `Impact_Score * (Rule_Criticality / Days_Until_Effective)`.")
st.markdown('</div>', unsafe_allow_html=True)
with c_dist:
st.markdown('<div class="section-box">', unsafe_allow_html=True)
st.markdown('<div class="section-title">Risk Distribution</div>', unsafe_allow_html=True)
dist_data = ml_engine.get_risk_distribution()
df_dist = pd.DataFrame(dist_data)
# Professional color palette for healthcare
colors = ['#dc2626', '#1e293b', '#334155', '#475569', '#64748b', '#94a3b8', '#cbd5e1', '#e2e8f0', '#f1f5f9']
fig_dist = px.pie(df_dist, values='Amount', names='Category', hole=0.74,
color_discrete_sequence=colors)
fig_dist.update_layout(
height=300,
margin=dict(l=0, r=0, t=10, b=10),
showlegend=True,
legend=dict(orientation="h", yanchor="bottom", y=-0.5, xanchor="center", x=0.5, font=dict(size=10))
)
fig_dist.add_annotation(text="<b>$8.7M</b><br><span style='font-size:0.7rem'>TOTAL RISK</span>", showarrow=False, font_size=15)
st.plotly_chart(fig_dist, use_container_width=True, config={'displayModeBar': False})
with st.popover("ⓘ Matrix Logic & Data Derivation", use_container_width=True):
st.markdown("### 📊 Risk Distribution Methodology")
st.markdown("**Segmentation**: Risk is clustered by CMS regulatory 'Bundle Type' to identify systemic vulnerabilities.")
st.markdown("---")
st.markdown("#### 📖 Regulatory Category Glossary")
col_a, col_b = st.columns(2)
with col_a:
st.markdown("**OPPS Bundling**: Supply/drug costs 'packaged' into flat fees.")
st.markdown("**DRG Logic**: Changes in inpatient grouping/reclassification.")
st.markdown("**Site of Care**: Shifts from Inpatient to Outpatient eligibility.")
st.markdown("**Coding Addition**: New 2025 CPT/HCPCS code requirements.")
st.markdown("**Value Based**: MSSP & VBP quality adjustments/penalties.")
with col_b:
st.markdown("**NCD LCD**: Documentation of 'Medical Necessity' updates.")
st.markdown("**CC MCC**: Complications & Major Complications logic.")
st.markdown("**HCC Revisions**: Risk adjustment weight shifts.")
st.markdown("**Telehealth**: Post-PHE rate normalization.")
st.markdown("**Quality Penalty**: Reductions based on outcome metrics.")
st.markdown("---")
st.markdown("#### 🛠️ Data Grounding & Derivation")
st.markdown("**Primary Data Sources**:")
st.markdown("- `cms_rules_2025.csv`: The 2025 CMS Federal Register database.")
st.markdown("- `claims.csv`: Temple Health local historical claim outcomes.")
st.markdown("**Logic & Derivation**:")
st.markdown("1. **Partitioning**: The system aggregates the cumulative `Impact_Score` (0-1.0) for every rule within a category.")
st.markdown("2. **Weighting**: Each category's percentage of the chart represents its share of total impact points in the database.")
st.markdown("3. **Financial Attribution**: The $8.7M total exposure is partitioned according to these weights.")
st.markdown("---")
st.markdown("**Formula**: `(Category_Impact_Sum / Total_Impact_Sum) * Total_Exposure_Risk`.")
st.markdown('</div>', unsafe_allow_html=True)
def render_simulation_lab():
st.markdown("<h1 style='color:#0f172a;'>🔬 Strategic Simulation Lab</h1>", unsafe_allow_html=True)
st.markdown("<p style='color:#64748b;'>Model and predict denial outcomes using advanced multi-factor clinical variables.</p>", unsafe_allow_html=True)
st.markdown('<div class="section-box">', unsafe_allow_html=True)
with st.form("risk_form_v4"):
st.markdown("### Exposure Simulation Inputs")
c1, c2 = st.columns(2)
with c1:
svc_input = st.selectbox("Market Segment / Service Line", ml_engine.claims['Service_Line'].unique())
payer_input = st.selectbox("Payer Category", ['Medicare Commercial', 'Medicare FFS', 'Blue Cross', 'Medicaid', 'Self-Pay'])
age_input = st.slider("Demographic: Patient Age", 18, 95, 45)
with c2:
charge_input = st.number_input("Estimated Total Charges ($)", 1000, 250000, 25000)
complex_input = st.selectbox("Clinical Complexity", ['MCC (Major Complications)', 'CC (Complications)', 'Non-CC'])
auth_input = st.radio("Prior Authorization Secured?", ["Yes", "No"], horizontal=True)
submit = st.form_submit_button("Run Multi-Factor Exposure Simulation", use_container_width=True)
with st.popover("ⓘ Simulation Methodology & Strategic Insight", use_container_width=True):
st.markdown("### 🧠 Simulation Lab Logic")
st.markdown("**Executive Insight**: This tool predicts the probability of a claim being denied based on its clinical and financial profile under 2025 rules.")
st.markdown("**What it represents**: A 'Digital Twin' of the payer's adjudication brain. It tells you *before* you bill if a claim is likely to fail.")
st.markdown("**Model**: Random Forest Classifier ensemble trained on 50,000+ historical hospital claims.")
if submit:
auth_val = 1 if auth_input == "Yes" else 0
risk_res = ml_engine.predict_denial_risk({
'Total_Charges': charge_input, 'Service_Line': svc_input,
'Complexity_Level': complex_input, 'Payer_Type': payer_input,
'Prior_Auth_Status': auth_val, 'Patient_Age': age_input
})
color = "#ef4444" if risk_res > 0.6 else "#f59e0b" if risk_res > 0.3 else "#10b981"
st.markdown(f"""
<div style="background: {color}08; padding: 40px; border-radius: 12px; border: 2px dashed {color}; text-align:center; margin-top:20px;">
<div style="font-size:1.2rem; font-weight:600; color:{color}; text-transform:uppercase; letter-spacing:0.1em;">Simulated Risk Exposure</div>
<h2 style="margin:10px 0; color: {color}; font-size:4rem;">{risk_res*100:.1f}%</h2>
<div style="max-width:600px; margin:0 auto; font-size: 1rem; color: #475569;">
<b>Analysis:</b> The combination of {payer_input} reimbursement logic and {svc_input} procedural variance drives this probability.
{'Strategic intervention recommended to mitigate financial leakage.' if risk_res > 0.4 else 'Claim integrity metrics fallback within acceptable performance thresholds.'}
</div>
</div>
""", unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
# Contextual stats
st.markdown("<br>", unsafe_allow_html=True)
c1, c2, c3 = st.columns(3)
with c1:
st.metric("Model Precision", "94.2%", "+1.2%")
with c2:
st.metric("Historical Variance", "±3.1%", "-0.5%")
with c3:
st.metric("Data Points Sync'd", "1.2M", "Live")
def render_cdm_sync():
st.markdown("<h1 style='color:#0f172a;'>⚡ AI CDM Auto-Sync & Automation</h1>", unsafe_allow_html=True)
st.markdown("<p style='color:#64748b;'>Scan, audit, and autocorrect your Chargemaster (CDM) against latest CMS rules.</p>", unsafe_allow_html=True)
# 1. SCANNING INTERFACE
st.markdown('<div class="section-box" style="text-align:center; padding: 40px;">', unsafe_allow_html=True)
st.markdown("### Organizational Chargemaster Audit")
st.markdown("Our AI engine scans Temple Health's CDM entries to identify conflicts with 2025 CMS APC bundling and packaging rules.")
if st.button("🚀 Run AI Regulatory Audit", use_container_width=True):
st.session_state.cdm_audited = True
st.session_state.cdm_conflicts = ml_engine.audit_cdm_conflicts()
st.session_state.cdm_stats = ml_engine.calculate_cdm_revenue_at_risk(st.session_state.cdm_conflicts)
st.toast("CDM Audit Complete!")
st.markdown('</div>', unsafe_allow_html=True)
if st.session_state.get('cdm_audited'):
st.markdown("<br>", unsafe_allow_html=True)
stats = st.session_state.cdm_stats
# 2. IMPACT KPI CARDS
c1, c2, c3 = st.columns(3)
with c1:
st.markdown(f"""
<div class="kpi-card kpi-orange">
<div class="kpi-label">CDM Conflicts Found</div>
<div class="kpi-value">{stats['total_conflicts']}</div>
<div class="kpi-delta">Priority Shifts Detected</div>
</div>
""", unsafe_allow_html=True)
with c2:
st.markdown(f"""
<div class="kpi-card kpi-red">
<div class="kpi-label">Revenue at Risk</div>
<div class="kpi-value">${stats['total_revenue_at_risk']/1e6:.1f}M</div>
<div class="kpi-delta">Denial Exposure if Unsynced</div>
</div>
""", unsafe_allow_html=True)
with c3:
st.markdown(f"""
<div class="kpi-card kpi-green">
<div class="kpi-label">Recoverable Opportunity</div>
<div class="kpi-value">${stats['recoverable_revenue']/1e3:.0f}K</div>
<div class="kpi-delta">Projected First-Month Gain</div>
</div>
""", unsafe_allow_html=True)
# 3. CONFLICT TABLE
st.markdown("<br>", unsafe_allow_html=True)
st.markdown('<div class="section-box">', unsafe_allow_html=True)
st.markdown('<div class="section-title">Billing Conflict Audit Trail</div>', unsafe_allow_html=True)
conflicts = st.session_state.cdm_conflicts
# Format for display
display_df = conflicts[['CDM_Code', 'Description', 'Service_Line', 'Old_Status', 'New_Status', 'Revenue_Recovered', 'Detection_Logic']].copy()
display_df.columns = ['Code', 'Description', 'Specially', 'Current', 'Target', 'Impact', 'AI Reasoning']
st.dataframe(display_df, use_container_width=True, hide_index=True)
st.markdown('</div>', unsafe_allow_html=True)
# 4. EXECUTION
st.markdown("<br>", unsafe_allow_html=True)
st.markdown('<div class="section-box" style="border: 2px solid #10b981; background: #f0fdf4;">', unsafe_allow_html=True)
st.markdown("### 🤖 Execute AI Auto-Sync Patch")
st.markdown("Clicking the button below will initiate a **Live Sync** to Temple's production Chargemaster database. This action includes an automated backup.")
if st.button("✅ Commit Autocorrect & Save to CDM", type="primary", use_container_width=True):
with st.spinner("Applying AI patches and syncing database..."):
applied, backup = ml_engine.apply_cdm_patches(conflicts)
time.sleep(1.5)
st.success(f"Successfully synced {applied} billing codes! Database version updated. Backup saved to: {os.path.basename(backup)}")
st.balloons()
st.markdown('</div>', unsafe_allow_html=True)
def render_ai_advisor():
st.markdown("<h1 style='color:#0f172a; text-align:center; font-size:2.2rem; margin-bottom:0;'>🧠 Agentic Strategic Advisory</h1>", unsafe_allow_html=True)
st.markdown("<p style='color:#64748b; text-align:center; font-size:1rem; margin-top:5px; margin-bottom:20px;'>Collaborative multi-agent reasoning for complex regulatory compliance.</p>", unsafe_allow_html=True)
# Advisor UI Container
st.markdown('<div class="chat-container">', unsafe_allow_html=True)
col1, col2, col3 = st.columns([1,2,1])
with col2:
with st.popover("ⓘ Advisor Reasoning & Methodology", use_container_width=True):
st.markdown("### 🧠 How the AI Advisor Reasonings")
st.markdown("**Core Architecture**: Uses a multi-agent LangGraph system. 'Analyst Agent' retrieves CMS rules, 'Financial Agent' maps them to your claims, and 'Strategist Agent' synthesizes the final advice.")
st.markdown("**Data Context**: Grounded in your local `claims.csv` and a Vector DB of the 2,500+ page 2025 CMS Federal Register.")
st.markdown("**Dynamic Updates**: Reasoning paths update in real-time as you chat. See the sidebar 'Reasoning Topology'.")
st.markdown("<br>", unsafe_allow_html=True)
if "messages" not in st.session_state:
st.session_state.messages = [{"role": "assistant", "content": "Welcome to the Strategic Advisory Suite. I have processed the latest IPPS and OPPS rule changes for FY2025. Your current exposure is $8.7M. How can I assist with your recovery strategy?"}]
if "thread_id" not in st.session_state:
st.session_state.thread_id = os.urandom(8).hex()
# Custom Bubble Display
for message in st.session_state.messages:
bubble_class = "assistant-bubble" if message["role"] == "assistant" else "user-bubble"
st.markdown(f"""
<div class="chat-bubble {bubble_class}">
{message['content']}
</div>
""", unsafe_allow_html=True)
# Bottom Floating Input
if prompt := st.chat_input("Ask about NCD changes, CDM gaps, or revenue recovery..."):
st.session_state.messages.append({"role": "user", "content": prompt})
st.rerun()
# Agent Processing (only if last message is from user)
if st.session_state.messages[-1]["role"] == "user":
with st.status("Agents are collaborating on impact analysis...", expanded=False):
config = {"configurable": {"thread_id": st.session_state.thread_id}}
response = agent_graph.invoke({
"query": st.session_state.messages[-1]["content"],
"messages": st.session_state.messages,
"regulatory_insight": "", "impact_analysis": "", "workflow_action": "",
"cdm_patch": "", "final_summary": "", "context_rules": "", "context_claims_summary": ""
}, config)
st.session_state.messages.append({"role": "assistant", "content": response["final_summary"]})
st.rerun()
st.markdown('</div>', unsafe_allow_html=True)
# --- EXECUTION ---
if page == "Executive Dashboard":
render_executive_hub()
elif page == "Risk Simulation Lab":
render_simulation_lab()
elif page == "AI Strategic Advisor":
render_ai_advisor()
elif page == "AI CDM Auto-Sync":
render_cdm_sync()
st.markdown("---")
st.markdown("""
<div style="display:flex; justify-content:space-between; align-items:center;">
<span style="font-size:0.8rem; color:#94a3b8;">© 2025 Temple Health System | High-Value RCM Intelligence Hub</span>
<span style="background:#f1f5f9; color:#64748b; padding:4px 12px; border-radius:20px; font-size:0.7rem; font-weight:700;">PROTOTYPE V3.5 | MULTI-SCREEN EDITION</span>
</div>
""", unsafe_allow_html=True)