/ dashboard / pages / 4_✅_Compliance.py
4_✅_Compliance.py
  1  """
  2  333 Method Analytics Dashboard - Compliance Page
  3  """
  4  
  5  import logging
  6  import streamlit as st
  7  from streamlit_autorefresh import st_autorefresh
  8  from dashboard import config
  9  from dashboard.utils import database
 10  from dashboard.components import metrics
 11  from dashboard.utils.logging_config import configure_app_logging, log_exception
 12  
 13  # Configure logging for this page
 14  logger = configure_app_logging("dashboard.compliance")
 15  
 16  # Page configuration
 17  st.set_page_config(page_title="Compliance", page_icon="✅", layout="wide")
 18  
 19  # Auto-refresh
 20  st_autorefresh(interval=config.REFRESH_INTERVAL * 1000, key="compliance_refresh")
 21  
 22  st.title("⚖️ Compliance & Rate Limits")
 23  
 24  # === Key Metrics ===
 25  try:
 26      optout_stats = database.get_optout_stats()
 27      platform_health = database.get_platform_health()
 28  
 29      email_optouts = (
 30          optout_stats["total_email_optouts"].iloc[0] if not optout_stats.empty else 0
 31      )
 32      sms_optouts = (
 33          optout_stats["total_sms_optouts"].iloc[0] if not optout_stats.empty else 0
 34      )
 35  
 36      metrics.display_metric_grid(
 37          [
 38              {"label": "Email Opt-outs", "value": f"{email_optouts:,}"},
 39              {"label": "SMS Opt-outs", "value": f"{sms_optouts:,}"},
 40              {
 41                  "label": "Total Opt-outs",
 42                  "value": f"{email_optouts + sms_optouts:,}",
 43              },
 44          ]
 45      )
 46  
 47      st.markdown("---")
 48  
 49      # === Platform Health & Rate Limits ===
 50      st.subheader("📊 Platform Health & Rate Limits")
 51  
 52      # Resend (Email) Health
 53      st.write("**📧 Resend.com Health**")
 54  
 55      if not platform_health.empty:
 56          email_data = platform_health[platform_health["contact_method"] == "email"]
 57  
 58          if not email_data.empty:
 59              bounce_rate = email_data["bounce_rate"].iloc[0]
 60              delivery_rate = email_data["delivery_rate"].iloc[0]
 61              total_sent = email_data["total_sent"].iloc[0]
 62              bounced = email_data["bounced"].iloc[0]
 63  
 64              # Alert logic
 65              if bounce_rate > config.RESEND_BOUNCE_CRITICAL:
 66                  st.error(
 67                      f"🚨 CRITICAL: Bounce rate is {bounce_rate}% (>{config.RESEND_BOUNCE_CRITICAL}%)"
 68                  )
 69                  st.warning(
 70                      "**Recommendation:** Immediate list cleaning required. High bounce rates damage sender reputation."
 71                  )
 72              elif bounce_rate > config.RESEND_BOUNCE_ALERT:
 73                  st.warning(
 74                      f"⚠️ ALERT: Bounce rate is {bounce_rate}% (>{config.RESEND_BOUNCE_ALERT}%)"
 75                  )
 76                  st.info(
 77                      "**Recommendation:** Consider list cleaning and removing invalid addresses."
 78                  )
 79              else:
 80                  st.success(f"✅ Bounce rate is healthy: {bounce_rate}%")
 81  
 82              # Email metrics
 83              email_cols = st.columns(4)
 84              with email_cols[0]:
 85                  st.metric("Total Sent", f"{total_sent:,}")
 86              with email_cols[1]:
 87                  st.metric("Delivery Rate", f"{delivery_rate}%")
 88              with email_cols[2]:
 89                  st.metric("Bounce Rate", f"{bounce_rate}%")
 90              with email_cols[3]:
 91                  st.metric("Bounced", f"{bounced:,}")
 92  
 93              # Note: Complaint rate would come from email tracking
 94              st.info("💡 Complaint rate tracking: Coming soon via Resend webhooks")
 95          else:
 96              st.info("No email outreach data available")
 97      else:
 98          st.info("No platform health data available")
 99  
