Spaces:
Sleeping
Sleeping
| """ | |
| Dashboard utility functions for cache management and updates. | |
| Call these functions when transactions/bookings/wallet changes occur. | |
| """ | |
| from insightfy_utils.logging import get_logger | |
| from app.cache import get_redis | |
| logger = get_logger(__name__) | |
| async def update_dashboard_on_transaction( | |
| partner_id: str, | |
| transaction_type: str = "transaction" | |
| ) -> bool: | |
| """ | |
| Update dashboard summary when a transaction occurs. | |
| This is the main function to call after order/wallet/booking changes. | |
| Flow: | |
| 1. Invalidate Redis cache | |
| 2. Fetch fresh data from database | |
| 3. Update MongoDB spa_dashboard_summary collection | |
| 4. Redis will be populated from MongoDB on next API request | |
| Args: | |
| partner_id: Partner ID | |
| transaction_type: Type of transaction (order, wallet, booking, etc.) | |
| Returns: | |
| bool: True if successful | |
| Usage: | |
| # After creating order | |
| await update_dashboard_on_transaction(partner_id, "order_created") | |
| # After wallet transaction | |
| await update_dashboard_on_transaction(partner_id, "wallet_transaction") | |
| # After booking update | |
| await update_dashboard_on_transaction(partner_id, "booking_updated") | |
| """ | |
| try: | |
| # Step 1: Invalidate Redis cache | |
| await invalidate_redis_cache(partner_id) | |
| # Step 2 & 3: Fetch from database and update MongoDB | |
| from app.dashboard.services.mongo_persistence import dashboard_mongo | |
| from app.dashboard.services.service import DashboardService | |
| # Fetch fresh data | |
| summary = await DashboardService._fetch_from_database(partner_id) | |
| # Update MongoDB | |
| summary_data = summary.model_dump(mode='json') | |
| success = await dashboard_mongo.upsert_summary( | |
| partner_id, | |
| summary_data, | |
| transaction_type=transaction_type | |
| ) | |
| if success: | |
| logger.info( | |
| "Dashboard updated on transaction", | |
| extra={ | |
| "partner_id": partner_id, | |
| "transaction_type": transaction_type | |
| } | |
| ) | |
| return success | |
| except Exception as e: | |
| logger.error( | |
| "Error updating dashboard on transaction", | |
| exc_info=e, | |
| extra={ | |
| "partner_id": partner_id, | |
| "transaction_type": transaction_type | |
| } | |
| ) | |
| return False | |
| async def invalidate_redis_cache(partner_id: str) -> bool: | |
| """ | |
| Invalidate Redis cache for a specific partner. | |
| Args: | |
| partner_id: Partner ID | |
| Returns: | |
| bool: True if cache was invalidated | |
| """ | |
| try: | |
| redis_client = get_redis() | |
| if not redis_client: | |
| logger.warning("Redis client not available") | |
| return False | |
| cache_key = f"dashboard:summary:{partner_id}" | |
| deleted = await redis_client.delete(cache_key) | |
| if deleted: | |
| logger.debug( | |
| "Redis cache invalidated", | |
| extra={"partner_id": partner_id} | |
| ) | |
| return bool(deleted) | |
| except Exception as e: | |
| logger.error( | |
| "Error invalidating Redis cache", | |
| exc_info=e, | |
| extra={"partner_id": partner_id} | |
| ) | |
| return False | |
| async def invalidate_mongo_cache(partner_id: str) -> bool: | |
| """ | |
| Delete dashboard summary from MongoDB. | |
| Use this only when you want to completely remove cached data. | |
| Args: | |
| partner_id: Partner ID | |
| Returns: | |
| bool: True if deleted | |
| """ | |
| try: | |
| from app.dashboard.services.mongo_persistence import dashboard_mongo | |
| success = await dashboard_mongo.delete_summary(partner_id) | |
| if success: | |
| logger.info( | |
| "MongoDB cache deleted", | |
| extra={"partner_id": partner_id} | |
| ) | |
| return success | |
| except Exception as e: | |
| logger.error( | |
| "Error deleting MongoDB cache", | |
| exc_info=e, | |
| extra={"partner_id": partner_id} | |
| ) | |
| return False | |
| async def invalidate_all_caches(partner_id: str) -> bool: | |
| """ | |
| Invalidate both Redis and MongoDB caches. | |
| Args: | |
| partner_id: Partner ID | |
| Returns: | |
| bool: True if both were invalidated | |
| """ | |
| try: | |
| redis_result = await invalidate_redis_cache(partner_id) | |
| mongo_result = await invalidate_mongo_cache(partner_id) | |
| return redis_result and mongo_result | |
| except Exception as e: | |
| logger.error( | |
| "Error invalidating all caches", | |
| exc_info=e, | |
| extra={"partner_id": partner_id} | |
| ) | |
| return False | |
| async def bulk_update_dashboards( | |
| partner_ids: list[str], | |
| transaction_type: str = "bulk_update" | |
| ) -> dict: | |
| """ | |
| Bulk update dashboard summaries for multiple partners. | |
| Useful for batch operations or background jobs. | |
| Args: | |
| partner_ids: List of partner IDs | |
| transaction_type: Type of transaction | |
| Returns: | |
| dict: Results with success/failure counts | |
| """ | |
| results = { | |
| "total": len(partner_ids), | |
| "success": 0, | |
| "failed": 0, | |
| "errors": [] | |
| } | |
| for partner_id in partner_ids: | |
| try: | |
| success = await update_dashboard_on_transaction( | |
| partner_id, | |
| transaction_type | |
| ) | |
| if success: | |
| results["success"] += 1 | |
| else: | |
| results["failed"] += 1 | |
| except Exception as e: | |
| results["failed"] += 1 | |
| results["errors"].append({ | |
| "partner_id": partner_id, | |
| "error": str(e) | |
| }) | |
| logger.info( | |
| "Bulk dashboard update completed", | |
| extra=results | |
| ) | |
| return results | |
| # Convenience functions for specific transaction types | |
| async def update_on_order_created(partner_id: str) -> bool: | |
| """Update dashboard when order is created""" | |
| return await update_dashboard_on_transaction(partner_id, "order_created") | |
| async def update_on_order_status_changed(partner_id: str) -> bool: | |
| """Update dashboard when order status changes""" | |
| return await update_dashboard_on_transaction(partner_id, "order_status_changed") | |
| async def update_on_wallet_transaction(partner_id: str) -> bool: | |
| """Update dashboard when wallet transaction occurs""" | |
| return await update_dashboard_on_transaction(partner_id, "wallet_transaction") | |
| async def update_on_payment_received(partner_id: str) -> bool: | |
| """Update dashboard when payment is received""" | |
| return await update_dashboard_on_transaction(partner_id, "payment_received") | |
| async def update_on_rating_submitted(partner_id: str) -> bool: | |
| """Update dashboard when rating is submitted""" | |
| return await update_dashboard_on_transaction(partner_id, "rating_submitted") | |