cuatrolabs-spa-ms / DASHBOARD_INTEGRATION_EXAMPLE.md
MukeshKapoor25's picture
feat(dashboard): implement 3-tier caching architecture for mobile performance
fd7ec1d
# Dashboard Integration Examples
## Quick Integration Guide
This document shows exactly how to integrate dashboard updates in your existing code.
## 1. Order Service Integration
### Update `app/orders/services/service.py`
```python
# Add import at the top
from app.dashboard.utils import update_on_order_created, update_on_order_status_changed
# In create_order method, after order is created:
@staticmethod
async def create_order(partner_id: str, order_data: OrderCreateRequest):
try:
# ... existing order creation code ...
# After successful order creation
order = SpaPartnerOrder(...)
session.add(order)
await session.commit()
# βœ… ADD THIS: Update dashboard
await update_on_order_created(partner_id)
return {
"success": True,
"message": "Order created successfully",
"order": OrderResponse.model_validate(order_with_items)
}
except Exception as e:
logger.error("Error creating order", exc_info=e)
return {"success": False, "message": str(e)}
```
### Update Order Status
```python
# In update_order_status method:
@staticmethod
async def update_order_status(order_id: UUID, new_status: str):
try:
# ... existing status update code ...
order.order_status = new_status
await session.commit()
# βœ… ADD THIS: Update dashboard
await update_on_order_status_changed(order.partner_id)
return {"success": True, "order": order}
except Exception as e:
logger.error("Error updating order status", exc_info=e)
return {"success": False}
```
## 2. Wallet Service Integration
### Update `app/wallet/services/service.py`
```python
# Add import at the top
from app.dashboard.utils import update_on_wallet_transaction, update_on_payment_received
# In create_transaction method:
@staticmethod
async def create_transaction(
partner_id: str,
amount: Decimal,
transaction_type: str,
reference_type: Optional[str] = None,
reference_id: Optional[str] = None,
description: Optional[str] = None
):
try:
# ... existing transaction creation code ...
transaction = SpaWalletTransaction(...)
session.add(transaction)
await session.commit()
# βœ… ADD THIS: Update dashboard
await update_on_wallet_transaction(partner_id)
return {"success": True, "transaction": transaction}
except Exception as e:
logger.error("Error creating transaction", exc_info=e)
return {"success": False}
```
### Payment Processing
```python
# In process_payment method:
@staticmethod
async def process_payment(order_id: UUID, payment_data: dict):
try:
# ... existing payment processing code ...
# Update order payment status
order.payment_status = "paid"
await session.commit()
# βœ… ADD THIS: Update dashboard
await update_on_payment_received(order.partner_id)
return {"success": True, "payment": payment}
except Exception as e:
logger.error("Error processing payment", exc_info=e)
return {"success": False}
```
## 3. Leave/Booking Service Integration
### Update `app/leave/services/service.py`
```python
# Add import at the top
from app.dashboard.utils import update_dashboard_on_transaction
# In create_leave method:
@staticmethod
async def create_leave(partner_id: str, leave_data: dict):
try:
# ... existing leave creation code ...
leave = SpaPartnerLeave(...)
session.add(leave)
await session.commit()
# βœ… ADD THIS: Update dashboard
await update_dashboard_on_transaction(partner_id, "booking_created")
return {"success": True, "leave": leave}
except Exception as e:
logger.error("Error creating leave", exc_info=e)
return {"success": False}
```
### Update Leave Status
```python
# In update_leave_status method:
@staticmethod
async def update_leave_status(leave_id: UUID, new_status: str):
try:
# ... existing status update code ...
leave.status = new_status
await session.commit()
# βœ… ADD THIS: Update dashboard
await update_dashboard_on_transaction(leave.partner_id, "booking_updated")
return {"success": True, "leave": leave}
except Exception as e:
logger.error("Error updating leave status", exc_info=e)
return {"success": False}
```
## 4. Rating Service Integration (Future)
### When rating tables are created:
```python
# In app/ratings/services/service.py
from app.dashboard.utils import update_on_rating_submitted
@staticmethod
async def submit_rating(partner_id: str, rating_data: dict):
try:
# ... rating creation code ...
rating = PartnerRating(...)
session.add(rating)
await session.commit()
# βœ… ADD THIS: Update dashboard
await update_on_rating_submitted(partner_id)
return {"success": True, "rating": rating}
except Exception as e:
logger.error("Error submitting rating", exc_info=e)
return {"success": False}
```
## 5. Background Job for Bulk Refresh
### Create `app/jobs/dashboard_refresh.py`
```python
"""
Background job to refresh stale dashboard summaries.
Run this periodically (e.g., every 10 minutes).
"""
import asyncio
from insightfy_utils.logging import get_logger
from app.dashboard.services.mongo_persistence import dashboard_mongo
from app.dashboard.utils import bulk_update_dashboards
logger = get_logger(__name__)
async def refresh_stale_dashboards():
"""Refresh dashboards that haven't been updated in 10 minutes"""
try:
# Get stale partner IDs
stale_ids = await dashboard_mongo.get_stale_summaries(minutes=10)
if not stale_ids:
logger.info("No stale dashboards found")
return
logger.info(f"Found {len(stale_ids)} stale dashboards, refreshing...")
# Bulk update
results = await bulk_update_dashboards(stale_ids, "scheduled_refresh")
logger.info(
"Dashboard refresh completed",
extra={
"total": results["total"],
"success": results["success"],
"failed": results["failed"]
}
)
except Exception as e:
logger.error("Error in dashboard refresh job", exc_info=e)
if __name__ == "__main__":
# For testing
asyncio.run(refresh_stale_dashboards())
```
### Schedule with Cron
```bash
# Add to crontab
# Refresh stale dashboards every 10 minutes
*/10 * * * * cd /path/to/app && python -m app.jobs.dashboard_refresh
```
### Or use APScheduler
```python
# In app/main.py
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from app.jobs.dashboard_refresh import refresh_stale_dashboards
scheduler = AsyncIOScheduler()
@app.on_event("startup")
async def startup_event():
# ... existing startup code ...
# Schedule dashboard refresh every 10 minutes
scheduler.add_job(
refresh_stale_dashboards,
'interval',
minutes=10,
id='dashboard_refresh'
)
scheduler.start()
logger.info("Dashboard refresh job scheduled")
@app.on_event("shutdown")
async def shutdown_event():
# ... existing shutdown code ...
scheduler.shutdown()
```
## 6. Testing Integration
### Test Dashboard Update
```python
# test_dashboard_integration.py
import asyncio
from app.dashboard.utils import update_on_order_created
from app.dashboard.services.mongo_persistence import dashboard_mongo
from app.sql import connect_to_database
from app.nosql import connect_to_mongo
async def test_integration():
# Initialize connections
await connect_to_database()
await connect_to_mongo()
test_partner_id = "PARTNER001"
# Simulate order creation
print(f"Updating dashboard for {test_partner_id}...")
success = await update_on_order_created(test_partner_id)
if success:
print("βœ… Dashboard updated successfully")
# Verify in MongoDB
doc = await dashboard_mongo.get_summary(test_partner_id)
if doc:
print(f"βœ… Found in MongoDB: {doc['summary']['bookings']['total_bookings']} bookings")
else:
print("❌ Not found in MongoDB")
else:
print("❌ Dashboard update failed")
if __name__ == "__main__":
asyncio.run(test_integration())
```
## 7. Error Handling Best Practices
### Always Wrap Dashboard Updates
```python
# βœ… Good - Dashboard update failure doesn't break main operation
async def create_order(partner_id: str, order_data: dict):
try:
# Create order
order = await _create_order_logic(partner_id, order_data)
# Update dashboard (non-blocking)
try:
await update_on_order_created(partner_id)
except Exception as e:
logger.error("Dashboard update failed", exc_info=e)
# Continue - order was created successfully
return {"success": True, "order": order}
except Exception as e:
logger.error("Order creation failed", exc_info=e)
return {"success": False, "message": str(e)}
```
### Use Fire-and-Forget for Non-Critical Updates
```python
# For non-critical updates, use background task
from fastapi import BackgroundTasks
@router.post("/orders")
async def create_order(
order_data: OrderCreateRequest,
background_tasks: BackgroundTasks,
token_data: dict = Depends(verify_token)
):
partner_id = token_data["partner_id"]
# Create order
result = await order_service.create_order(partner_id, order_data)
# Update dashboard in background
background_tasks.add_task(update_on_order_created, partner_id)
return result
```
## 8. Monitoring Integration
### Add Metrics
```python
# In app/dashboard/utils.py
from prometheus_client import Counter, Histogram
dashboard_updates = Counter(
'dashboard_updates_total',
'Total dashboard updates',
['transaction_type', 'status']
)
dashboard_update_duration = Histogram(
'dashboard_update_duration_seconds',
'Dashboard update duration',
['transaction_type']
)
async def update_dashboard_on_transaction(
partner_id: str,
transaction_type: str = "transaction"
) -> bool:
with dashboard_update_duration.labels(transaction_type).time():
try:
# ... existing code ...
dashboard_updates.labels(
transaction_type=transaction_type,
status='success'
).inc()
return True
except Exception as e:
dashboard_updates.labels(
transaction_type=transaction_type,
status='failed'
).inc()
raise
```
## Summary
### Integration Checklist
- [ ] Add dashboard update to order creation
- [ ] Add dashboard update to order status changes
- [ ] Add dashboard update to wallet transactions
- [ ] Add dashboard update to payment processing
- [ ] Add dashboard update to booking/leave operations
- [ ] Set up background job for stale refresh
- [ ] Add error handling around updates
- [ ] Add monitoring/metrics
- [ ] Test integration with sample data
- [ ] Deploy and monitor
### Key Points
1. **Always call update functions** after transactions
2. **Use specific functions** (update_on_order_created, etc.)
3. **Handle errors gracefully** - don't break main operations
4. **Use background tasks** for non-critical updates
5. **Monitor update success rate** with metrics
6. **Schedule bulk refresh** for stale data
### Performance Impact
- Dashboard update: ~50-100ms
- Non-blocking: Use background tasks
- Minimal overhead: Only updates MongoDB
- Redis populated on next API request