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 |
| 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.) |
| spotify_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 fieldadd_song_fields.py: Added additional metadata fields to Songadd_spotify_audio_features.py: Added audio analysis dataadd_oauth_providers.py: Extended OAuth provider supportadd_tag_system.py: Added tagging functionalityadd_dropbox_oauth.py: Added Dropbox OAuth supportadd_dropbox_export_path.py: Added export path tracking