veza/veza-backend-api/docs/DASHBOARD_ENDPOINT_CONTRACT.md
senke 34256056a3 data-flow: design dashboard aggregation endpoint contract
- Completed Action 2.1.1.1: Designed dashboard endpoint contract
- Created DASHBOARD_ENDPOINT_CONTRACT.md with complete specification
- Defined GET /api/v1/dashboard endpoint consolidating 4+ API calls
- Response structure: stats, recent_activity, library_preview
- Query parameters: activity_limit, library_limit, stats_period
- Documented data sources, error handling, performance considerations
- Migration strategy outlined for phased rollout
- Ready for backend implementation (Action 2.1.1.2)
2026-01-11 16:43:14 +01:00

215 lines
6.3 KiB
Markdown

# Dashboard Aggregation Endpoint Contract
**Date**: 2025-01-27
**Action**: 2.1.1.1 - Design dashboard endpoint contract
**Status**: ✅ Complete
## Overview
This document defines the contract for a new aggregated dashboard endpoint that consolidates multiple API calls into a single request, reducing over-fetching and improving performance.
## Current Implementation
The dashboard currently makes **4+ separate API calls**:
1. **GET /audit/stats** - Dashboard statistics
2. **GET /audit/activity** - Recent activity logs
3. **Social feed API** - Recent posts/feed items
4. **GET /tracks** (with limit: 5) - Library preview
**Problems**:
- Multiple round trips increase latency
- Over-fetching of data
- Race conditions possible
- No atomic data consistency
## Proposed Endpoint
### Endpoint Specification
**Method**: `GET`
**Path**: `/api/v1/dashboard`
**Authentication**: Required (Bearer token)
**Response Format**: Wrapped format `{ success: true, data: DashboardResponse }`
### Request Parameters
**Query Parameters** (all optional):
- `activity_limit` (integer, default: 10) - Number of recent activity items to return
- `library_limit` (integer, default: 5) - Number of library items to return in preview
- `stats_period` (string, default: "30d") - Time period for statistics ("7d", "30d", "90d", "all")
### Response Structure
```typescript
interface DashboardResponse {
stats: DashboardStats;
recent_activity: RecentActivity[];
library_preview: LibraryPreview;
}
interface DashboardStats {
tracks_played: number;
messages_sent: number;
favorites: number;
active_friends: number;
tracks_played_change?: string; // Percentage change (e.g., "+12%", "-5%")
messages_sent_change?: string;
favorites_change?: string;
active_friends_change?: string;
period: string; // "7d", "30d", "90d", "all"
}
interface RecentActivity {
id: string; // UUID
type: 'track_upload' | 'message_received' | 'favorite_added' |
'playlist_created' | 'comment_added' | 'post';
title: string; // Human-readable title
description?: string; // Optional description/details
timestamp: string; // ISO8601 timestamp
icon?: string; // Optional icon URL or identifier
metadata?: Record<string, any>; // Additional context (track_id, user_id, etc.)
}
interface LibraryPreview {
items: TrackPreview[];
total_count: number; // Total tracks in user's library
has_more: boolean; // Whether there are more items beyond limit
}
interface TrackPreview {
id: string; // UUID
title: string;
artist: string;
duration: number; // Seconds
cover_art_path?: string;
play_count: number;
like_count: number;
created_at: string; // ISO8601 timestamp
}
```
### Response Example
```json
{
"success": true,
"data": {
"stats": {
"tracks_played": 1234,
"messages_sent": 567,
"favorites": 89,
"active_friends": 45,
"tracks_played_change": "+12%",
"messages_sent_change": "+8%",
"favorites_change": "+23%",
"active_friends_change": "+5%",
"period": "30d"
},
"recent_activity": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "track_upload",
"title": "Nouvelle piste ajoutée",
"description": "My New Track.mp3",
"timestamp": "2025-01-27T10:30:00Z",
"metadata": {
"track_id": "660e8400-e29b-41d4-a716-446655440001",
"file_name": "My New Track.mp3"
}
},
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"type": "message_received",
"title": "Message reçu de @username",
"timestamp": "2025-01-27T09:15:00Z",
"metadata": {
"conversation_id": "770e8400-e29b-41d4-a716-446655440003",
"from_user_id": "880e8400-e29b-41d4-a716-446655440004"
}
}
],
"library_preview": {
"items": [
{
"id": "990e8400-e29b-41d4-a716-446655440005",
"title": "My Favorite Track",
"artist": "Artist Name",
"duration": 240,
"cover_art_path": "/covers/track-123.jpg",
"play_count": 42,
"like_count": 7,
"created_at": "2025-01-20T14:30:00Z"
}
],
"total_count": 156,
"has_more": true
}
}
}
```
## Data Sources
### Stats Calculation
**tracks_played**: Sum of play actions from audit logs + track play counts
**messages_sent**: Count of message actions from audit logs
**favorites**: Count of favorite/like actions from audit logs
**active_friends**: Count of unique users interacted with in period
**Change percentages**: Compare current period to previous period (e.g., last 30d vs previous 30d)
### Recent Activity
Combines:
1. **Audit logs** (`/audit/activity`) - User actions (uploads, plays, favorites, etc.)
2. **Social feed** - Recent posts from followed users
3. **Chat messages** - Recent messages received
4. **Comments** - Comments on user's tracks/playlists
Sorted by `timestamp` descending, limited by `activity_limit`.
### Library Preview
Returns user's most recently added or most played tracks, limited by `library_limit`.
## Error Handling
**401 Unauthorized**: User not authenticated
**500 Internal Server Error**: Backend error during aggregation
Error responses follow standard format:
```json
{
"success": false,
"error": {
"code": 500,
"message": "Failed to fetch dashboard data",
"timestamp": "2025-01-27T10:30:00Z"
}
}
```
## Performance Considerations
- **Caching**: Response can be cached for 30-60 seconds (user-specific)
- **Database queries**: Use efficient joins and indexes
- **Parallel fetching**: Fetch stats, activity, and library in parallel
- **Timeouts**: Aggregate endpoint should complete within 2 seconds
## Migration Strategy
1. **Phase 1**: Implement backend endpoint (Action 2.1.1.2)
2. **Phase 2**: Update frontend to use new endpoint (Action 2.1.1.3)
3. **Phase 3**: Remove old API calls (Actions 2.1.1.4-2.1.1.6)
4. **Phase 4**: Add caching (Action 2.1.1.7)
## Validation
✅ Contract documented
✅ Response structure defined
✅ Data sources identified
✅ Error handling specified
✅ Performance considerations noted
⏭️ Next: Action 2.1.1.2 - Implement backend dashboard handler