feat: initial implementation of metadata aggregator
- gRPC service with MusicBrainz provider - PostgreSQL schema with migrations - Service layer with database-first caching - Repository pattern for data access - YAML configuration support - Research documentation for 17 music metadata projects
This commit is contained in:
@@ -0,0 +1,276 @@
|
||||
@startuml Music Metadata ERD
|
||||
|
||||
skinparam linetype ortho
|
||||
skinparam ranksep 50
|
||||
skinparam nodesep 30
|
||||
|
||||
skinparam entity {
|
||||
BackgroundColor White
|
||||
BorderColor #333333
|
||||
}
|
||||
|
||||
skinparam package {
|
||||
BackgroundColor #FAFAFA
|
||||
BorderColor #DDDDDD
|
||||
}
|
||||
|
||||
title Music Metadata Aggregator - Internal Structure
|
||||
|
||||
' ══════════════════════════════════════════════════════════════
|
||||
' CORE MUSIC ENTITIES
|
||||
' ══════════════════════════════════════════════════════════════
|
||||
|
||||
package "Core Entities" #E3F2FD {
|
||||
entity "artists" {
|
||||
* id : UUID <<PK>>
|
||||
--
|
||||
name : TEXT
|
||||
sort_name : TEXT
|
||||
artist_type : TEXT
|
||||
country : TEXT
|
||||
formed_date : DATE
|
||||
disbanded_date : DATE
|
||||
description : TEXT
|
||||
image_url : TEXT
|
||||
--
|
||||
source : TEXT
|
||||
source_id : TEXT
|
||||
created_at : TIMESTAMPTZ
|
||||
updated_at : TIMESTAMPTZ
|
||||
}
|
||||
|
||||
entity "works" {
|
||||
* id : UUID <<PK>>
|
||||
--
|
||||
title : TEXT
|
||||
work_type : TEXT
|
||||
language : TEXT
|
||||
--
|
||||
source : TEXT
|
||||
source_id : TEXT
|
||||
created_at : TIMESTAMPTZ
|
||||
updated_at : TIMESTAMPTZ
|
||||
}
|
||||
|
||||
entity "tracks" {
|
||||
* id : UUID <<PK>>
|
||||
--
|
||||
work_id : UUID <<FK>>
|
||||
--
|
||||
title : TEXT
|
||||
duration_ms : INT
|
||||
isrc : TEXT
|
||||
explicit : BOOLEAN
|
||||
--
|
||||
source : TEXT
|
||||
source_id : TEXT
|
||||
created_at : TIMESTAMPTZ
|
||||
updated_at : TIMESTAMPTZ
|
||||
}
|
||||
|
||||
entity "albums" {
|
||||
* id : UUID <<PK>>
|
||||
--
|
||||
label_id : UUID <<FK>>
|
||||
--
|
||||
title : TEXT
|
||||
album_type : TEXT
|
||||
release_date : DATE
|
||||
upc : TEXT
|
||||
total_tracks : INT
|
||||
total_discs : INT
|
||||
cover_url : TEXT
|
||||
--
|
||||
source : TEXT
|
||||
source_id : TEXT
|
||||
created_at : TIMESTAMPTZ
|
||||
updated_at : TIMESTAMPTZ
|
||||
}
|
||||
|
||||
entity "labels" {
|
||||
* id : UUID <<PK>>
|
||||
--
|
||||
name : TEXT
|
||||
country : TEXT
|
||||
founded_date : DATE
|
||||
--
|
||||
source : TEXT
|
||||
source_id : TEXT
|
||||
created_at : TIMESTAMPTZ
|
||||
updated_at : TIMESTAMPTZ
|
||||
}
|
||||
|
||||
entity "genres" {
|
||||
* id : UUID <<PK>>
|
||||
--
|
||||
name : TEXT
|
||||
parent_id : UUID <<FK>>
|
||||
}
|
||||
}
|
||||
|
||||
' ══════════════════════════════════════════════════════════════
|
||||
' RELATIONSHIPS
|
||||
' ══════════════════════════════════════════════════════════════
|
||||
|
||||
package "Relationships" #FFF3E0 {
|
||||
entity "track_artists" {
|
||||
* track_id : UUID <<FK>>
|
||||
* artist_id : UUID <<FK>>
|
||||
--
|
||||
role : TEXT
|
||||
position : INT
|
||||
}
|
||||
|
||||
entity "album_artists" {
|
||||
* album_id : UUID <<FK>>
|
||||
* artist_id : UUID <<FK>>
|
||||
--
|
||||
role : TEXT
|
||||
position : INT
|
||||
}
|
||||
|
||||
entity "album_tracks" {
|
||||
* album_id : UUID <<FK>>
|
||||
* track_id : UUID <<FK>>
|
||||
--
|
||||
disc_number : INT
|
||||
track_number : INT
|
||||
}
|
||||
|
||||
entity "work_artists" {
|
||||
* work_id : UUID <<FK>>
|
||||
* artist_id : UUID <<FK>>
|
||||
--
|
||||
role : TEXT
|
||||
}
|
||||
|
||||
entity "artist_genres" {
|
||||
* artist_id : UUID <<FK>>
|
||||
* genre_id : UUID <<FK>>
|
||||
}
|
||||
|
||||
entity "album_genres" {
|
||||
* album_id : UUID <<FK>>
|
||||
* genre_id : UUID <<FK>>
|
||||
}
|
||||
|
||||
entity "similar_artists" {
|
||||
* artist_id : UUID <<FK>>
|
||||
* similar_artist_id : UUID <<FK>>
|
||||
--
|
||||
score : REAL
|
||||
}
|
||||
}
|
||||
|
||||
' ══════════════════════════════════════════════════════════════
|
||||
' CONTENT
|
||||
' ══════════════════════════════════════════════════════════════
|
||||
|
||||
package "Content" #E8F5E9 {
|
||||
entity "lyrics" {
|
||||
* id : UUID <<PK>>
|
||||
--
|
||||
track_id : UUID <<FK>>
|
||||
--
|
||||
content : TEXT
|
||||
synced_content : JSONB
|
||||
language : TEXT
|
||||
--
|
||||
source : TEXT
|
||||
source_id : TEXT
|
||||
created_at : TIMESTAMPTZ
|
||||
}
|
||||
|
||||
entity "playlists" {
|
||||
* id : UUID <<PK>>
|
||||
--
|
||||
name : TEXT
|
||||
description : TEXT
|
||||
is_public : BOOLEAN
|
||||
cover_url : TEXT
|
||||
--
|
||||
created_at : TIMESTAMPTZ
|
||||
updated_at : TIMESTAMPTZ
|
||||
}
|
||||
|
||||
entity "playlist_tracks" {
|
||||
* playlist_id : UUID <<FK>>
|
||||
* track_id : UUID <<FK>>
|
||||
--
|
||||
position : INT
|
||||
added_at : TIMESTAMPTZ
|
||||
}
|
||||
}
|
||||
|
||||
' ══════════════════════════════════════════════════════════════
|
||||
' EXTERNAL IDS (Cross-platform linking)
|
||||
' ══════════════════════════════════════════════════════════════
|
||||
|
||||
package "External IDs" #FCE4EC {
|
||||
entity "artist_external_ids" {
|
||||
* artist_id : UUID <<FK>>
|
||||
* source : TEXT
|
||||
* source_id : TEXT
|
||||
--
|
||||
url : TEXT
|
||||
fetched_at : TIMESTAMPTZ
|
||||
}
|
||||
|
||||
entity "album_external_ids" {
|
||||
* album_id : UUID <<FK>>
|
||||
* source : TEXT
|
||||
* source_id : TEXT
|
||||
--
|
||||
url : TEXT
|
||||
fetched_at : TIMESTAMPTZ
|
||||
}
|
||||
|
||||
entity "track_external_ids" {
|
||||
* track_id : UUID <<FK>>
|
||||
* source : TEXT
|
||||
* source_id : TEXT
|
||||
--
|
||||
url : TEXT
|
||||
fetched_at : TIMESTAMPTZ
|
||||
}
|
||||
}
|
||||
|
||||
' ══════════════════════════════════════════════════════════════
|
||||
' RELATIONSHIPS DIAGRAM
|
||||
' ══════════════════════════════════════════════════════════════
|
||||
|
||||
' Core relationships
|
||||
works ||--o{ tracks : "recorded as"
|
||||
albums ||--o{ album_tracks : "contains"
|
||||
tracks ||--o{ album_tracks : "appears on"
|
||||
labels ||--o{ albums : "released by"
|
||||
genres ||--o{ genres : "parent"
|
||||
|
||||
' Artist relationships
|
||||
artists ||--o{ track_artists : ""
|
||||
tracks ||--o{ track_artists : ""
|
||||
artists ||--o{ album_artists : ""
|
||||
albums ||--o{ album_artists : ""
|
||||
artists ||--o{ work_artists : ""
|
||||
works ||--o{ work_artists : ""
|
||||
|
||||
' Genre relationships
|
||||
artists ||--o{ artist_genres : ""
|
||||
genres ||--o{ artist_genres : ""
|
||||
albums ||--o{ album_genres : ""
|
||||
genres ||--o{ album_genres : ""
|
||||
|
||||
' Similar artists
|
||||
artists ||--o{ similar_artists : ""
|
||||
|
||||
' Content
|
||||
tracks ||--o| lyrics : "has"
|
||||
playlists ||--o{ playlist_tracks : ""
|
||||
tracks ||--o{ playlist_tracks : ""
|
||||
|
||||
' External IDs
|
||||
artists ||--o{ artist_external_ids : ""
|
||||
albums ||--o{ album_external_ids : ""
|
||||
tracks ||--o{ track_external_ids : ""
|
||||
|
||||
@enduml
|
||||
Reference in New Issue
Block a user