Spaces:
Running
Running
| # Dashboard Module Implementation | |
| ## Overview | |
| Complete, production-ready dashboard module for spa partner mobile app with performance optimizations including parallel queries, Redis caching, and efficient data aggregation. | |
| ## Features | |
| ### 1. Single Aggregated Endpoint | |
| - **GET `/api/v1/dashboard/summary`** - Returns all dashboard data in one request | |
| - Reduces network calls from 6+ to 1 | |
| - Minimizes mobile data usage and latency | |
| ### 2. Performance Optimizations | |
| #### Parallel Async Queries | |
| ```python | |
| # All queries run simultaneously using asyncio.gather() | |
| results = await asyncio.gather( | |
| _get_booking_stats(partner_id), | |
| _get_earnings_stats(partner_id), | |
| _get_rating_stats(partner_id), | |
| _get_upcoming_appointments(partner_id), | |
| _get_recent_ratings(partner_id), | |
| _get_special_offers(partner_id) | |
| ) | |
| ``` | |
| #### Redis Caching | |
| - 60-second TTL for dashboard data | |
| - Cache key: `dashboard:summary:{partner_id}` | |
| - Automatic cache invalidation on data changes | |
| - Cache warming utility for background jobs | |
| #### Database Optimizations | |
| - Single aggregated queries with conditional counts | |
| - Indexed fields (partner_id, status, created_at) | |
| - Limited result sets (5 upcoming, 5 recent) | |
| - No N+1 query problems | |
| ### 3. Data Included | |
| #### Booking Statistics | |
| - Total bookings count | |
| - Confirmed bookings | |
| - Completed bookings | |
| - Cancelled bookings | |
| - Pending bookings | |
| #### Earnings Statistics | |
| - Total lifetime earnings | |
| - Current month earnings | |
| - Pending payment amount | |
| - Wallet balance | |
| - Currency | |
| #### Rating Statistics | |
| - Average rating (1-5) | |
| - Total ratings count | |
| - Distribution (5-star, 4-star, etc.) | |
| #### Upcoming Appointments | |
| - Next 5 appointments | |
| - Order details | |
| - Customer info (when available) | |
| - Scheduled time | |
| - Amount and status | |
| #### Recent Ratings | |
| - Last 5 ratings | |
| - Customer name | |
| - Rating value and comment | |
| - Timestamp | |
| #### Special Offers | |
| - Active offers for partner | |
| - Discount details | |
| - Validity period | |
| ## API Endpoints | |
| ### 1. Get Dashboard Summary | |
| ```http | |
| GET /api/v1/dashboard/summary | |
| Authorization: Bearer <jwt_token> | |
| ``` | |
| **Response:** | |
| ```json | |
| { | |
| "bookings": { | |
| "total_bookings": 150, | |
| "confirmed_bookings": 45, | |
| "completed_bookings": 95, | |
| "cancelled_bookings": 8, | |
| "pending_bookings": 2 | |
| }, | |
| "earnings": { | |
| "total_earnings": "125000.00", | |
| "current_month_earnings": "15000.00", | |
| "pending_amount": "2500.00", | |
| "wallet_balance": "8500.00", | |
| "currency": "INR" | |
| }, | |
| "ratings": { | |
| "average_rating": 4.5, | |
| "total_ratings": 120, | |
| "five_star": 80, | |
| "four_star": 30, | |
| "three_star": 8, | |
| "two_star": 2, | |
| "one_star": 0 | |
| }, | |
| "upcoming_appointments": [ | |
| { | |
| "order_id": "uuid", | |
| "order_number": "SPA-2024-12345", | |
| "customer_name": "John Doe", | |
| "service_name": "Massage Therapy", | |
| "scheduled_time": "2024-01-20T14:00:00", | |
| "amount": "2500.00", | |
| "status": "approved" | |
| } | |
| ], | |
| "recent_ratings": [ | |
| { | |
| "rating_id": "uuid", | |
| "customer_name": "Jane Smith", | |
| "rating": 5, | |
| "comment": "Excellent service!", | |
| "created_at": "2024-01-15T10:30:00" | |
| } | |
| ], | |
| "special_offers": [], | |
| "last_updated": "2024-01-15T10:30:00" | |
| } | |
| ``` | |
| ### 2. Refresh Dashboard Cache | |
| ```http | |
| POST /api/v1/dashboard/refresh | |
| Authorization: Bearer <jwt_token> | |
| ``` | |
| Forces cache invalidation for fresh data. | |
| ### 3. Get Booking Stats Only | |
| ```http | |
| GET /api/v1/dashboard/bookings/stats | |
| Authorization: Bearer <jwt_token> | |
| ``` | |
| Lighter endpoint for specific use cases. | |
| ### 4. Get Earnings Stats Only | |
| ```http | |
| GET /api/v1/dashboard/earnings/stats | |
| Authorization: Bearer <jwt_token> | |
| ``` | |
| Lighter endpoint for specific use cases. | |
| ## Mobile App Integration | |
| ### Best Practices | |
| #### 1. Client-Side Caching | |
| ```javascript | |
| // Cache dashboard data locally | |
| const CACHE_DURATION = 30000; // 30 seconds | |
| async function getDashboard() { | |
| const cached = await AsyncStorage.getItem('dashboard'); | |
| const cacheTime = await AsyncStorage.getItem('dashboard_time'); | |
| if (cached && Date.now() - cacheTime < CACHE_DURATION) { | |
| return JSON.parse(cached); | |
| } | |
| const fresh = await api.get('/dashboard/summary'); | |
| await AsyncStorage.setItem('dashboard', JSON.stringify(fresh)); | |
| await AsyncStorage.setItem('dashboard_time', Date.now().toString()); | |
| return fresh; | |
| } | |
| ``` | |
| #### 2. Progressive Loading | |
| ```javascript | |
| // Show skeleton while loading | |
| <DashboardSkeleton /> | |
| // Load data | |
| const data = await getDashboard(); | |
| // Render actual content | |
| <DashboardContent data={data} /> | |
| ``` | |
| #### 3. Optimistic Updates | |
| ```javascript | |
| // After creating order, update local cache | |
| async function createOrder(orderData) { | |
| const result = await api.post('/orders', orderData); | |
| // Update dashboard cache optimistically | |
| const dashboard = await AsyncStorage.getItem('dashboard'); | |
| if (dashboard) { | |
| const data = JSON.parse(dashboard); | |
| data.bookings.total_bookings += 1; | |
| data.bookings.pending_bookings += 1; | |
| await AsyncStorage.setItem('dashboard', JSON.stringify(data)); | |
| } | |
| // Invalidate server cache for next fetch | |
| await api.post('/dashboard/refresh'); | |
| return result; | |
| } | |
| ``` | |
| #### 4. Pull-to-Refresh | |
| ```javascript | |
| const onRefresh = async () => { | |
| setRefreshing(true); | |
| // Invalidate server cache | |
| await api.post('/dashboard/refresh'); | |
| // Clear local cache | |
| await AsyncStorage.removeItem('dashboard'); | |
| // Fetch fresh data | |
| const fresh = await getDashboard(); | |
| setData(fresh); | |
| setRefreshing(false); | |
| }; | |
| ``` | |
| ## Cache Invalidation Strategy | |
| ### Automatic Invalidation | |
| Call `invalidate_dashboard_cache(partner_id)` after: | |
| - New order created | |
| - Order status changed | |
| - Payment received | |
| - Rating submitted | |
| - Offer activated/deactivated | |
| ### Example Integration | |
| ```python | |
| # In order service after creating order | |
| from app.dashboard.utils import invalidate_dashboard_cache | |
| async def create_order(partner_id: str, order_data: dict): | |
| # Create order | |
| order = await _create_order_logic(partner_id, order_data) | |
| # Invalidate dashboard cache | |
| await invalidate_dashboard_cache(partner_id) | |
| return order | |
| ``` | |
| ## Performance Metrics | |
| ### Expected Response Times | |
| - **Cache Hit**: 10-20ms | |
| - **Cache Miss**: 100-200ms (parallel queries) | |
| - **Network Transfer**: ~2-5KB (compressed) | |
| ### Database Query Optimization | |
| - Booking stats: 1 query with aggregation | |
| - Earnings stats: 2 queries (orders + wallet) | |
| - Upcoming appointments: 1 query with limit | |
| - Total: ~4 queries running in parallel | |
| ### Caching Benefits | |
| - 95%+ cache hit rate expected | |
| - 80-90% reduction in database load | |
| - 5-10x faster response times | |
| ## Future Enhancements | |
| ### 1. Rating System Integration | |
| When rating tables are created: | |
| - Update `_get_rating_stats()` to query actual ratings | |
| - Update `_get_recent_ratings()` to fetch real data | |
| - Add rating distribution calculation | |
| ### 2. Offers/Promotions Integration | |
| When offers tables are created: | |
| - Update `_get_special_offers()` to query active offers | |
| - Add offer expiry tracking | |
| - Include offer usage statistics | |
| ### 3. Advanced Analytics | |
| - Earnings trends (daily/weekly/monthly) | |
| - Booking patterns and forecasting | |
| - Customer retention metrics | |
| - Service popularity analysis | |
| ### 4. Real-Time Updates | |
| - WebSocket support for live updates | |
| - Push notifications for new bookings | |
| - Real-time earnings counter | |
| ### 5. Materialized Views | |
| For very high traffic: | |
| ```sql | |
| CREATE MATERIALIZED VIEW trans.partner_dashboard_stats AS | |
| SELECT | |
| partner_id, | |
| COUNT(*) as total_bookings, | |
| SUM(CASE WHEN order_status = 'delivered' THEN net_amount ELSE 0 END) as total_earnings, | |
| -- ... other aggregations | |
| FROM trans.spa_partner_orders | |
| GROUP BY partner_id; | |
| -- Refresh periodically | |
| REFRESH MATERIALIZED VIEW CONCURRENTLY trans.partner_dashboard_stats; | |
| ``` | |
| ## Testing | |
| ### Manual Testing | |
| ```bash | |
| # Get dashboard summary | |
| curl -X GET http://localhost:8000/api/v1/dashboard/summary \ | |
| -H "Authorization: Bearer <token>" | |
| # Refresh cache | |
| curl -X POST http://localhost:8000/api/v1/dashboard/refresh \ | |
| -H "Authorization: Bearer <token>" | |
| # Get specific stats | |
| curl -X GET http://localhost:8000/api/v1/dashboard/bookings/stats \ | |
| -H "Authorization: Bearer <token>" | |
| ``` | |
| ### Load Testing | |
| ```bash | |
| # Using Apache Bench | |
| ab -n 1000 -c 10 -H "Authorization: Bearer <token>" \ | |
| http://localhost:8000/api/v1/dashboard/summary | |
| # Expected results with caching: | |
| # - Requests per second: 500-1000+ | |
| # - Mean response time: 10-20ms | |
| # - 99th percentile: <50ms | |
| ``` | |
| ## Monitoring | |
| ### Key Metrics to Track | |
| - Cache hit rate (target: >95%) | |
| - Response time (target: <100ms p95) | |
| - Error rate (target: <0.1%) | |
| - Database query time | |
| - Redis latency | |
| ### Logging | |
| All operations are logged with structured logging: | |
| ```python | |
| logger.info("Dashboard cache hit", extra={"partner_id": partner_id}) | |
| logger.warning("Cache read failed", exc_info=cache_error) | |
| logger.error("Error getting dashboard summary", exc_info=e) | |
| ``` | |
| ## Security | |
| ### Authentication | |
| - JWT token required for all endpoints | |
| - Partner ID extracted from token | |
| - No cross-partner data access | |
| ### Data Privacy | |
| - Each partner sees only their own data | |
| - Wallet balance encrypted at rest | |
| - No PII in cache keys | |
| ## Deployment Checklist | |
| - [ ] Redis server configured and running | |
| - [ ] Database indexes created (partner_id, status, created_at) | |
| - [ ] Environment variables set (REDIS_URL, etc.) | |
| - [ ] Cache TTL configured appropriately | |
| - [ ] Monitoring and alerting set up | |
| - [ ] Load testing completed | |
| - [ ] Documentation reviewed | |
| - [ ] Mobile app integration tested | |
| ## File Structure | |
| ``` | |
| app/dashboard/ | |
| βββ __init__.py | |
| βββ controllers/ | |
| β βββ __init__.py | |
| β βββ router.py # API endpoints with caching | |
| βββ services/ | |
| β βββ __init__.py | |
| β βββ service.py # Business logic with parallel queries | |
| βββ schemas/ | |
| β βββ __init__.py | |
| β βββ schema.py # Pydantic models | |
| βββ utils.py # Cache utilities | |
| ``` | |
| ## Summary | |
| The dashboard module provides a complete, production-ready solution for mobile app dashboards with: | |
| - Single aggregated endpoint reducing network calls | |
| - Parallel async queries for fast response | |
| - Redis caching with 60s TTL | |
| - Automatic cache invalidation | |
| - Comprehensive metrics and statistics | |
| - Mobile-optimized data transfer | |
| - Extensible architecture for future features | |
| Expected performance: <100ms response time with 95%+ cache hit rate. | |