Add cache source tracking (L1/L2) for Telegram bot responses
Implements cache tier identification in Telegram bot to display data source: - "db" for database queries - "cached L1" for in-memory cache hits - "cached L2" for SQLite cache hits Backend changes: - Added cache metadata fields to TrendsResponse and DashboardSummary models (cache_hit, response_time_ms, cache_source) - Updated /api/dashboard/summary and /api/dashboard/trends endpoints to include cache metadata when X-Include-Cache-Metadata header is present - Cache metadata is extracted from request.state (set by @cached decorator) Telegram bot changes: - Updated API client to send X-Include-Cache-Metadata header - Modified helpers to extract cache_source from backend responses - Updated handlers to pass cache metadata to formatters - Performance footer now displays specific cache tier (L1 vs L2) Fixed Pydantic serialization issue: - Changed field names from _cache_hit to cache_hit (without underscore) - Pydantic excludes underscore-prefixed fields from JSON by default 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -344,7 +344,7 @@ async def get_treasury_breakdown_split(
|
||||
for item in banca_data.get('items', [])
|
||||
]
|
||||
|
||||
return {
|
||||
result = {
|
||||
'casa': {
|
||||
'accounts': casa_accounts,
|
||||
'total': float(casa_data.get('total', 0))
|
||||
@@ -355,6 +355,16 @@ async def get_treasury_breakdown_split(
|
||||
}
|
||||
}
|
||||
|
||||
# Pass through cache metadata if present
|
||||
if 'cache_hit' in breakdown:
|
||||
result['cache_hit'] = breakdown['cache_hit']
|
||||
if 'response_time_ms' in breakdown:
|
||||
result['response_time_ms'] = breakdown['response_time_ms']
|
||||
if 'cache_source' in breakdown:
|
||||
result['cache_source'] = breakdown['cache_source']
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting treasury breakdown split: {e}", exc_info=True)
|
||||
return None
|
||||
@@ -425,7 +435,7 @@ async def get_clients_with_maturity(
|
||||
overdue = sum(c['balance'] for c in clients if c.get('daysOverdue', 0) > 0)
|
||||
in_term = total - overdue
|
||||
|
||||
return {
|
||||
result = {
|
||||
'clients': clients,
|
||||
'maturity': {
|
||||
'in_term': in_term,
|
||||
@@ -434,6 +444,16 @@ async def get_clients_with_maturity(
|
||||
}
|
||||
}
|
||||
|
||||
# Pass through cache metadata if present
|
||||
if 'cache_hit' in maturity_response:
|
||||
result['cache_hit'] = maturity_response['cache_hit']
|
||||
if 'response_time_ms' in maturity_response:
|
||||
result['response_time_ms'] = maturity_response['response_time_ms']
|
||||
if 'cache_source' in maturity_response:
|
||||
result['cache_source'] = maturity_response['cache_source']
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting clients with maturity: {e}", exc_info=True)
|
||||
return None
|
||||
@@ -504,7 +524,7 @@ async def get_suppliers_with_maturity(
|
||||
overdue = sum(s['balance'] for s in suppliers if s.get('daysOverdue', 0) > 0)
|
||||
in_term = total - overdue
|
||||
|
||||
return {
|
||||
result = {
|
||||
'suppliers': suppliers,
|
||||
'maturity': {
|
||||
'in_term': in_term,
|
||||
@@ -513,6 +533,16 @@ async def get_suppliers_with_maturity(
|
||||
}
|
||||
}
|
||||
|
||||
# Pass through cache metadata if present
|
||||
if 'cache_hit' in maturity_response:
|
||||
result['cache_hit'] = maturity_response['cache_hit']
|
||||
if 'response_time_ms' in maturity_response:
|
||||
result['response_time_ms'] = maturity_response['response_time_ms']
|
||||
if 'cache_source' in maturity_response:
|
||||
result['cache_source'] = maturity_response['cache_source']
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting suppliers with maturity: {e}", exc_info=True)
|
||||
return None
|
||||
@@ -650,11 +680,21 @@ async def get_cashflow_evolution_data(
|
||||
'plati_prev': last_12_plati_prev
|
||||
}
|
||||
|
||||
return {
|
||||
result = {
|
||||
'performance': performance,
|
||||
'monthly': monthly
|
||||
}
|
||||
|
||||
# Pass through cache metadata if present
|
||||
if 'cache_hit' in trends_data:
|
||||
result['cache_hit'] = trends_data['cache_hit']
|
||||
if 'response_time_ms' in trends_data:
|
||||
result['response_time_ms'] = trends_data['response_time_ms']
|
||||
if 'cache_source' in trends_data:
|
||||
result['cache_source'] = trends_data['cache_source']
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting cashflow evolution data: {e}", exc_info=True)
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user