100      st.markdown("---")
101  
102      # Twilio (SMS) Health
103      st.write("**📱 Twilio Health**")
104  
105      if not platform_health.empty:
106          sms_data = platform_health[platform_health["contact_method"] == "sms"]
107  
108          if not sms_data.empty:
109              sms_delivery_rate = sms_data["delivery_rate"].iloc[0]
110              sms_bounce_rate = sms_data["bounce_rate"].iloc[0]
111              sms_total_sent = sms_data["total_sent"].iloc[0]
112  
113              if sms_delivery_rate < 95:
114                  st.warning(f"⚠️ SMS delivery rate is {sms_delivery_rate}% (<95%)")
115                  st.info(
116                      "**Recommendation:** Review message templates for carrier filtering issues."
117                  )
118              else:
119                  st.success(f"✅ SMS delivery rate is healthy: {sms_delivery_rate}%")
120  
121              sms_cols = st.columns(3)
122              with sms_cols[0]:
123                  st.metric("Total Sent", f"{sms_total_sent:,}")
124              with sms_cols[1]:
125                  st.metric("Delivery Rate", f"{sms_delivery_rate}%")
126              with sms_cols[2]:
127                  st.metric("Failed Rate", f"{sms_bounce_rate}%")
128          else:
129              st.info("No SMS outreach data available")
130      else:
131          st.info("No SMS data available")
132  
133      st.markdown("---")
134  
135      # Other Platform Limits
136      st.subheader("🔧 Other Platform Limits")
137  
138      limits_cols = st.columns(3)
139  
140      with limits_cols[0]:
141          st.write("**ZenRows API**")
142          st.info("Daily API calls: Coming soon")
143          st.caption("Plan limit tracking TBD")
144  
145      with limits_cols[1]:
146          st.write("**OpenRouter**")
147          st.info("Token usage: Coming soon")
148          st.caption("Budget tracking TBD")
149  
150      with limits_cols[2]:
151          st.write("**Playwright**")
152          st.info("Concurrent instances: Coming soon")
153          st.caption("Resource monitoring TBD")
154  
155      st.markdown("---")
156  
157      # === Compliance Checklist ===
158      st.subheader("✅ Compliance Checklist")
159  
160      checklist_cols = st.columns(2)
161  
162      with checklist_cols[0]:
163          st.write("**CAN-SPAM (Email)**")
164          st.checkbox("✅ Unsubscribe link in all emails", value=True, disabled=True)
165          st.checkbox("✅ Sender identification present", value=True, disabled=True)
166          st.checkbox("✅ Physical address included", value=True, disabled=True)
167          st.checkbox("✅ Honor opt-outs within 10 days", value=True, disabled=True)
168  
169      with checklist_cols[1]:
170          st.write("**TCPA (SMS)**")
171          st.checkbox("✅ Opt-out instructions (STOP)", value=True, disabled=True)
172          st.checkbox("✅ Business hours only (8am-9pm)", value=True, disabled=True)
173          st.checkbox("✅ Sender identification", value=True, disabled=True)
174          st.checkbox("✅ E.164 phone format", value=True, disabled=True)
175  
176      st.markdown("---")
177  
178      # === Platform Health Table ===
179      st.subheader("Platform Summary")
180      if not platform_health.empty:
181          st.dataframe(
182              platform_health[
183                  [
184                      "contact_method",
185                      "total_sent",
186                      "delivered",
187                      "delivery_rate",
188                      "bounced",
189                      "bounce_rate",
190                  ]
191              ],
192              use_container_width=True,
193              hide_index=True,
194              column_config={
195                  "delivery_rate": st.column_config.NumberColumn(
196                      "Delivery %", format="%.2f%%"
197                  ),
198                  "bounce_rate": st.column_config.NumberColumn(
199                      "Bounce %", format="%.2f%%"
200                  ),
201              },
202          )
203      else:
204          st.info("No platform data available")
205  
206  except Exception as e:
207      log_exception(logger, f"Error loading compliance data: {e}")
208      st.error(f"Error loading compliance data: {e}")