Add skip tracking, compressed heatmap, listening log, docs, tests, and OpenAI support

Major changes:
- Add skip tracking: poll currently-playing every 15s, detect skips (<30s listened)
- Add listening-log and sessions API endpoints
- Fix ReccoBeats client to extract spotify_id from href response
- Compress heatmap from 24 hours to 6 x 4-hour blocks
- Add OpenAI support in narrative service (use max_completion_tokens for new models)
- Add ListeningLog component with timeline and list views
- Update all frontend components to use real data (album art, play counts)
- Add docker-compose external network (dockernet) support
- Add comprehensive documentation (API, DATA_MODEL, ARCHITECTURE, FRONTEND)
- Add unit tests for ingest and API endpoints
This commit is contained in:
bnair123
2025-12-30 00:15:01 +04:00
parent faee830545
commit 887e78bf47
26 changed files with 1942 additions and 662 deletions

125
docs/API.md Normal file
View File

@@ -0,0 +1,125 @@
# API Documentation
The MusicAnalyser Backend is built with FastAPI. It provides endpoints for data ingestion, listening history retrieval, and AI-powered analysis.
## Base URL
Default local development: `http://localhost:8000`
Docker environment: Proxied via Nginx at `http://localhost:8991/api`
---
## Endpoints
### 1. Root / Health Check
- **URL**: `/`
- **Method**: `GET`
- **Response**:
```json
{
"status": "ok",
"message": "Music Analyser API is running"
}
```
### 2. Get Recent History
Returns a flat list of recently played tracks.
- **URL**: `/history`
- **Method**: `GET`
- **Query Parameters**:
- `limit` (int, default=50): Number of items to return.
- **Response**: List of PlayHistory objects with nested Track data.
### 3. Get Tracks
Returns a list of unique tracks in the database.
- **URL**: `/tracks`
- **Method**: `GET`
- **Query Parameters**:
- `limit` (int, default=50): Number of tracks to return.
### 4. Trigger Spotify Ingestion
Manually triggers a background task to poll Spotify for recently played tracks.
- **URL**: `/trigger-ingest`
- **Method**: `POST`
- **Response**:
```json
{
"status": "Ingestion started in background"
}
```
### 5. Trigger Analysis Pipeline
Runs the full stats calculation and AI narrative generation for a specific timeframe.
- **URL**: `/trigger-analysis`
- **Method**: `POST`
- **Query Parameters**:
- `days` (int, default=30): Number of past days to analyze.
- `model_name` (str): LLM model to use.
- **Response**:
```json
{
"status": "success",
"snapshot_id": 1,
"period": { "start": "...", "end": "..." },
"metrics": { ... },
"narrative": { ... }
}
```
### 6. Get Analysis Snapshots
Retrieves previously saved analysis reports.
- **URL**: `/snapshots`
- **Method**: `GET`
- **Query Parameters**:
- `limit` (int, default=10): Number of snapshots to return.
### 7. Detailed Listening Log
Returns a refined listening log with skip detection and listening duration calculations.
- **URL**: `/listening-log`
- **Method**: `GET`
- **Query Parameters**:
- `days` (int, 1-365, default=7): Timeframe.
- `limit` (int, 1-1000, default=200): Max plays to return.
- **Response**:
```json
{
"plays": [
{
"id": 123,
"track_name": "Song Name",
"artist": "Artist Name",
"played_at": "ISO-TIMESTAMP",
"listened_ms": 180000,
"skipped": false,
"image": "..."
}
],
"period": { "start": "...", "end": "..." }
}
```
### 8. Session Statistics
Groups plays into listening sessions (Marathon, Standard, Micro).
- **URL**: `/sessions`
- **Method**: `GET`
- **Query Parameters**:
- `days` (int, 1-365, default=7): Timeframe.
- **Response**:
```json
{
"sessions": [
{
"start_time": "...",
"end_time": "...",
"duration_minutes": 45,
"track_count": 12,
"type": "Standard"
}
],
"summary": {
"count": 10,
"avg_minutes": 35,
"micro_rate": 0.1,
"marathon_rate": 0.05
}
}
```