File size: 10,333 Bytes
ad6169d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
# 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.