06/05 Optimize app

This commit is contained in:
2026-06-05 15:51:57 -04:00
parent 458044201e
commit 025f3f8823
14 changed files with 425 additions and 64 deletions
+93
View File
@@ -323,6 +323,99 @@ def update_prices(investment_ids=None):
return updated
def check_and_save_price_alerts(threshold: float = 5.0) -> int:
"""
Fetch today's day-change for every unique ticker that has an active holding.
For any ticker where |day_change_pct| >= threshold, write an AiInsight row
with insight_type='alert' so the investments page can surface a banner.
Deduplicates by ticker so each ticker's Groq/Yahoo call happens only once.
Returns the number of alerts saved.
"""
import json
from app.models.ai_insight import AiInsight
today = datetime.utcnow().date()
investments = Investment.query.filter(
Investment.ticker != None,
Investment.ticker != '',
Investment.is_active == True,
).all()
if not investments:
return 0
# Collect unique tickers and their holding names
ticker_map = {} # ticker → asset_name (first one found)
for inv in investments:
t = inv.ticker.upper()
if t not in ticker_map:
ticker_map[t] = inv.asset_name
alerts = []
for ticker, asset_name in ticker_map.items():
try:
change = fetch_day_change(ticker)
except Exception:
continue
if not change:
continue
pct = change.get('day_change_pct') or 0
if abs(pct) >= threshold:
alerts.append({
'ticker': ticker,
'asset_name': asset_name,
'day_change_pct': round(pct, 2),
'current_price': change.get('current'),
})
if not alerts:
return 0
# Upsert: overwrite any earlier alert from today
existing = AiInsight.query.filter_by(
insight_date=today, insight_type='alert'
).first()
content_json = json.dumps(alerts)
if existing:
existing.content = content_json
else:
db.session.add(AiInsight(
insight_date=today,
insight_type='alert',
content=content_json,
prompt_summary=f'price_alert threshold={threshold}%',
))
try:
db.session.commit()
log.info('[investment] saved %d price alert(s) (threshold=%.1f%%)', len(alerts), threshold)
except Exception as e:
db.session.rollback()
log.error('[investment] failed to save price alerts: %s', e)
return len(alerts)
def get_price_alerts():
"""
Return today's price alert list (from ai_insights) or [] if none exist.
Each item: {ticker, asset_name, day_change_pct, current_price}
"""
import json
from app.models.ai_insight import AiInsight
today = datetime.utcnow().date()
row = AiInsight.query.filter_by(insight_date=today, insight_type='alert').first()
if not row:
return []
try:
return json.loads(row.content)
except Exception:
return []
def get_portfolio_summary():
"""
Return portfolio-level aggregates across all active investments.