walaa2022 commited on
Commit
623e602
·
verified ·
1 Parent(s): fb6f46e

Upload 6 files

Browse files
pages/app.py ADDED
@@ -0,0 +1,439 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ import plotly.express as px
5
+ import plotly.graph_objects as go
6
+ import os
7
+ from datetime import datetime, timedelta, date
8
+ import time
9
+ import json
10
+ import google.generativeai as genai
11
+ from google.generativeai.types import HarmCategory, HarmBlockThreshold
12
+
13
+ # Initialize page configuration
14
+ st.set_page_config(
15
+ page_title="StartupFinancePilot",
16
+ page_icon="💰",
17
+ layout="wide",
18
+ initial_sidebar_state="expanded"
19
+ )
20
+
21
+ # Custom CSS
22
+ st.markdown("""
23
+ <style>
24
+ .main-header {
25
+ font-size: 2.5rem;
26
+ color: #0066cc;
27
+ margin-bottom: 0.5rem;
28
+ }
29
+ .sub-header {
30
+ font-size: 1.5rem;
31
+ color: #5c5c5c;
32
+ margin-bottom: 1.5rem;
33
+ }
34
+ .metric-card {
35
+ background-color: #f8f9fa;
36
+ border-radius: 10px;
37
+ padding: 20px;
38
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
39
+ }
40
+ .metric-label {
41
+ font-size: 1rem;
42
+ color: #5c5c5c;
43
+ }
44
+ .metric-value {
45
+ font-size: 1.8rem;
46
+ color: #0066cc;
47
+ font-weight: bold;
48
+ }
49
+ .good-metric {
50
+ color: #28a745;
51
+ }
52
+ .warning-metric {
53
+ color: #ffc107;
54
+ }
55
+ .danger-metric {
56
+ color: #dc3545;
57
+ }
58
+ .advisor-card {
59
+ background-color: #f0f7ff;
60
+ border-radius: 10px;
61
+ padding: 20px;
62
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
63
+ margin-bottom: 20px;
64
+ }
65
+ .advice-text {
66
+ font-size: 1.1rem;
67
+ line-height: 1.6;
68
+ color: #333;
69
+ }
70
+ .insight-card {
71
+ background-color: #f0f8ff;
72
+ border-left: 4px solid #0066cc;
73
+ padding: 15px;
74
+ margin-bottom: 15px;
75
+ border-radius: 4px;
76
+ }
77
+ .ai-badge {
78
+ background-color: #0066cc;
79
+ color: white;
80
+ padding: 3px 10px;
81
+ border-radius: 10px;
82
+ font-size: 0.8rem;
83
+ margin-bottom: 10px;
84
+ display: inline-block;
85
+ }
86
+ .booking-card {
87
+ background-color: white;
88
+ border-radius: 10px;
89
+ padding: 20px;
90
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
91
+ margin-bottom: 20px;
92
+ }
93
+ .session-type {
94
+ font-size: 1.2rem;
95
+ font-weight: bold;
96
+ color: #0066cc;
97
+ }
98
+ .session-duration {
99
+ color: #5c5c5c;
100
+ font-size: 0.9rem;
101
+ }
102
+ .session-price {
103
+ font-size: 1.1rem;
104
+ font-weight: bold;
105
+ color: #28a745;
106
+ }
107
+ </style>
108
+ """, unsafe_allow_html=True)
109
+
110
+ # Constants
111
+ DEFAULT_GROWTH_RATE = 0.08 # 8% monthly growth
112
+ DEFAULT_BURN_RATE = 85000 # $85,000 monthly burn
113
+ ENGINEER_SALARY = 10000 # $10,000 monthly cost per engineer ($120K/year)
114
+ DEFAULT_MARKETING_BUDGET = 10000 # $10,000 monthly marketing budget
115
+
116
+ # Initialize session state variables
117
+ if 'booked_sessions' not in st.session_state:
118
+ st.session_state.booked_sessions = []
119
+ if 'chat_history' not in st.session_state:
120
+ st.session_state.chat_history = []
121
+ if 'audio_response' not in st.session_state:
122
+ st.session_state.audio_response = None
123
+ if 'insights_cache' not in st.session_state:
124
+ st.session_state.insights_cache = {}
125
+ if 'gemini_model' not in st.session_state:
126
+ st.session_state.gemini_model = None
127
+
128
+ # Sample data
129
+ @st.cache_data
130
+ def load_sample_data():
131
+ # TechHealth AI data
132
+ startup_data = {
133
+ "name": "TechHealth AI",
134
+ "stage": "Seed",
135
+ "founded": "18 months ago",
136
+ "employees": 12,
137
+ "last_funding": "$1.2M seed round 10 months ago",
138
+ "cash": 320000,
139
+ "burn_rate": 85000,
140
+ "revenue": 15000,
141
+ "growth_rate": 0.08
142
+ }
143
+
144
+ # Cash flow history
145
+ cash_flow_data = {
146
+ "Month": [f"Month {i}" for i in range(1, 11)],
147
+ "Revenue": [8000, 8500, 9200, 10000, 10800, 11700, 12600, 13600, 14700, 15800],
148
+ "Payroll": [60000, 60000, 62000, 62000, 65000, 65000, 70000, 70000, 75000, 75000],
149
+ "Marketing": [8000, 9000, 10000, 12000, 15000, 18000, 15000, 12000, 10000, 8000],
150
+ "Office": [5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000],
151
+ "Software": [3000, 3200, 3500, 3800, 4000, 4200, 4500, 4800, 5000, 5200],
152
+ "Travel": [2000, 1800, 2500, 3000, 4000, 4500, 3500, 3000, 2500, 2000],
153
+ "Legal": [1500, 1000, 800, 1200, 800, 2000, 1500, 1000, 3000, 1200],
154
+ "Misc": [1000, 1200, 1300, 1500, 1700, 1800, 2000, 2200, 2500, 2800]
155
+ }
156
+
157
+ # Add calculated fields
158
+ df = pd.DataFrame(cash_flow_data)
159
+ df["Total_Expenses"] = df[["Payroll", "Marketing", "Office", "Software", "Travel", "Legal", "Misc"]].sum(axis=1)
160
+ df["Net_Burn"] = df["Total_Expenses"] - df["Revenue"]
161
+
162
+ # Transaction data
163
+ transactions = pd.DataFrame([
164
+ {"Date": "2023-11-05", "Category": "Travel", "Vendor": "Caribbean Cruises", "Amount": 8500, "Description": "Team Retreat Planning", "Flag": "Suspicious"},
165
+ {"Date": "2023-11-12", "Category": "Marketing", "Vendor": "LuxuryGifts Inc", "Amount": 4200, "Description": "Client Appreciation", "Flag": "Suspicious"},
166
+ {"Date": "2023-11-22", "Category": "Office", "Vendor": "Premium Furniture", "Amount": 12000, "Description": "Office Upgrades", "Flag": "Suspicious"},
167
+ {"Date": "2023-11-28", "Category": "Consulting", "Vendor": "Strategic Vision LLC", "Amount": 7500, "Description": "Strategy Consulting", "Flag": "Suspicious"},
168
+ {"Date": "2023-12-05", "Category": "Software", "Vendor": "Personal Apple Store", "Amount": 3200, "Description": "Development Tools", "Flag": "Suspicious"},
169
+ {"Date": "2023-12-12", "Category": "Legal", "Vendor": "Anderson Brothers", "Amount": 5800, "Description": "Legal Services", "Flag": "Normal"},
170
+ {"Date": "2023-12-20", "Category": "Payroll", "Vendor": "November Payroll", "Amount": 75000, "Description": "Monthly Payroll", "Flag": "Normal"},
171
+ {"Date": "2023-12-22", "Category": "Marketing", "Vendor": "Google Ads", "Amount": 8000, "Description": "Ad Campaign", "Flag": "Normal"},
172
+ {"Date": "2023-12-25", "Category": "Office", "Vendor": "WeWork", "Amount": 5000, "Description": "Monthly Rent", "Flag": "Normal"},
173
+ {"Date": "2023-12-28", "Category": "Software", "Vendor": "AWS", "Amount": 5200, "Description": "Cloud Services", "Flag": "Normal"},
174
+ {"Date": "2024-01-05", "Category": "Travel", "Vendor": "Delta Airlines", "Amount": 1200, "Description": "Client Meeting Travel", "Flag": "Normal"},
175
+ {"Date": "2024-01-10", "Category": "Marketing", "Vendor": "Facebook Ads", "Amount": 4500, "Description": "Social Media Campaign", "Flag": "Normal"},
176
+ {"Date": "2024-01-15", "Category": "Software", "Vendor": "Atlassian", "Amount": 2800, "Description": "Development Tools", "Flag": "Normal"},
177
+ {"Date": "2024-01-20", "Category": "Payroll", "Vendor": "January Payroll", "Amount": 75000, "Description": "Monthly Payroll", "Flag": "Normal"},
178
+ {"Date": "2024-01-25", "Category": "Office", "Vendor": "WeWork", "Amount": 5000, "Description": "Monthly Rent", "Flag": "Normal"}
179
+ ])
180
+
181
+ return startup_data, df, transactions
182
+
183
+ # Setup AI Services
184
+ def setup_genai():
185
+ """Initialize and configure Google's Generative AI and list available models"""
186
+ try:
187
+ if 'GOOGLE_API_KEY' in st.secrets:
188
+ genai.configure(api_key=st.secrets['GOOGLE_API_KEY'])
189
+
190
+ # Get available models and select one for text generation
191
+ models = genai.list_models()
192
+ text_models = [m.name for m in models if 'generateContent' in m.supported_generation_methods]
193
+
194
+ if text_models:
195
+ # Use first available text generation model
196
+ model_name = text_models[0]
197
+ st.session_state.gemini_model = model_name
198
+ return True
199
+ else:
200
+ st.warning("No appropriate generative AI models available")
201
+ # Use a fallback model name for demonstration
202
+ st.session_state.gemini_model = "gemini-1.5-pro"
203
+ return False
204
+ else:
205
+ st.warning("Google API key not found in secrets. Using simulated AI responses.")
206
+ st.session_state.gemini_model = "gemini-1.5-pro"
207
+ return False
208
+ except Exception as e:
209
+ st.warning(f"Failed to initialize Gemini: {e}. Using simulated AI responses.")
210
+ st.session_state.gemini_model = "gemini-1.5-pro"
211
+ return False
212
+
213
+ def generate_ai_response(prompt, simulate=False):
214
+ """Generate response from Gemini or simulate one if the API is unavailable"""
215
+ if simulate:
216
+ # Simulate AI response with predefined text based on keywords in prompt
217
+ time.sleep(1) # Simulate processing time
218
+
219
+ if "runway" in prompt.lower():
220
+ return "Based on your current spend rate of $85K/month and revenue growth of 8%, your runway is approximately 3.8 months. I recommend reducing non-essential expenses to extend runway to at least 6 months before your next fundraising round."
221
+ elif "hire" in prompt.lower() or "hiring" in prompt.lower():
222
+ return "Adding new hires at this stage would reduce your runway significantly. Consider contracting talent first or postponing hiring until after securing additional funding. Each new engineer costs $10K/month, reducing runway by approximately 3 weeks per hire."
223
+ elif "marketing" in prompt.lower():
224
+ return "Your current CAC to LTV ratio doesn't justify increasing marketing spend. Focus on optimizing current channels and improving conversion rates. Once unit economics improve, gradually increase marketing budget by no more than 20% per month."
225
+ elif "fundraising" in prompt.lower() or "investor" in prompt.lower():
226
+ return "With less than 4 months of runway, you should begin fundraising preparations immediately. Focus on demonstrating product-market fit and improving key metrics like MRR growth, user retention, and unit economics before approaching investors."
227
+ elif "suspicious" in prompt.lower() or "transaction" in prompt.lower():
228
+ return "I've identified several concerning transactions including a $8,500 travel expense and $12,000 in office upgrades. These discretionary expenses represent over 25% of a month's burn and should be reviewed with your finance team immediately."
229
+ else:
230
+ return "Based on your financial data, I recommend prioritizing runway extension and focusing on core metrics that demonstrate product-market fit. Consider reducing non-essential expenses by 15-20% to add 1-2 months to your runway before beginning fundraising conversations."
231
+ else:
232
+ try:
233
+ # Use the actual Gemini model
234
+ model = genai.GenerativeModel(st.session_state.gemini_model)
235
+
236
+ generation_config = {
237
+ "temperature": 0.7,
238
+ "top_p": 0.95,
239
+ "top_k": 40,
240
+ "max_output_tokens": 1024,
241
+ }
242
+
243
+ safety_settings = {
244
+ HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_NONE,
245
+ HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
246
+ HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE,
247
+ HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_NONE
248
+ }
249
+
250
+ response = model.generate_content(
251
+ prompt,
252
+ generation_config=generation_config,
253
+ safety_settings=safety_settings
254
+ )
255
+
256
+ return response.text
257
+ except Exception as e:
258
+ st.warning(f"Error generating AI response: {e}")
259
+ # Fall back to simulated response
260
+ return generate_ai_response(prompt, simulate=True)
261
+
262
+ # Financial modeling functions
263
+ def calculate_runway(initial_cash, monthly_burn, monthly_revenue, growth_rate, months=24):
264
+ """Calculate runway based on current burn rate and revenue growth."""
265
+ dates = [datetime.now() + timedelta(days=30*i) for i in range(months)]
266
+ df = pd.DataFrame(index=dates, columns=['Cash', 'Revenue', 'Expenses', 'Net_Burn', 'Cumulative_Cash'])
267
+
268
+ current_cash = initial_cash
269
+ current_revenue = monthly_revenue
270
+ df.iloc[0, df.columns.get_loc('Cash')] = current_cash
271
+ df.iloc[0, df.columns.get_loc('Revenue')] = current_revenue
272
+ df.iloc[0, df.columns.get_loc('Expenses')] = monthly_burn
273
+ df.iloc[0, df.columns.get_loc('Net_Burn')] = monthly_burn - current_revenue
274
+ df.iloc[0, df.columns.get_loc('Cumulative_Cash')] = current_cash
275
+
276
+ runway_months = months
277
+ for i in range(1, months):
278
+ current_revenue = current_revenue * (1 + growth_rate)
279
+ net_burn = monthly_burn - current_revenue
280
+ current_cash = current_cash - net_burn
281
+
282
+ df.iloc[i, df.columns.get_loc('Cash')] = current_cash
283
+ df.iloc[i, df.columns.get_loc('Revenue')] = current_revenue
284
+ df.iloc[i, df.columns.get_loc('Expenses')] = monthly_burn
285
+ df.iloc[i, df.columns.get_loc('Net_Burn')] = net_burn
286
+ df.iloc[i, df.columns.get_loc('Cumulative_Cash')] = current_cash
287
+
288
+ if current_cash <= 0:
289
+ runway_months = i
290
+ break
291
+
292
+ return runway_months, df
293
+
294
+ def simulate_decision(initial_cash, monthly_burn, monthly_revenue, growth_rate,
295
+ new_expenses=0, new_hires=0, new_marketing=0, growth_impact=0):
296
+ """Simulate the impact of a business decision on runway."""
297
+ # Calculate current runway
298
+ current_runway, current_df = calculate_runway(initial_cash, monthly_burn, monthly_revenue, growth_rate)
299
+
300
+ # Calculate additional expenses
301
+ additional_expenses = new_expenses + (new_hires * ENGINEER_SALARY) + new_marketing
302
+
303
+ # Calculate new runway
304
+ new_runway, new_df = calculate_runway(
305
+ initial_cash,
306
+ monthly_burn + additional_expenses,
307
+ monthly_revenue,
308
+ growth_rate + growth_impact
309
+ )
310
+
311
+ return current_runway, new_runway, current_df, new_df
312
+
313
+ def detect_suspicious_transactions(transactions_df):
314
+ """AI-enhanced suspicious transaction detection."""
315
+ df = transactions_df.copy()
316
+
317
+ # Define thresholds for each category
318
+ category_thresholds = {
319
+ "Travel": 3000,
320
+ "Marketing": 10000,
321
+ "Office": 7000,
322
+ "Software": 6000,
323
+ "Consulting": 5000,
324
+ "Legal": 6000
325
+ }
326
+
327
+ # Define suspicious terms
328
+ suspicious_terms = ['luxury', 'cruise', 'premium', 'personal', 'gift']
329
+
330
+ # Add suspicious column
331
+ df['Suspicious'] = False
332
+ df['Reason'] = ""
333
+ df['Risk_Score'] = 0
334
+
335
+ # Check for suspicious patterns
336
+ for idx, row in df.iterrows():
337
+ reasons = []
338
+ risk_score = 0
339
+
340
+ # Check if amount exceeds category threshold
341
+ if row['Category'] in category_thresholds:
342
+ if row['Amount'] > category_thresholds[row['Category']]:
343
+ reasons.append(f"Amount exceeds typical spending for {row['Category']}")
344
+ risk_score += 30
345
+
346
+ # Higher risk for significantly exceeding threshold
347
+ excess_percentage = (row['Amount'] - category_thresholds[row['Category']]) / category_thresholds[row['Category']] * 100
348
+ if excess_percentage > 100: # More than double the threshold
349
+ risk_score += 20
350
+
351
+ # Check for suspicious vendors or descriptions
352
+ if any(term in str(row['Vendor']).lower() for term in suspicious_terms):
353
+ reasons.append(f"Vendor name contains suspicious term")
354
+ risk_score += 25
355
+
356
+ if any(term in str(row['Description']).lower() for term in suspicious_terms):
357
+ reasons.append(f"Description contains suspicious term")
358
+ risk_score += 20
359
+
360
+ # Check for rounded amounts (potential indicator of estimation/fabrication)
361
+ if row['Amount'] % 1000 == 0 and row['Amount'] > 3000:
362
+ reasons.append(f"Suspiciously round amount")
363
+ risk_score += 15
364
+
365
+ # Mark as suspicious if risk score is high enough
366
+ if risk_score >= 30:
367
+ df.at[idx, 'Suspicious'] = True
368
+ df.at[idx, 'Reason'] = "; ".join(reasons)
369
+ df.at[idx, 'Risk_Score'] = risk_score
370
+
371
+ # Sort by risk score
372
+ df = df.sort_values(by='Risk_Score', ascending=False)
373
+
374
+ return df
375
+
376
+ # Import page functions
377
+ from dashboard_page import render_financial_dashboard, get_runway_analysis, get_fundraising_readiness_analysis
378
+ from decision_simulator import render_decision_simulator, get_decision_analysis
379
+ from fund_monitoring import render_fund_monitoring, get_fraud_analysis
380
+ from financial_advisor import render_ai_financial_advisor, get_advisory_guidance, generate_voice_response
381
+ from book_session import render_book_session
382
+
383
+ # UI Components
384
+ def create_sidebar():
385
+ """Create sidebar with company profile and filters."""
386
+ st.sidebar.title("StartupFinancePilot")
387
+ st.sidebar.image("https://img.freepik.com/premium-vector/business-finance-analytics-logo-design-vector-template_67715-552.jpg", width=150)
388
+
389
+ # Company profile
390
+ startup_data, _, _ = load_sample_data()
391
+
392
+ st.sidebar.header("Company Profile")
393
+ st.sidebar.write(f"**{startup_data['name']}**")
394
+ st.sidebar.write(f"Stage: {startup_data['stage']}")
395
+ st.sidebar.write(f"Founded: {startup_data['founded']}")
396
+ st.sidebar.write(f"Employees: {startup_data['employees']}")
397
+ st.sidebar.write(f"Last Funding: {startup_data['last_funding']}")
398
+
399
+ # AI Status
400
+ has_api = setup_genai()
401
+ ai_status = "🟢 Connected" if has_api else "🟡 Demo Mode"
402
+ st.sidebar.write(f"AI Status: {ai_status}")
403
+ if not has_api:
404
+ st.sidebar.info("Running in demo mode with simulated AI responses. Add GOOGLE_API_KEY to secrets for full functionality.")
405
+
406
+ # App navigation
407
+ st.sidebar.header("Navigation")
408
+ page = st.sidebar.radio("Go to", [
409
+ "Financial Dashboard",
410
+ "Decision Simulator",
411
+ "Fund Monitoring",
412
+ "AI Financial Advisor",
413
+ "Book a Session"
414
+ ])
415
+
416
+ return page
417
+
418
+ # Main application
419
+ def main():
420
+ # Load sample data
421
+ startup_data, cash_flow_df, transactions_df = load_sample_data()
422
+
423
+ # Create sidebar and get selected page
424
+ page = create_sidebar()
425
+
426
+ # Render selected page
427
+ if page == "Financial Dashboard":
428
+ render_financial_dashboard(startup_data, cash_flow_df)
429
+ elif page == "Decision Simulator":
430
+ render_decision_simulator(startup_data)
431
+ elif page == "Fund Monitoring":
432
+ render_fund_monitoring(transactions_df)
433
+ elif page == "AI Financial Advisor":
434
+ render_ai_financial_advisor(startup_data)
435
+ elif page == "Book a Session":
436
+ render_book_session()
437
+
438
+ if __name__ == "__main__":
439
+ main()
pages/dashboard-page.py ADDED
@@ -0,0 +1,342 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def render_financial_dashboard(startup_data, cash_flow_df):
2
+ """
3
+ Render the AI-powered financial dashboard page.
4
+
5
+ This dashboard uses AI to analyze financial data and provide actionable insights
6
+ to startup founders, helping them make better decisions about their runway,
7
+ spending, and financial health.
8
+ """
9
+ st.markdown("<h1 class='main-header'>Financial Dashboard</h1>", unsafe_allow_html=True)
10
+ st.markdown("<p class='sub-header'>AI-powered financial insights at a glance</p>", unsafe_allow_html=True)
11
+
12
+ # How AI helps with financial dashboards
13
+ with st.expander("ℹ️ How AI enhances your financial dashboard"):
14
+ st.markdown("""
15
+ ### How AI Powers Your Financial Dashboard
16
+
17
+ The financial dashboard uses AI to transform raw financial data into actionable intelligence:
18
+
19
+ - **Automated Analysis**: Instead of manually calculating runway and burn rates, our AI model analyzes your data and highlights critical trends
20
+ - **Predictive Forecasting**: AI forecasts your runway using pattern recognition and predictive analytics to account for varying growth rates
21
+ - **Anomaly Detection**: The system identifies unusual spending patterns or concerning financial trends that human analysis might miss
22
+ - **Strategic Recommendations**: Based on your specific financial situation, the AI provides tailored recommendations to optimize your runway
23
+ - **Benchmark Comparison**: Your metrics are automatically compared against industry standards for startups at your funding stage
24
+
25
+ This helps founders save time, catch financial issues early, and make data-driven decisions without needing financial expertise.
26
+ """)
27
+
28
+ # AI Insights Summary
29
+ insights_key = f"dashboard_{date.today().isoformat()}"
30
+ if insights_key not in st.session_state.insights_cache:
31
+ insights = generate_ai_response(f"""
32
+ You are a financial advisor for startups. Based on this startup's data:
33
+ - Current cash: ${startup_data['cash']}
34
+ - Monthly burn rate: ${startup_data['burn_rate']}
35
+ - Monthly revenue: ${startup_data['revenue']}
36
+ - Monthly growth rate: {startup_data['growth_rate'] * 100}%
37
+
38
+ Provide the top 3 most important financial insights that the founder should know today.
39
+ Format each insight as a brief, action-oriented bullet point.
40
+ """, simulate=True)
41
+ st.session_state.insights_cache[insights_key] = insights
42
+
43
+ with st.expander("📊 AI Financial Insights", expanded=True):
44
+ st.markdown("<span class='ai-badge'>AI-Generated Insights</span>", unsafe_allow_html=True)
45
+ st.markdown(st.session_state.insights_cache[insights_key])
46
+
47
+ # Key metrics
48
+ col1, col2, col3, col4 = st.columns(4)
49
+
50
+ # Calculate runway
51
+ runway_months, runway_df = calculate_runway(
52
+ startup_data['cash'],
53
+ startup_data['burn_rate'],
54
+ startup_data['revenue'],
55
+ startup_data['growth_rate']
56
+ )
57
+
58
+ # Determine status colors based on financial health indicators
59
+ runway_status = "danger-metric" if runway_months < 6 else ("warning-metric" if runway_months < 9 else "good-metric")
60
+ burn_status = "danger-metric" if startup_data['burn_rate'] > 100000 else ("warning-metric" if startup_data['burn_rate'] > 80000 else "good-metric")
61
+ revenue_status = "good-metric" if startup_data['revenue'] > 20000 else ("warning-metric" if startup_data['revenue'] > 10000 else "danger-metric")
62
+
63
+ with col1:
64
+ st.markdown(f"""
65
+ <div class='metric-card'>
66
+ <p class='metric-label'>Current Cash</p>
67
+ <p class='metric-value'>${startup_data['cash']:,}</p>
68
+ </div>
69
+ """, unsafe_allow_html=True)
70
+
71
+ with col2:
72
+ st.markdown(f"""
73
+ <div class='metric-card'>
74
+ <p class='metric-label'>Monthly Burn</p>
75
+ <p class='metric-value {burn_status}'>${startup_data['burn_rate']:,}</p>
76
+ </div>
77
+ """, unsafe_allow_html=True)
78
+
79
+ with col3:
80
+ st.markdown(f"""
81
+ <div class='metric-card'>
82
+ <p class='metric-label'>Monthly Revenue</p>
83
+ <p class='metric-value {revenue_status}'>${startup_data['revenue']:,}</p>
84
+ </div>
85
+ """, unsafe_allow_html=True)
86
+
87
+ with col4:
88
+ st.markdown(f"""
89
+ <div class='metric-card'>
90
+ <p class='metric-label'>Runway</p>
91
+ <p class='metric-value {runway_status}'>{runway_months} months</p>
92
+ </div>
93
+ """, unsafe_allow_html=True)
94
+
95
+ # Financial charts
96
+ st.subheader("Financial Overview")
97
+
98
+ tab1, tab2, tab3 = st.tabs(["Runway Projection", "Revenue vs. Expenses", "Burn Rate Trend"])
99
+
100
+ with tab1:
101
+ # Runway projection chart
102
+ fig = px.line(runway_df.reset_index(), x='index', y='Cumulative_Cash',
103
+ title="Cash Runway Projection",
104
+ labels={'index': 'Date', 'Cumulative_Cash': 'Remaining Cash ($)'},
105
+ color_discrete_sequence=['#0066cc'])
106
+ fig.add_hline(y=0, line_dash="dash", line_color="red", annotation_text="Out of Cash")
107
+ fig.update_layout(
108
+ height=400,
109
+ plot_bgcolor='rgba(240,247,255,0.8)',
110
+ xaxis_title="Date",
111
+ yaxis_title="Cash Balance ($)",
112
+ font=dict(family="Arial, sans-serif", size=12),
113
+ margin=dict(l=20, r=20, t=40, b=20),
114
+ )
115
+ st.plotly_chart(fig, use_container_width=True)
116
+
117
+ # Get analysis from Gemini
118
+ with st.expander("🔍 AI Financial Analysis", expanded=True):
119
+ # Use cache to avoid repeated API calls
120
+ analysis_key = f"runway_{date.today().isoformat()}"
121
+ if analysis_key not in st.session_state.insights_cache:
122
+ analysis = get_runway_analysis(startup_data)
123
+ st.session_state.insights_cache[analysis_key] = analysis
124
+
125
+ st.markdown("<span class='ai-badge'>AI Financial Analysis</span>", unsafe_allow_html=True)
126
+ st.markdown(st.session_state.insights_cache[analysis_key])
127
+
128
+ with tab2:
129
+ # Revenue vs Expenses chart
130
+ rev_exp_df = cash_flow_df.copy()
131
+ fig = px.bar(rev_exp_df, x='Month', y=['Revenue', 'Total_Expenses'],
132
+ title="Revenue vs. Expenses",
133
+ barmode='group',
134
+ labels={'value': 'Amount ($)', 'variable': 'Category'},
135
+ color_discrete_sequence=['#28a745', '#dc3545'])
136
+ fig.update_layout(
137
+ height=400,
138
+ plot_bgcolor='rgba(240,247,255,0.8)',
139
+ xaxis_title="Month",
140
+ yaxis_title="Amount ($)",
141
+ font=dict(family="Arial, sans-serif", size=12),
142
+ legend_title="",
143
+ margin=dict(l=20, r=20, t=40, b=20),
144
+ )
145
+ st.plotly_chart(fig, use_container_width=True)
146
+
147
+ # Calculate revenue growth
148
+ revenue_growth = [(cash_flow_df['Revenue'].iloc[i] / cash_flow_df['Revenue'].iloc[i-1] - 1) * 100 if i > 0 else 0
149
+ for i in range(len(cash_flow_df))]
150
+ avg_growth = sum(revenue_growth[1:]) / len(revenue_growth[1:])
151
+
152
+ col1, col2 = st.columns(2)
153
+ with col1:
154
+ st.metric("Average Monthly Revenue Growth", f"{avg_growth:.1f}%")
155
+ with col2:
156
+ expense_growth = (cash_flow_df['Total_Expenses'].iloc[-1] / cash_flow_df['Total_Expenses'].iloc[0] - 1) * 100
157
+ st.metric("Total Expense Growth", f"{expense_growth:.1f}%", delta=f"{expense_growth - avg_growth:.1f}%", delta_color="inverse")
158
+
159
+ with tab3:
160
+ # Burn rate trend
161
+ fig = px.line(cash_flow_df, x='Month', y='Net_Burn',
162
+ title="Monthly Net Burn Trend",
163
+ labels={'Net_Burn': 'Net Burn ($)'},
164
+ color_discrete_sequence=['#dc3545'])
165
+ fig.update_layout(
166
+ height=400,
167
+ plot_bgcolor='rgba(240,247,255,0.8)',
168
+ xaxis_title="Month",
169
+ yaxis_title="Net Burn ($)",
170
+ font=dict(family="Arial, sans-serif", size=12),
171
+ margin=dict(l=20, r=20, t=40, b=20),
172
+ )
173
+
174
+ # Add efficiency ratio as a second y-axis
175
+ efficiency_ratio = [cash_flow_df['Revenue'].iloc[i] / cash_flow_df['Total_Expenses'].iloc[i] * 100
176
+ for i in range(len(cash_flow_df))]
177
+
178
+ fig.add_trace(go.Scatter(
179
+ x=cash_flow_df['Month'],
180
+ y=efficiency_ratio,
181
+ name='Efficiency Ratio (%)',
182
+ yaxis='y2',
183
+ line=dict(color='#0066cc', width=2, dash='dot')
184
+ ))
185
+
186
+ fig.update_layout(
187
+ yaxis2=dict(
188
+ title='Efficiency Ratio (%)',
189
+ overlaying='y',
190
+ side='right',
191
+ range=[0, max(efficiency_ratio) * 1.2]
192
+ )
193
+ )
194
+
195
+ st.plotly_chart(fig, use_container_width=True)
196
+
197
+ with st.expander("🔎 Understanding Efficiency Ratio"):
198
+ st.info("The efficiency ratio measures how efficiently your startup is generating revenue relative to expenses. A higher percentage means you're getting more revenue per dollar spent. Venture-backed startups typically aim for at least 40% before Series B funding.")
199
+
200
+ # Expense breakdown
201
+ st.subheader("Expense Breakdown")
202
+
203
+ # Last month expenses
204
+ last_month = cash_flow_df.iloc[-1]
205
+ expense_categories = ['Payroll', 'Marketing', 'Office', 'Software', 'Travel', 'Legal', 'Misc']
206
+ expense_values = [last_month[cat] for cat in expense_categories]
207
+
208
+ col1, col2 = st.columns([2, 1])
209
+
210
+ with col1:
211
+ fig = px.pie(values=expense_values, names=expense_categories,
212
+ title="Current Month Expense Breakdown",
213
+ color_discrete_sequence=px.colors.sequential.Blues_r)
214
+ fig.update_layout(
215
+ height=400,
216
+ font=dict(family="Arial, sans-serif", size=12),
217
+ margin=dict(l=20, r=20, t=40, b=20),
218
+ )
219
+ fig.update_traces(textposition='inside', textinfo='percent+label')
220
+ st.plotly_chart(fig, use_container_width=True)
221
+
222
+ with col2:
223
+ # Expense analysis
224
+ st.markdown("<h4>Expense Analysis</h4>", unsafe_allow_html=True)
225
+
226
+ # Calculate industry benchmarks (simulated)
227
+ benchmarks = {
228
+ "Payroll": "70-80%",
229
+ "Marketing": "10-15%",
230
+ "Office": "5-8%",
231
+ "Software": "3-5%"
232
+ }
233
+
234
+ # Create a table with expense categories, amounts, and % of total
235
+ expense_df = pd.DataFrame({
236
+ "Category": expense_categories,
237
+ "Amount": expense_values,
238
+ "% of Total": [v / sum(expense_values) * 100 for v in expense_values]
239
+ })
240
+
241
+ # Add benchmark column
242
+ expense_df["Industry Benchmark"] = expense_df["Category"].map(
243
+ lambda x: benchmarks.get(x, "N/A")
244
+ )
245
+
246
+ # Format the dataframe for display
247
+ formatted_df = expense_df.copy()
248
+ formatted_df["Amount"] = formatted_df["Amount"].apply(lambda x: f"${x:,.0f}")
249
+ formatted_df["% of Total"] = formatted_df["% of Total"].apply(lambda x: f"{x:.1f}%")
250
+
251
+ st.table(formatted_df)
252
+
253
+ # AI-powered spending optimization
254
+ with st.expander("💡 AI Spending Optimization"):
255
+ st.markdown("<span class='ai-badge'>AI Recommendation</span>", unsafe_allow_html=True)
256
+
257
+ # Use cache to avoid repeated API calls
258
+ spending_key = f"spending_{date.today().isoformat()}"
259
+ if spending_key not in st.session_state.insights_cache:
260
+ spending_recommendation = generate_ai_response("""
261
+ Based on your expense breakdown, recommend 2-3 specific ways to optimize spending to extend runway.
262
+ Focus on industry best practices for seed-stage startups.
263
+ """, simulate=True)
264
+ st.session_state.insights_cache[spending_key] = spending_recommendation
265
+
266
+ st.markdown(st.session_state.insights_cache[spending_key])
267
+
268
+ # Fundraising Readiness Assessment
269
+ st.subheader("Fundraising Readiness")
270
+
271
+ # Get AI analysis of fundraising readiness
272
+ fundraising_key = f"fundraising_{date.today().isoformat()}"
273
+ if fundraising_key not in st.session_state.insights_cache:
274
+ fundraising_analysis = get_fundraising_readiness_analysis(startup_data, cash_flow_df)
275
+ st.session_state.insights_cache[fundraising_key] = fundraising_analysis
276
+
277
+ st.markdown("<div class='advisor-card'>", unsafe_allow_html=True)
278
+ st.markdown("<span class='ai-badge'>AI Fundraising Assessment</span>", unsafe_allow_html=True)
279
+ st.markdown(f"<p class='advice-text'>{st.session_state.insights_cache[fundraising_key]}</p>", unsafe_allow_html=True)
280
+ st.markdown("</div>", unsafe_allow_html=True)
281
+
282
+ # Call-to-action for advisor
283
+ st.info("📅 Need personalized guidance on fundraising? [Book a session](#book-a-session) with our AI financial advisor.")
284
+
285
+ def get_runway_analysis(financial_data):
286
+ """Get runway analysis using Gemini."""
287
+ prompt = f"""
288
+ You are a financial advisor for startups. Analyze this startup's financial data:
289
+ - Current cash: ${financial_data['cash']}
290
+ - Monthly burn rate: ${financial_data['burn_rate']}
291
+ - Monthly revenue: ${financial_data['revenue']}
292
+ - Monthly growth rate: {financial_data['growth_rate'] * 100}%
293
+
294
+ Provide a detailed analysis of their runway and financial health. Include:
295
+ 1. Exact runway calculation in months
296
+ 2. Assessment of financial health (critical, concerning, stable, or healthy)
297
+ 3. Benchmarks compared to similar seed-stage startups
298
+ 4. Three specific, actionable recommendations to improve runway
299
+ 5. Key metrics they should focus on
300
+
301
+ Format your response in a structured, easy-to-read format with clear sections and bullet points.
302
+ """
303
+
304
+ return generate_ai_response(prompt)
305
+
306
+ def get_fundraising_readiness_analysis(startup_data, cash_flow_df):
307
+ """Get AI analysis of fundraising readiness."""
308
+ metrics = {
309
+ "MRR Growth": f"{(cash_flow_df['Revenue'].iloc[-1] / cash_flow_df['Revenue'].iloc[-2] - 1) * 100:.1f}%",
310
+ "Gross Margin": f"{(cash_flow_df['Revenue'].iloc[-1] - cash_flow_df['Total_Expenses'].iloc[-1] / 2) / cash_flow_df['Revenue'].iloc[-1] * 100:.1f}%",
311
+ "CAC": "$950", # Example value
312
+ "LTV": "$4,500", # Example value
313
+ "Churn": "3.2%", # Example value
314
+ }
315
+
316
+ metrics_text = "\n".join([f"- {k}: {v}" for k, v in metrics.items()])
317
+
318
+ prompt = f"""
319
+ You are a startup fundraising advisor. Analyze this startup's readiness for their next funding round:
320
+
321
+ Company Profile:
322
+ - Stage: {startup_data['stage']}
323
+ - Last Funding: {startup_data['last_funding']}
324
+ - Current Cash: ${startup_data['cash']}
325
+ - Monthly Burn: ${startup_data['burn_rate']}
326
+ - Runway: {startup_data['cash'] / (startup_data['burn_rate'] - startup_data['revenue']):.1f} months
327
+
328
+ Key Metrics:
329
+ {metrics_text}
330
+
331
+ Provide a comprehensive fundraising readiness assessment:
332
+ 1. Overall fundraising readiness score (0-10)
333
+ 2. Assessment of current metrics compared to investor expectations for next round
334
+ 3. Identify the 3 most critical metrics to improve before fundraising
335
+ 4. Recommend specific targets for each key metric
336
+ 5. Suggest timeline and specific milestones for fundraising preparation
337
+ 6. Estimate reasonable valuation range based on metrics and market conditions
338
+
339
+ Be specific with numbers, timelines, and actionable targets.
340
+ """
341
+
342
+ return generate_ai_response(prompt)
pages/decision-simulator.py ADDED
@@ -0,0 +1,321 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def render_decision_simulator(startup_data):
2
+ """
3
+ Render the AI-powered decision simulator page.
4
+
5
+ This feature helps startup founders test the financial impact of business
6
+ decisions before implementing them, using AI to analyze risks and benefits.
7
+ """
8
+ st.markdown("<h1 class='main-header'>Decision Simulator</h1>", unsafe_allow_html=True)
9
+ st.markdown("<p class='sub-header'>AI-powered analysis of business decisions</p>", unsafe_allow_html=True)
10
+
11
+ # How AI helps with decision-making
12
+ with st.expander("ℹ️ How AI enhances your decision-making"):
13
+ st.markdown("""
14
+ ### How AI Powers Your Decision Simulator
15
+
16
+ The decision simulator uses AI to help you make better strategic decisions:
17
+
18
+ - **Scenario Analysis**: Our AI model simulates multiple financial scenarios based on your input variables
19
+ - **Risk Assessment**: The system automatically evaluates risk levels based on your cash runway and growth metrics
20
+ - **Return Prediction**: AI algorithms predict potential returns on investments like hiring or marketing
21
+ - **Opportunity Cost Analysis**: The model compares different allocations of capital to maximize growth
22
+ - **Personalized Recommendations**: Based on your specific situation, the AI provides tailored alternatives
23
+
24
+ This helps founders make data-driven decisions with less guesswork, avoid costly mistakes, and optimize resource allocation.
25
+ """)
26
+
27
+ st.write("Test the financial impact of key business decisions before implementing them. Our AI advisor will analyze the risks and benefits.")
28
+
29
+ # Quick decision templates
30
+ st.subheader("Common Scenarios")
31
+
32
+ decision_templates = {
33
+ "Hiring Engineering Team": {
34
+ "description": "Evaluate the impact of growing your engineering team",
35
+ "new_hires": 3,
36
+ "new_marketing": 0,
37
+ "other_expenses": 2000,
38
+ "growth_impact": 0.02,
39
+ "question": "We're considering hiring 3 more engineers to accelerate product development. How will this affect our runway and what growth impact should we expect to justify this investment?"
40
+ },
41
+ "Marketing Expansion": {
42
+ "description": "Test increasing your marketing budget",
43
+ "new_hires": 0,
44
+ "new_marketing": 15000,
45
+ "other_expenses": 0,
46
+ "growth_impact": 0.04,
47
+ "question": "We want to increase our marketing spend by $15K/month to drive growth. What growth rate would we need to achieve to make this financially viable?"
48
+ },
49
+ "Office Expansion": {
50
+ "description": "Analyze the cost of moving to a larger office",
51
+ "new_hires": 0,
52
+ "new_marketing": 0,
53
+ "other_expenses": 8000,
54
+ "growth_impact": 0.01,
55
+ "question": "We're considering moving to a larger office space that would add $8K/month to our expenses. Is this justified at our current stage?"
56
+ },
57
+ "Custom Scenario": {
58
+ "description": "Create your own custom scenario",
59
+ "new_hires": 0,
60
+ "new_marketing": 0,
61
+ "other_expenses": 0,
62
+ "growth_impact": 0.0,
63
+ "question": ""
64
+ }
65
+ }
66
+
67
+ # Template selection
68
+ template_cols = st.columns(4)
69
+ selected_template = None
70
+
71
+ for i, (template_name, template) in enumerate(decision_templates.items()):
72
+ with template_cols[i]:
73
+ if st.button(f"{template_name}\n{template['description']}", key=f"template_{i}"):
74
+ selected_template = template_name
75
+
76
+ # Initialize form values based on selected template
77
+ if selected_template and selected_template != "Custom Scenario":
78
+ new_hires = decision_templates[selected_template]["new_hires"]
79
+ new_marketing = decision_templates[selected_template]["new_marketing"]
80
+ other_expenses = decision_templates[selected_template]["other_expenses"]
81
+ growth_impact = decision_templates[selected_template]["growth_impact"]
82
+ question = decision_templates[selected_template]["question"]
83
+ else:
84
+ new_hires = 0
85
+ new_marketing = 0
86
+ other_expenses = 0
87
+ growth_impact = 0.0
88
+ question = ""
89
+
90
+ # Decision input form
91
+ with st.form("decision_form"):
92
+ st.subheader("Scenario Parameters")
93
+
94
+ col1, col2 = st.columns(2)
95
+
96
+ with col1:
97
+ new_hires = st.number_input("New Engineering Hires", min_value=0, max_value=10, value=new_hires,
98
+ help=f"Each engineer costs ${ENGINEER_SALARY:,} per month")
99
+ st.caption(f"Monthly Cost: ${new_hires * ENGINEER_SALARY:,}")
100
+
101
+ new_marketing = st.number_input("Additional Monthly Marketing Budget",
102
+ min_value=0, max_value=50000, value=new_marketing, step=1000,
103
+ help="Additional marketing spend per month")
104
+
105
+ with col2:
106
+ other_expenses = st.number_input("Other Additional Monthly Expenses",
107
+ min_value=0, max_value=50000, value=other_expenses, step=1000,
108
+ help="Any other additional monthly expenses")
109
+
110
+ growth_impact = st.slider("Estimated Impact on Monthly Growth Rate",
111
+ min_value=0.0, max_value=0.10, value=growth_impact, step=0.01,
112
+ format="%.2f",
113
+ help="Estimated increase in monthly growth rate due to these investments")
114
+ st.caption(f"New Growth Rate: {(startup_data['growth_rate'] + growth_impact) * 100:.1f}% (current: {startup_data['growth_rate'] * 100:.1f}%)")
115
+
116
+ question = st.text_area("Describe your decision scenario",
117
+ value=question,
118
+ height=100,
119
+ placeholder="E.g., We're considering hiring two more engineers and increasing our marketing budget...")
120
+
121
+ decision_summary = f"""
122
+ - {new_hires} new engineers: ${new_hires * ENGINEER_SALARY:,}/month
123
+ - Marketing increase: ${new_marketing:,}/month
124
+ - Other expenses: ${other_expenses:,}/month
125
+ - Total additional burn: ${new_hires * ENGINEER_SALARY + new_marketing + other_expenses:,}/month
126
+ - Growth impact: +{growth_impact * 100:.1f}% monthly growth
127
+ """
128
+
129
+ st.markdown(f"**Decision Summary:**\n{decision_summary}")
130
+
131
+ submitted = st.form_submit_button("Simulate Decision")
132
+
133
+ if submitted:
134
+ # Calculate current and new runway
135
+ current_runway, new_runway, current_df, new_df = simulate_decision(
136
+ startup_data['cash'],
137
+ startup_data['burn_rate'],
138
+ startup_data['revenue'],
139
+ startup_data['growth_rate'],
140
+ other_expenses,
141
+ new_hires,
142
+ new_marketing,
143
+ growth_impact
144
+ )
145
+
146
+ # Display results
147
+ st.markdown("<h3>Decision Impact Analysis</h3>", unsafe_allow_html=True)
148
+
149
+ # Summary metrics
150
+ col1, col2, col3 = st.columns(3)
151
+
152
+ with col1:
153
+ st.metric("Current Runway", f"{current_runway} months")
154
+ with col2:
155
+ runway_change = new_runway - current_runway
156
+ st.metric("New Runway", f"{new_runway} months",
157
+ delta=f"{runway_change} months",
158
+ delta_color="off" if runway_change == 0 else ("normal" if runway_change > 0 else "inverse"))
159
+ with col3:
160
+ new_burn = startup_data['burn_rate'] + other_expenses + (new_hires * ENGINEER_SALARY) + new_marketing
161
+ burn_change = new_burn - startup_data['burn_rate']
162
+ burn_percentage = burn_change / startup_data['burn_rate'] * 100
163
+ st.metric("New Monthly Burn", f"${new_burn:,}",
164
+ delta=f"${burn_change:,} ({burn_percentage:.1f}%)",
165
+ delta_color="inverse")
166
+
167
+ # Cash projection comparison
168
+ st.subheader("Cash Projection Comparison")
169
+
170
+ # Combine dataframes for comparison
171
+ current_df['Scenario'] = 'Current'
172
+ new_df['Scenario'] = 'After Decision'
173
+
174
+ combined_df = pd.concat([current_df, new_df])
175
+ combined_df = combined_df.reset_index()
176
+ combined_df = combined_df.rename(columns={'index': 'Date'})
177
+
178
+ # Plot comparison
179
+ fig = px.line(combined_df, x='Date', y='Cumulative_Cash', color='Scenario',
180
+ title="Cash Runway Comparison",
181
+ labels={'Cumulative_Cash': 'Remaining Cash'},
182
+ color_discrete_sequence=['#4c78a8', '#f58518'])
183
+
184
+ fig.add_hline(y=0, line_dash="dash", line_color="red", annotation_text="Out of Cash")
185
+
186
+ fig.update_layout(
187
+ height=400,
188
+ plot_bgcolor='rgba(240,247,255,0.8)',
189
+ xaxis_title="Date",
190
+ yaxis_title="Cash Balance ($)",
191
+ font=dict(family="Arial, sans-serif", size=12),
192
+ margin=dict(l=20, r=20, t=40, b=20),
193
+ )
194
+
195
+ st.plotly_chart(fig, use_container_width=True)
196
+
197
+ # Get AI analysis
198
+ if question:
199
+ decision_params = {
200
+ "new_hires": new_hires,
201
+ "new_marketing": new_marketing,
202
+ "other_expenses": other_expenses,
203
+ "growth_impact": growth_impact
204
+ }
205
+
206
+ analysis = get_decision_analysis(question, startup_data, decision_params)
207
+
208
+ st.markdown("<div class='advisor-card'>", unsafe_allow_html=True)
209
+ st.markdown("<span class='ai-badge'>AI Decision Analysis</span>", unsafe_allow_html=True)
210
+ st.markdown(f"<p class='advice-text'>{analysis}</p>", unsafe_allow_html=True)
211
+ st.markdown("</div>", unsafe_allow_html=True)
212
+
213
+ # Break down impacts of each component
214
+ st.subheader("Component Impact Analysis")
215
+
216
+ # Calculate the impact of each component in isolation
217
+ _, hiring_runway, _, _ = simulate_decision(
218
+ startup_data['cash'],
219
+ startup_data['burn_rate'],
220
+ startup_data['revenue'],
221
+ startup_data['growth_rate'],
222
+ 0,
223
+ new_hires,
224
+ 0,
225
+ 0
226
+ )
227
+
228
+ _, marketing_runway, _, _ = simulate_decision(
229
+ startup_data['cash'],
230
+ startup_data['burn_rate'],
231
+ startup_data['revenue'],
232
+ startup_data['growth_rate'],
233
+ 0,
234
+ 0,
235
+ new_marketing,
236
+ growth_impact
237
+ )
238
+
239
+ _, expenses_runway, _, _ = simulate_decision(
240
+ startup_data['cash'],
241
+ startup_data['burn_rate'],
242
+ startup_data['revenue'],
243
+ startup_data['growth_rate'],
244
+ other_expenses,
245
+ 0,
246
+ 0,
247
+ 0
248
+ )
249
+
250
+ component_data = {
251
+ "Component": ["Engineering Hires", "Marketing Increase", "Other Expenses", "Combined Impact"],
252
+ "Runway Impact (months)": [
253
+ hiring_runway - current_runway,
254
+ marketing_runway - current_runway,
255
+ expenses_runway - current_runway,
256
+ new_runway - current_runway
257
+ ]
258
+ }
259
+
260
+ component_df = pd.DataFrame(component_data)
261
+
262
+ fig = px.bar(component_df, x='Component', y='Runway Impact (months)',
263
+ title="Impact of Each Component on Runway",
264
+ color='Runway Impact (months)',
265
+ color_continuous_scale=['#dc3545', '#ffc107', '#28a745'],
266
+ text='Runway Impact (months)')
267
+
268
+ fig.update_layout(
269
+ height=400,
270
+ plot_bgcolor='rgba(240,247,255,0.8)',
271
+ font=dict(family="Arial, sans-serif", size=12),
272
+ margin=dict(l=20, r=20, t=40, b=20),
273
+ )
274
+
275
+ fig.update_traces(texttemplate='%{text:.1f}', textposition='outside')
276
+ st.plotly_chart(fig, use_container_width=True)
277
+
278
+ # Risk assessment
279
+ risk_level = "High" if new_runway < 3 else ("Medium" if new_runway < 6 else "Low")
280
+ risk_color = "danger-metric" if risk_level == "High" else ("warning-metric" if risk_level == "Medium" else "good-metric")
281
+
282
+ st.markdown(f"""
283
+ <div class='metric-card'>
284
+ <p class='metric-label'>Risk Assessment</p>
285
+ <p class='metric-value {risk_color}'>{risk_level} Risk Decision</p>
286
+ <p>This decision would give you {new_runway} months of runway.</p>
287
+ </div>
288
+ """, unsafe_allow_html=True)
289
+
290
+ # Recommendations
291
+ st.info("💡 **Want personalized guidance on this decision?** [Book a session](#book-a-session) with our AI financial advisor for detailed analysis.")
292
+
293
+ def get_decision_analysis(question, financial_data, decision_params):
294
+ """Get AI analysis for a specific business decision."""
295
+ prompt = f"""
296
+ You are a financial advisor for startups. A founder asks:
297
+ "{question}"
298
+
299
+ Here's their current financial situation:
300
+ - Current cash: ${financial_data['cash']}
301
+ - Monthly burn rate: ${financial_data['burn_rate']}
302
+ - Monthly revenue: ${financial_data['revenue']}
303
+ - Monthly growth rate: {financial_data['growth_rate'] * 100}%
304
+
305
+ They're considering these changes:
306
+ - Adding {decision_params['new_hires']} new engineers (${ENGINEER_SALARY}/month each)
307
+ - Increasing marketing budget by ${decision_params['new_marketing']}/month
308
+ - Adding ${decision_params['other_expenses']}/month in other expenses
309
+ - Expecting {decision_params['growth_impact'] * 100}% additional monthly growth
310
+
311
+ Analyze this decision thoroughly:
312
+ 1. Quantify the impact on runway (exact calculation)
313
+ 2. Assess the risk level (low, medium, high)
314
+ 3. Compare the ROI potential
315
+ 4. Provide 3 specific recommendations or alternatives
316
+ 5. Suggest timeline and milestones for implementation if approved
317
+
318
+ Be direct and specific with numbers and timeframes.
319
+ """
320
+
321
+ return generate_ai_response(prompt)
pages/financial-advisor.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def render_ai_financial_advisor(startup_data):
2
+ """
3
+ Render the AI financial advisor page with voice chat capabilities.
4
+
5
+ This feature provides conversational financial guidance to founders through a
6
+ natural chat interface with both text and voice responses.
7
+ """
8
+ st.markdown("<h1 class='main-header'>AI Financial Advisor</h1>", unsafe_allow_html=True)
9
+ st.markdown("<p class='sub-header'>Get expert financial guidance through our AI-powered advisor</p>", unsafe_allow_html=True)
10
+
11
+ # How AI helps with financial advisory
12
+ with st.expander("ℹ️ How AI powers your financial advisor"):
13
+ st.markdown("""
14
+ ### How AI Powers Your Financial Advisor
15
+
16
+ Our AI financial advisor combines advanced language models with financial expertise:
17
+
18
+ - **Natural Language Understanding**: The system interprets complex financial questions in plain English
19
+ - **Domain-Specific Knowledge**: Our AI is trained on startup finance, venture capital, and financial modeling
20
+ - **Context-Aware Responses**: The advisor takes into account your specific financial situation and history
21
+ - **Voice Synthesis**: ElevenLabs voice technology creates natural, high-quality voice responses
22
+ - **Customized Guidance**: AI tailors advice specifically to your stage, industry, and financial position
23
+
24
+ This gives founders 24/7 access to high-quality financial guidance without the high cost of consultants.
25
+ """)
26
+
27
+ # Chat container
28
+ st.markdown("<div style='background-color: #f8f9fa; padding: 20px; border-radius: 10px; margin-bottom: 20px;'>", unsafe_allow_html=True)
29
+
30
+ # Display chat history
31
+ st.subheader("Chat with your Financial Advisor")
32
+
33
+ # Initialize chat history if needed
34
+ if 'chat_history' not in st.session_state:
35
+ st.session_state.chat_history = [
36
+ {"role": "assistant", "content": "Hi there! I'm your AI financial advisor. How can I help with your startup's finances today?"}
37
+ ]
38
+
39
+ # Display chat messages
40
+ for message in st.session_state.chat_history:
41
+ if message["role"] == "user":
42
+ st.markdown(f"<div style='background-color: #e6f7ff; padding: 10px; border-radius: 10px; margin-bottom: 10px;'><strong>You:</strong> {message['content']}</div>", unsafe_allow_html=True)
43
+ else:
44
+ st.markdown(f"<div style='background-color: #f0f7ff; padding: 10px; border-radius: 10px; margin-bottom: 10px;'><strong>Financial Advisor:</strong> {message['content']}</div>", unsafe_allow_html=True)
45
+
46
+ # Show play button for voice if it exists
47
+ if 'audio' in message and message['audio']:
48
+ st.audio(message['audio'], format='audio/mp3')
49
+
50
+ # Input for new message
51
+ col1, col2 = st.columns([5, 1])
52
+
53
+ with col1:
54
+ user_input = st.text_input("Ask a financial question", key="user_question")
55
+
56
+ with col2:
57
+ use_voice = st.checkbox("Enable voice", value=True)
58
+
59
+ # Common financial questions
60
+ st.markdown("### Common Questions")
61
+ question_cols = st.columns(3)
62
+
63
+ common_questions = [
64
+ "How much runway do we have at our current burn rate?",
65
+ "Should we increase our marketing spend given our growth rate?",
66
+ "When should we start preparing for our next fundraising round?",
67
+ "How can we optimize our burn rate without impacting growth?",
68
+ "What metrics should we focus on improving right now?",
69
+ "How do our unit economics compare to similar startups?"
70
+ ]
71
+
72
+ selected_question = None
73
+
74
+ for i, question in enumerate(common_questions):
75
+ with question_cols[i % 3]:
76
+ if st.button(question, key=f"q_{i}"):
77
+ selected_question = question
78
+
79
+ # Process user input (either from text input or selected question)
80
+ if user_input or selected_question:
81
+ question = user_input or selected_question
82
+
83
+ # Add user message to chat history
84
+ st.session_state.chat_history.append({"role": "user", "content": question})
85
+
86
+ # Get AI response
87
+ response = get_advisory_guidance(question, startup_data)
88
+
89
+ # Generate voice response if enabled
90
+ audio_data = None
91
+ if use_voice:
92
+ audio_data = generate_voice_response(response)
93
+
94
+ # Add AI response to chat history
95
+ st.session_state.chat_history.append({
96
+ "role": "assistant",
97
+ "content": response,
98
+ "audio": audio_data
99
+ })
100
+
101
+ # Rerun to display updated chat
102
+ st.experimental_rerun()
103
+
104
+ st.markdown("</div>", unsafe_allow_html=True)
105
+
106
+ # Advanced options
107
+ st.subheader("Advanced Tools")
108
+
109
+ tool_cols = st.columns(3)
110
+
111
+ with tool_cols[0]:
112
+ st.markdown("""
113
+ <div style='background-color: white; padding: 15px; border-radius: 10px; height: 200px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);'>
114
+ <h4>Financial Model Review</h4>
115
+ <p>Upload your financial model for AI analysis and recommendations.</p>
116
+ <div style='position: absolute; bottom: 15px;'>
117
+ <input type='file' disabled/>
118
+ </div>
119
+ </div>
120
+ """, unsafe_allow_html=True)
121
+
122
+ with tool_cols[1]:
123
+ st.markdown("""
124
+ <div style='background-color: white; padding: 15px; border-radius: 10px; height: 200px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);'>
125
+ <h4>Investor Pitch Review</h4>
126
+ <p>Get AI feedback on your investor pitch deck and financial projections.</p>
127
+ <div style='position: absolute; bottom: 15px;'>
128
+ <input type='file' disabled/>
129
+ </div>
130
+ </div>
131
+ """, unsafe_allow_html=True)
132
+
133
+ with tool_cols[2]:
134
+ st.markdown("""
135
+ <div style='background-color: white; padding: 15px; border-radius: 10px; height: 200px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);'>
136
+ <h4>Fundraising Strategy</h4>
137
+ <p>Generate a customized fundraising strategy based on your metrics.</p>
138
+ <div style='position: absolute; bottom: 15px;'>
139
+ <button disabled>Generate Strategy</button>
140
+ </div>
141
+ </div>
142
+ """, unsafe_allow_html=True)
143
+
144
+ # Book a session CTA
145
+ st.markdown("""
146
+ <div style='background-color: #e6f7ff; padding: 20px; border-radius: 10px; margin-top: 30px;'>
147
+ <h3>Need more in-depth guidance?</h3>
148
+ <p>Book a dedicated session with our AI financial advisor for comprehensive analysis and personalized advice.</p>
149
+ <a href='#book-a-session'><button>Book a Session</button></a>
150
+ </div>
151
+ """, unsafe_allow_html=True)
152
+
153
+ def get_advisory_guidance(question, financial_data):
154
+ """Get strategic guidance for a startup question."""
155
+ prompt = f"""
156
+ You are a strategic financial advisor for startups. A founder asks:
157
+ "{question}"
158
+
159
+ Here's their current financial situation:
160
+ - Stage: {financial_data['stage']}
161
+ - Current cash: ${financial_data['cash']}
162
+ - Monthly burn rate: ${financial_data['burn_rate']}
163
+ - Monthly revenue: ${financial_data['revenue']}
164
+ - Monthly growth rate: {financial_data['growth_rate'] * 100}%
165
+ - Last funding: {financial_data['last_funding']}
166
+ - Team size: {financial_data['employees']}
167
+
168
+ Provide detailed, actionable advice addressing their question. Include:
169
+ 1. Clear assessment of their current situation
170
+ 2. 3-5 specific, actionable recommendations with expected outcomes
171
+ 3. Relevant metrics they should track
172
+ 4. Industry benchmarks for comparison
173
+ 5. Timeline for implementation and results
174
+
175
+ Be specific with numbers, timeframes, and expected outcomes.
176
+ """
177
+
178
+ return generate_ai_response(prompt)
179
+
180
+ def generate_voice_response(text):
181
+ """Generate voice response using ElevenLabs API (simulated)."""
182
+ try:
183
+ # In a real implementation, this would call the ElevenLabs API
184
+ # For demonstration, we'll simulate an audio response
185
+
186
+ # Simulated audio data (just an empty response)
187
+ audio_data = b''
188
+
189
+ # In a real implementation, you would do something like:
190
+ # url = "https://api.elevenlabs.io/v1/text-to-speech/{voice_id}"
191
+ # headers = {
192
+ # "Accept": "audio/mpeg",
193
+ # "Content-Type": "application/json",
194
+ # "xi-api-key": st.secrets["ELEVENLABS_API_KEY"]
195
+ # }
196
+ # data = {
197
+ # "text": text,
198
+ # "model_id": "eleven_monolingual_v1",
199
+ # "voice_settings": {
200
+ # "stability": 0.5,
201
+ # "similarity_boost": 0.5
202
+ # }
203
+ # }
204
+ # response = requests.post(url, json=data, headers=headers)
205
+ # audio_data = response.content
206
+
207
+ return audio_data
208
+ except Exception as e:
209
+ st.warning(f"Error generating voice response: {e}")
210
+ return None
pages/fund-monitoring.py ADDED
@@ -0,0 +1,334 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def render_fund_monitoring(transactions_df):
2
+ """
3
+ Render the AI-powered fund monitoring page.
4
+
5
+ This feature helps startups monitor spending, detect fraudulent transactions,
6
+ and maintain investor trust through AI-powered analysis.
7
+ """
8
+ st.markdown("<h1 class='main-header'>Investor Fund Monitoring</h1>", unsafe_allow_html=True)
9
+ st.markdown("<p class='sub-header'>AI-powered fraud detection and spending analysis</p>", unsafe_allow_html=True)
10
+
11
+ # How AI helps with fund monitoring
12
+ with st.expander("ℹ️ How AI enhances fund monitoring"):
13
+ st.markdown("""
14
+ ### How AI Powers Your Fund Monitoring
15
+
16
+ The fund monitoring system uses AI to help maintain investor trust and optimize spending:
17
+
18
+ - **Anomaly Detection**: Our AI models identify unusual transactions that don't match typical startup spending patterns
19
+ - **Risk Scoring**: Each transaction is assigned a risk score based on multiple factors like amount, category, vendor, and description
20
+ - **Pattern Recognition**: The system identifies potentially concerning spending trends across categories over time
21
+ - **Fraud Prevention**: AI algorithms flag transactions that match known patterns of misuse before they become issues
22
+ - **Investor-Ready Reporting**: Generate reports that demonstrate responsible financial stewardship to investors
23
+
24
+ This helps founders maintain investor trust, prevent misuse of funds, and create transparency in financial operations.
25
+ """)
26
+
27
+ st.write("Monitor your startup's spending to maintain investor trust and ensure proper fund usage. Our AI algorithms automatically flag suspicious transactions and identify spending patterns.")
28
+
29
+ # AI insights for fund monitoring
30
+ insights_key = f"fund_monitoring_{date.today().isoformat()}"
31
+ if insights_key not in st.session_state.insights_cache:
32
+ insights = generate_ai_response("""
33
+ You are a financial fraud detection expert. Provide 2-3 critical spending patterns that investors typically look for when monitoring startup fund usage.
34
+ Format as brief bullet points focused on maintaining investor trust.
35
+ """, simulate=True)
36
+ st.session_state.insights_cache[insights_key] = insights
37
+
38
+ with st.expander("🔍 AI Monitoring Insights", expanded=True):
39
+ st.markdown("<span class='ai-badge'>AI-Generated Insights</span>", unsafe_allow_html=True)
40
+ st.markdown(st.session_state.insights_cache[insights_key])
41
+
42
+ # Process transactions to detect suspicious ones with AI enhancement
43
+ processed_df = detect_suspicious_transactions(transactions_df)
44
+
45
+ # Summary metrics
46
+ total_transactions = len(processed_df)
47
+ suspicious_transactions = processed_df[processed_df['Suspicious']].copy()
48
+ suspicious_count = len(suspicious_transactions)
49
+ suspicious_amount = suspicious_transactions['Amount'].sum()
50
+ total_amount = processed_df['Amount'].sum()
51
+
52
+ col1, col2, col3, col4 = st.columns(4)
53
+
54
+ with col1:
55
+ st.markdown(f"""
56
+ <div class='metric-card'>
57
+ <p class='metric-label'>Total Transactions</p>
58
+ <p class='metric-value'>{total_transactions}</p>
59
+ </div>
60
+ """, unsafe_allow_html=True)
61
+
62
+ with col2:
63
+ flagged_percent = suspicious_count/total_transactions*100 if total_transactions > 0 else 0
64
+ status = "danger-metric" if flagged_percent > 10 else ("warning-metric" if flagged_percent > 5 else "good-metric")
65
+ st.markdown(f"""
66
+ <div class='metric-card'>
67
+ <p class='metric-label'>Flagged Transactions</p>
68
+ <p class='metric-value {status}'>{suspicious_count} ({flagged_percent:.1f}%)</p>
69
+ </div>
70
+ """, unsafe_allow_html=True)
71
+
72
+ with col3:
73
+ amount_percent = suspicious_amount/total_amount*100 if total_amount > 0 else 0
74
+ status = "danger-metric" if amount_percent > 15 else ("warning-metric" if amount_percent > 7 else "good-metric")
75
+ st.markdown(f"""
76
+ <div class='metric-card'>
77
+ <p class='metric-label'>Flagged Amount</p>
78
+ <p class='metric-value {status}'>${suspicious_amount:,.0f} ({amount_percent:.1f}%)</p>
79
+ </div>
80
+ """, unsafe_allow_html=True)
81
+
82
+ with col4:
83
+ avg_risk = suspicious_transactions['Risk_Score'].mean() if not suspicious_transactions.empty else 0
84
+ status = "danger-metric" if avg_risk > 50 else ("warning-metric" if avg_risk > 30 else "good-metric")
85
+ st.markdown(f"""
86
+ <div class='metric-card'>
87
+ <p class='metric-label'>Average Risk Score</p>
88
+ <p class='metric-value {status}'>{avg_risk:.1f}/100</p>
89
+ </div>
90
+ """, unsafe_allow_html=True)
91
+
92
+ # Tabs for different views
93
+ tab1, tab2 = st.tabs(["Flagged Transactions", "All Transactions"])
94
+
95
+ with tab1:
96
+ if suspicious_count > 0:
97
+ # Add risk score visualization (color coded)
98
+ suspicious_view = suspicious_transactions.copy()
99
+
100
+ # Format for display
101
+ def colorize_risk(val):
102
+ color = "red" if val > 50 else ("orange" if val > 30 else "blue")
103
+ return f'background-color: {color}; color: white; font-weight: bold'
104
+
105
+ # Apply styling
106
+ styled_suspicious = suspicious_view.style.applymap(
107
+ lambda x: colorize_risk(x) if x > 0 else '',
108
+ subset=['Risk_Score']
109
+ )
110
+
111
+ st.dataframe(
112
+ suspicious_view[['Date', 'Category', 'Vendor', 'Amount', 'Description', 'Risk_Score', 'Reason']],
113
+ use_container_width=True
114
+ )
115
+
116
+ # Get AI analysis of suspicious transactions
117
+ fraud_key = f"fraud_{date.today().isoformat()}"
118
+ if fraud_key not in st.session_state.insights_cache:
119
+ fraud_analysis = get_fraud_analysis(suspicious_transactions)
120
+ st.session_state.insights_cache[fraud_key] = fraud_analysis
121
+
122
+ st.markdown("<div class='advisor-card'>", unsafe_allow_html=True)
123
+ st.markdown("<span class='ai-badge'>AI Fraud Analysis</span>", unsafe_allow_html=True)
124
+ st.markdown(f"<p class='advice-text'>{st.session_state.insights_cache[fraud_key]}</p>", unsafe_allow_html=True)
125
+ st.markdown("</div>", unsafe_allow_html=True)
126
+
127
+ # Action buttons
128
+ st.subheader("Recommended Actions")
129
+
130
+ col1, col2, col3 = st.columns(3)
131
+ with col1:
132
+ if st.button("🔍 Investigate All Flagged"):
133
+ st.session_state.investigation_started = True
134
+ with col2:
135
+ if st.button("📝 Generate Investor Report"):
136
+ st.session_state.report_generated = True
137
+ with col3:
138
+ if st.button("✅ Mark Reviewed"):
139
+ st.session_state.marked_reviewed = True
140
+
141
+ # Simulate action responses
142
+ if 'investigation_started' in st.session_state and st.session_state.investigation_started:
143
+ st.success("Investigation initiated for all flagged transactions. Your financial team will be notified.")
144
+
145
+ if 'report_generated' in st.session_state and st.session_state.report_generated:
146
+ st.success("Investor report generated and ready for review before sending.")
147
+
148
+ if 'marked_reviewed' in st.session_state and st.session_state.marked_reviewed:
149
+ st.success("All transactions marked as reviewed. Status will be updated in the system.")
150
+ else:
151
+ st.success("No suspicious transactions detected by our AI system. Your spending appears to be normal for a startup at your stage.")
152
+
153
+ with tab2:
154
+ st.dataframe(processed_df[['Date', 'Category', 'Vendor', 'Amount', 'Description', 'Suspicious', 'Risk_Score']],
155
+ use_container_width=True)
156
+
157
+ # Spending patterns
158
+ st.subheader("Spending Pattern Analysis")
159
+
160
+ # Category breakdown
161
+ category_spending = processed_df.groupby('Category')['Amount'].sum().reset_index()
162
+
163
+ col1, col2 = st.columns(2)
164
+
165
+ with col1:
166
+ fig = px.bar(category_spending, x='Category', y='Amount',
167
+ title="Spending by Category",
168
+ labels={'Amount': 'Total Spent ($)'},
169
+ color='Amount',
170
+ color_continuous_scale='Blues')
171
+ fig.update_layout(
172
+ height=400,
173
+ plot_bgcolor='rgba(240,247,255,0.8)',
174
+ xaxis_title="Category",
175
+ yaxis_title="Amount Spent ($)",
176
+ font=dict(family="Arial, sans-serif", size=12),
177
+ margin=dict(l=20, r=20, t=40, b=20),
178
+ )
179
+ st.plotly_chart(fig, use_container_width=True)
180
+
181
+ with col2:
182
+ # AI spending pattern analysis
183
+ spending_key = f"spending_pattern_{date.today().isoformat()}"
184
+ if spending_key not in st.session_state.insights_cache:
185
+ spending_pattern_analysis = generate_ai_response("""
186
+ You are a startup spending analyst. Review the spending patterns and provide 3 key insights about:
187
+ 1. Categories that appear to have unusually high spending
188
+ 2. Potential areas where spending could be optimized
189
+ 3. Changes in spending patterns that investors might find concerning
190
+
191
+ Format as concise, actionable bullet points.
192
+ """, simulate=True)
193
+ st.session_state.insights_cache[spending_key] = spending_pattern_analysis
194
+
195
+ st.markdown("<div class='insight-card'>", unsafe_allow_html=True)
196
+ st.markdown("<span class='ai-badge'>AI Spending Analysis</span>", unsafe_allow_html=True)
197
+ st.markdown(st.session_state.insights_cache[spending_key])
198
+ st.markdown("</div>", unsafe_allow_html=True)
199
+
200
+ # Time series of spending
201
+ processed_df['Date'] = pd.to_datetime(processed_df['Date'])
202
+ processed_df['Week'] = processed_df['Date'].dt.isocalendar().week
203
+ weekly_spending = processed_df.groupby(['Week', 'Category'])['Amount'].sum().reset_index()
204
+
205
+ fig = px.line(weekly_spending, x='Week', y='Amount', color='Category',
206
+ title="Weekly Spending Trends",
207
+ labels={'Amount': 'Amount Spent ($)'},
208
+ color_discrete_sequence=px.colors.qualitative.Bold)
209
+ fig.update_layout(
210
+ height=400,
211
+ plot_bgcolor='rgba(240,247,255,0.8)',
212
+ xaxis_title="Week",
213
+ yaxis_title="Amount Spent ($)",
214
+ font=dict(family="Arial, sans-serif", size=12),
215
+ margin=dict(l=20, r=20, t=40, b=20),
216
+ )
217
+ st.plotly_chart(fig, use_container_width=True)
218
+
219
+ # AI-powered spending controls recommendation
220
+ st.subheader("AI-Recommended Spending Controls")
221
+
222
+ # Get AI recommendations for spending controls
223
+ controls_key = f"spending_controls_{date.today().isoformat()}"
224
+ if controls_key not in st.session_state.insights_cache:
225
+ controls_recommendations = generate_ai_response("""
226
+ You are a financial controls expert for startups. Based on the spending patterns and suspicious transactions,
227
+ recommend 3-4 specific spending controls that the startup should implement to prevent misuse of funds.
228
+
229
+ For each control, provide:
230
+ 1. A clear policy statement
231
+ 2. Implementation steps
232
+ 3. Expected impact
233
+
234
+ Format as concise, actionable recommendations.
235
+ """, simulate=True)
236
+ st.session_state.insights_cache[controls_key] = controls_recommendations
237
+
238
+ st.markdown("<div class='advisor-card'>", unsafe_allow_html=True)
239
+ st.markdown("<span class='ai-badge'>AI Control Recommendations</span>", unsafe_allow_html=True)
240
+ st.markdown(f"<p class='advice-text'>{st.session_state.insights_cache[controls_key]}</p>", unsafe_allow_html=True)
241
+ st.markdown("</div>", unsafe_allow_html=True)
242
+
243
+ # Call-to-action
244
+ st.info("📅 Need help implementing financial controls? [Book a session](#book-a-session) with our AI financial advisor.")
245
+
246
+ def detect_suspicious_transactions(transactions_df):
247
+ """AI-enhanced suspicious transaction detection."""
248
+ df = transactions_df.copy()
249
+
250
+ # Define thresholds for each category
251
+ category_thresholds = {
252
+ "Travel": 3000,
253
+ "Marketing": 10000,
254
+ "Office": 7000,
255
+ "Software": 6000,
256
+ "Consulting": 5000,
257
+ "Legal": 6000
258
+ }
259
+
260
+ # Define suspicious terms
261
+ suspicious_terms = ['luxury', 'cruise', 'premium', 'personal', 'gift']
262
+
263
+ # Add suspicious column
264
+ df['Suspicious'] = False
265
+ df['Reason'] = ""
266
+ df['Risk_Score'] = 0
267
+
268
+ # Check for suspicious patterns
269
+ for idx, row in df.iterrows():
270
+ reasons = []
271
+ risk_score = 0
272
+
273
+ # Check if amount exceeds category threshold
274
+ if row['Category'] in category_thresholds:
275
+ if row['Amount'] > category_thresholds[row['Category']]:
276
+ reasons.append(f"Amount exceeds typical spending for {row['Category']}")
277
+ risk_score += 30
278
+
279
+ # Higher risk for significantly exceeding threshold
280
+ excess_percentage = (row['Amount'] - category_thresholds[row['Category']]) / category_thresholds[row['Category']] * 100
281
+ if excess_percentage > 100: # More than double the threshold
282
+ risk_score += 20
283
+
284
+ # Check for suspicious vendors or descriptions
285
+ if any(term in str(row['Vendor']).lower() for term in suspicious_terms):
286
+ reasons.append(f"Vendor name contains suspicious term")
287
+ risk_score += 25
288
+
289
+ if any(term in str(row['Description']).lower() for term in suspicious_terms):
290
+ reasons.append(f"Description contains suspicious term")
291
+ risk_score += 20
292
+
293
+ # Check for rounded amounts (potential indicator of estimation/fabrication)
294
+ if row['Amount'] % 1000 == 0 and row['Amount'] > 3000:
295
+ reasons.append(f"Suspiciously round amount")
296
+ risk_score += 15
297
+
298
+ # Mark as suspicious if risk score is high enough
299
+ if risk_score >= 30:
300
+ df.at[idx, 'Suspicious'] = True
301
+ df.at[idx, 'Reason'] = "; ".join(reasons)
302
+ df.at[idx, 'Risk_Score'] = risk_score
303
+
304
+ # Sort by risk score
305
+ df = df.sort_values(by='Risk_Score', ascending=False)
306
+
307
+ return df
308
+
309
+ def get_fraud_analysis(transactions_df):
310
+ """Get AI analysis of potentially fraudulent transactions."""
311
+ suspicious_df = transactions_df[transactions_df['Suspicious']].copy()
312
+
313
+ if len(suspicious_df) == 0:
314
+ return "No suspicious transactions detected."
315
+
316
+ transactions_text = suspicious_df[['Date', 'Category', 'Vendor', 'Amount', 'Description', 'Risk_Score']].to_string(index=False)
317
+
318
+ prompt = f"""
319
+ You are a financial forensics expert specializing in startup spending oversight.
320
+ Review these flagged transactions:
321
+
322
+ {transactions_text}
323
+
324
+ Provide a detailed analysis:
325
+ 1. Identify the most concerning transactions and explain why
326
+ 2. Calculate the total financial impact of these suspicious transactions
327
+ 3. Identify spending patterns or potential policy violations
328
+ 4. Recommend specific actions the startup should take immediately
329
+ 5. Suggest controls to prevent similar issues in the future
330
+
331
+ Be specific about which transactions are most concerning and why investors would have questions.
332
+ """
333
+
334
+ return generate_ai_response(prompt)
pages/init-file.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ # This file can be empty, it just marks the directory as a Python package