204941a1dc
- Created a detailed database schema document outlining tables, relationships, and key fields. - Added OAuth integration documentation covering Spotify and Dropbox authentication processes. - Introduced a FAQ section addressing common user inquiries about the application. - Developed a user-friendly index page for easy navigation of the documentation. - Specified documentation dependencies in requirements.txt for building the documentation site. - Expanded user guide with sections on account management, creating rounds, exporting rounds, getting started, importing songs, and user interface navigation. - Updated mkdocs.yml for improved site structure and navigation.
289 lines
17 KiB
Markdown
289 lines
17 KiB
Markdown
# Database Schema
|
|
|
|
This document provides an overview of the Quizzical Beats database schema, including tables, relationships, and key fields.
|
|
|
|
## Entity Relationship Diagram
|
|
|
|
The following diagram illustrates the relationships between the main entities in Quizzical Beats:
|
|
|
|
```
|
|
+---------------+ +---------------+ +---------------+
|
|
| User | | Round | | Song |
|
|
+---------------+ +---------------+ +---------------+
|
|
| id |<----->| id | | id |
|
|
| username | | name | | title |
|
|
| email | | round_type | | artist |
|
|
| password_hash | | songs |-------| spotify_id |
|
|
| is_admin | | round_criteria| | deezer_id |
|
|
| roles |----+ | created_at | | isrc |
|
|
| auth_provider | | | updated_at | | preview_url |
|
|
| oauth_tokens | | | mp3_generated | | cover_url |
|
|
+---------------+ | | pdf_generated | | tags |----+
|
|
^ | +---------------+ | audio_features| |
|
|
| | +---------------+ |
|
|
| | ^ |
|
|
| v | |
|
|
+---------------+ +---------------+ +---------------+ |
|
|
| UserPreferences| | Role | | RoundExport | |
|
|
+---------------+ +---------------+ +---------------+ |
|
|
| id | | id | | id | |
|
|
| user_id | | name | | round_id | |
|
|
| default_tts | | description | | user_id | |
|
|
| enable_intro | +---------------+ | export_type | |
|
|
| theme | | timestamp | |
|
|
+---------------+ | destination | |
|
|
+---------------+ |
|
|
|
|
|
+---------------+ +---------------+ |
|
|
| SystemSetting | | Tag |<--------+
|
|
+---------------+ +---------------+
|
|
| id | | id |
|
|
| key | | name |
|
|
| value | | created_at |
|
|
+---------------+ +---------------+
|
|
```
|
|
|
|
## Tables
|
|
|
|
### User
|
|
|
|
The `User` table stores user account information and authentication details.
|
|
|
|
| Column | Type | Description |
|
|
|-----------------------|--------------|--------------------------------------------------|
|
|
| id | Integer | Primary key |
|
|
| username | String(80) | User's display name |
|
|
| email | String(120) | User's email address |
|
|
| password_hash | String(255) | Hashed password (nullable for OAuth-only users) |
|
|
| first_name | String(50) | User's first name |
|
|
| last_name | String(50) | User's last name |
|
|
| active | Boolean | Account active status |
|
|
| is_admin | Boolean | Administrator privileges flag |
|
|
| created_at | DateTime | Account creation timestamp |
|
|
| last_login | DateTime | Last login timestamp |
|
|
| reset_token | String(100) | Password reset token |
|
|
| reset_token_expiry | DateTime | Token expiration time |
|
|
| auth_provider | String(20) | Authentication provider (local, google, etc.) |
|
|
| oauth_id | String(100) | Spotify user ID |
|
|
| spotify_token | Text | Spotify access token |
|
|
| spotify_refresh_token | Text | Spotify refresh token |
|
|
| spotify_token_expiry | DateTime | Spotify token expiration |
|
|
| google_id | String(100) | Google user ID |
|
|
| google_token | Text | Google access token |
|
|
| google_refresh_token | Text | Google refresh token |
|
|
| authentik_id | String(100) | Authentik user ID |
|
|
| authentik_token | Text | Authentik access token |
|
|
| authentik_refresh_token | Text | Authentik refresh token |
|
|
| dropbox_id | String(100) | Dropbox user ID |
|
|
| dropbox_token | Text | Dropbox access token |
|
|
| dropbox_refresh_token | Text | Dropbox refresh token |
|
|
| dropbox_token_expiry | DateTime | Dropbox token expiration |
|
|
| dropbox_export_path | String(255) | User's preferred Dropbox export folder |
|
|
| intro_mp3 | String(255) | Custom intro MP3 path |
|
|
| outro_mp3 | String(255) | Custom outro MP3 path |
|
|
| replay_mp3 | String(255) | Custom replay MP3 path |
|
|
|
|
### UserPreferences
|
|
|
|
The `UserPreferences` table stores user-specific settings.
|
|
|
|
| Column | Type | Description |
|
|
|----------------------|--------------|--------------------------------------------------|
|
|
| id | Integer | Primary key |
|
|
| user_id | Integer | Foreign key to User |
|
|
| default_tts_service | String(32) | Default text-to-speech service (polly, etc.) |
|
|
| enable_intro | Boolean | Whether to enable intro sound |
|
|
| theme | String(16) | UI theme preference (light, dark) |
|
|
|
|
### Role
|
|
|
|
The `Role` table defines user roles for permission management.
|
|
|
|
| Column | Type | Description |
|
|
|-------------|--------------|--------------------------------------------------|
|
|
| id | Integer | Primary key |
|
|
| name | String(50) | Role name |
|
|
| description | String(255) | Role description |
|
|
|
|
### user_roles
|
|
|
|
The `user_roles` table is an association table linking users to roles.
|
|
|
|
| Column | Type | Description |
|
|
|-------------|--------------|--------------------------------------------------|
|
|
| user_id | Integer | Foreign key to User |
|
|
| role_id | Integer | Foreign key to Role |
|
|
|
|
### Song
|
|
|
|
The `Song` table stores detailed information about music tracks from various sources.
|
|
|
|
| Column | Type | Description |
|
|
|-----------------------|--------------|-------------------------------------------------|
|
|
| id | Integer | Primary key |
|
|
| spotify_id | String(100) | Spotify track ID |
|
|
| deezer_id | Integer | Deezer track ID |
|
|
| isrc | String(20) | International Standard Recording Code |
|
|
| title | String(200) | Song title |
|
|
| artist | String(200) | Artist name |
|
|
| album_name | String(200) | Album name |
|
|
| genre | String(100) | Music genre |
|
|
| year | Integer | Release year |
|
|
| preview_url | String(500) | Primary audio preview URL |
|
|
| cover_url | String(500) | Primary album cover URL |
|
|
| spotify_preview_url | String(500) | Spotify-specific preview URL |
|
|
| deezer_preview_url | String(500) | Deezer-specific preview URL |
|
|
| apple_preview_url | String(500) | Apple Music preview URL |
|
|
| youtube_preview_url | String(500) | YouTube preview URL |
|
|
| spotify_cover_url | String(500) | Spotify cover image URL |
|
|
| deezer_cover_url | String(500) | Deezer cover image URL |
|
|
| apple_cover_url | String(500) | Apple Music cover image URL |
|
|
| popularity | Integer | Popularity score (0-100) |
|
|
| used_count | Integer | Number of times used in rounds |
|
|
| source | String(20) | Data source (spotify, deezer, acrcloud) |
|
|
| import_date | DateTime | When the song was imported |
|
|
| added_at | DateTime | When the song was added |
|
|
| last_used | DateTime | When the song was last used |
|
|
| metadata_sources | String(500) | Comma-separated list of metadata sources |
|
|
| acousticness | Float | Spotify audio feature - acousticness (0.0-1.0) |
|
|
| danceability | Float | Spotify audio feature - danceability (0.0-1.0) |
|
|
| energy | Float | Spotify audio feature - energy (0.0-1.0) |
|
|
| instrumentalness | Float | Spotify audio feature - instrumentalness |
|
|
| key | Integer | Spotify audio feature - musical key |
|
|
| liveness | Float | Spotify audio feature - liveness (0.0-1.0) |
|
|
| loudness | Float | Spotify audio feature - loudness (dB) |
|
|
| mode | Integer | Spotify audio feature - modality (major/minor) |
|
|
| speechiness | Float | Spotify audio feature - speechiness (0.0-1.0) |
|
|
| tempo | Float | Spotify audio feature - tempo (BPM) |
|
|
| time_signature | Integer | Spotify audio feature - time signature |
|
|
| valence | Float | Spotify audio feature - valence (0.0-1.0) |
|
|
| duration_ms | Integer | Track duration in milliseconds |
|
|
| analysis_url | String(500) | URL to full audio analysis |
|
|
| additional_data | Text | Additional data as JSON |
|
|
|
|
### Tag
|
|
|
|
The `Tag` table stores tags for categorizing songs.
|
|
|
|
| Column | Type | Description |
|
|
|-------------|--------------|--------------------------------------------------|
|
|
| id | Integer | Primary key |
|
|
| name | String(50) | Tag name |
|
|
| created_at | DateTime | Creation timestamp |
|
|
|
|
### SongTag
|
|
|
|
The `SongTag` table links songs to tags.
|
|
|
|
| Column | Type | Description |
|
|
|-------------|--------------|--------------------------------------------------|
|
|
| song_id | Integer | Foreign key to Song |
|
|
| tag_id | Integer | Foreign key to Tag |
|
|
| created_at | DateTime | When the tag was applied |
|
|
|
|
### Round
|
|
|
|
The `Round` table stores music quiz rounds.
|
|
|
|
| Column | Type | Description |
|
|
|-----------------------|--------------|--------------------------------------------------|
|
|
| id | Integer | Primary key |
|
|
| name | String(200) | Round name |
|
|
| round_type | String(50) | Type of round (genre, decade, etc.) |
|
|
| round_criteria_used | String(500) | Criteria used to generate the round |
|
|
| songs | Text | JSON string of song IDs in order |
|
|
| genre | String(100) | Genre of the round (if applicable) |
|
|
| decade | String(10) | Decade of the round (if applicable) |
|
|
| tag | String(50) | Tag of the round (if applicable) |
|
|
| created_at | DateTime | Creation timestamp |
|
|
| updated_at | DateTime | Last update timestamp |
|
|
| mp3_generated | Boolean | Flag indicating if MP3 has been generated |
|
|
| pdf_generated | Boolean | Flag indicating if PDF has been generated |
|
|
| last_generated_at | DateTime | When files were last generated |
|
|
|
|
### RoundExport
|
|
|
|
The `RoundExport` table tracks exports of rounds to various destinations.
|
|
|
|
| Column | Type | Description |
|
|
|---------------|--------------|--------------------------------------------------|
|
|
| id | Integer | Primary key |
|
|
| round_id | Integer | Foreign key to Round |
|
|
| user_id | Integer | Foreign key to User |
|
|
| export_type | String(20) | Export type (dropbox, email, etc.) |
|
|
| timestamp | DateTime | Export timestamp |
|
|
| destination | String(500) | Destination (path, email, etc.) |
|
|
| include_mp3s | Boolean | Whether MP3s were included |
|
|
| status | String(20) | Export status (success, failed) |
|
|
| error_message | Text | Error message if export failed |
|
|
|
|
### SystemSetting
|
|
|
|
The `SystemSetting` table stores application-wide settings.
|
|
|
|
| Column | Type | Description |
|
|
|-------------|--------------|--------------------------------------------------|
|
|
| id | Integer | Primary key |
|
|
| key | String(64) | Setting key |
|
|
| value | Text | Setting value |
|
|
|
|
## Key Relationships
|
|
|
|
### User Relationships
|
|
|
|
- **User → UserPreferences**: One-to-one. A user has one set of preferences.
|
|
- **User ↔ Roles**: Many-to-many through user_roles. A user can have multiple roles, and a role can be assigned to multiple users.
|
|
- **User → RoundExports**: One-to-many. A user can create multiple exports.
|
|
|
|
### Song Relationships
|
|
|
|
- **Song ↔ Tags**: Many-to-many through SongTag. A song can have multiple tags, and a tag can be applied to multiple songs.
|
|
- **Song → Rounds**: Many-to-many (implicit). Songs are referenced in the Round.songs field as a JSON string of IDs.
|
|
|
|
### Round Relationships
|
|
|
|
- **Round → RoundExports**: One-to-many. A round can have multiple exports.
|
|
- **Round → Songs**: Many-to-many (implicit). A round contains multiple songs referenced by ID.
|
|
|
|
## Data Model Features
|
|
|
|
### OAuth Integration
|
|
|
|
The User model integrates OAuth provider information directly:
|
|
- Support for Spotify, Google, Authentik and Dropbox OAuth providers
|
|
- Token storage and refresh token functionality
|
|
- Provider-specific user IDs
|
|
|
|
### Audio Features
|
|
|
|
The Song model includes detailed audio features from Spotify:
|
|
- Acoustic characteristics (acousticness, instrumentalness)
|
|
- Rhythmic characteristics (tempo, time_signature)
|
|
- Mood characteristics (valence, energy, danceability)
|
|
- Technical characteristics (loudness, key, mode)
|
|
|
|
### Multi-Source Integration
|
|
|
|
Songs can be imported from multiple sources:
|
|
- Spotify API
|
|
- Deezer API
|
|
- ACRCloud identification service
|
|
- Each song stores source-specific IDs and URLs
|
|
|
|
### Tagging System
|
|
|
|
The tagging system allows flexible organization:
|
|
- Songs can be tagged for easier categorization
|
|
- Tags provide a way to group songs by custom criteria
|
|
|
|
## Data Migrations
|
|
|
|
The database schema evolves over time through migrations. Migration scripts are stored in the `migrations/` directory:
|
|
|
|
- `add_preview_urls.py`: Added Song.preview_url field
|
|
- `add_song_fields.py`: Added additional metadata fields to Song
|
|
- `add_spotify_audio_features.py`: Added audio analysis data
|
|
- `add_oauth_providers.py`: Extended OAuth provider support
|
|
- `add_tag_system.py`: Added tagging functionality
|
|
- `add_dropbox_oauth.py`: Added Dropbox OAuth support
|
|
- `add_dropbox_export_path.py`: Added export path tracking |