syntax = "proto3"; package metadata.v1; option go_package = "github.com/metadata-agregator/pkg/gen/metadata/v1;metadatav1"; enum Provider { PROVIDER_UNSPECIFIED = 0; PROVIDER_MUSICBRAINZ = 1; } // MetadataService provides music metadata aggregation. service MetadataService { // GetArtist retrieves an artist by ID or external source ID. rpc GetArtist(GetArtistRequest) returns (Artist); // SearchArtists searches for artists by name. rpc SearchArtists(SearchArtistsRequest) returns (SearchArtistsResponse); // GetAlbum retrieves an album by ID. rpc GetAlbum(GetAlbumRequest) returns (Album); // GetArtistAlbums retrieves all albums by an artist. rpc GetArtistAlbums(GetArtistAlbumsRequest) returns (GetArtistAlbumsResponse); // GetTrack retrieves a track by ID. rpc GetTrack(GetTrackRequest) returns (Track); // GetAlbumTracks retrieves all tracks on an album. rpc GetAlbumTracks(GetAlbumTracksRequest) returns (GetAlbumTracksResponse); // SearchAlbums searches for albums by name, optionally filtered by artist. rpc SearchAlbums(SearchAlbumsRequest) returns (SearchAlbumsResponse); // SyncArtist triggers ingestion of an artist from external sources. rpc SyncArtist(SyncArtistRequest) returns (SyncArtistResponse); } // Requests message GetArtistRequest { oneof identifier { string id = 1; // Internal UUID ExternalID external = 2; // External source ID (e.g., musicbrainz MBID) } Provider provider = 3; // UNSPECIFIED = query all providers } message SearchArtistsRequest { string query = 1; int32 limit = 2; int32 offset = 3; Provider provider = 4; } message GetAlbumRequest { oneof identifier { string id = 1; ExternalID external = 2; } Provider provider = 3; } message GetArtistAlbumsRequest { string artist_id = 1; int32 limit = 2; int32 offset = 3; Provider provider = 4; } message GetTrackRequest { oneof identifier { string id = 1; ExternalID external = 2; string isrc = 3; } Provider provider = 4; } message GetAlbumTracksRequest { string album_id = 1; Provider provider = 2; } message SearchAlbumsRequest { string query = 1; string artist = 2; int32 limit = 3; int32 offset = 4; Provider provider = 5; } message SearchAlbumsResponse { repeated Album albums = 1; int32 total = 2; } message SyncArtistRequest { oneof target { string name = 1; ExternalID external = 2; } Provider provider = 3; } // Responses message SearchArtistsResponse { repeated Artist artists = 1; int32 total = 2; } message GetArtistAlbumsResponse { repeated Album albums = 1; int32 total = 2; } message GetAlbumTracksResponse { repeated Track tracks = 1; } message SyncArtistResponse { Artist artist = 1; int32 albums_synced = 2; int32 tracks_synced = 3; } // Core Entities message Artist { string id = 1; string name = 2; string sort_name = 3; string artist_type = 4; // person, group, orchestra, etc. string country = 5; string formed_date = 6; string disbanded_date = 7; string description = 8; string image_url = 9; repeated Genre genres = 10; repeated ExternalID external_ids = 11; } message Album { string id = 1; string title = 2; string album_type = 3; // album, ep, single, compilation string release_date = 4; string upc = 5; int32 total_tracks = 6; int32 total_discs = 7; string cover_url = 8; repeated ArtistCredit artists = 9; Label label = 10; repeated Genre genres = 11; repeated ExternalID external_ids = 12; } message Track { string id = 1; string title = 2; int32 duration_ms = 3; string isrc = 4; bool explicit = 5; int32 disc_number = 6; int32 track_number = 7; repeated ArtistCredit artists = 8; Work work = 9; repeated ExternalID external_ids = 10; } message Work { string id = 1; string title = 2; string work_type = 3; string language = 4; repeated ArtistCredit composers = 5; } message Label { string id = 1; string name = 2; string country = 3; } message Genre { string id = 1; string name = 2; } message ArtistCredit { Artist artist = 1; string role = 2; // primary, featured, remixer, producer int32 position = 3; string join_phrase = 4; // " & ", " feat. ", etc. } message ExternalID { string source = 1; // musicbrainz, spotify, discogs, etc. string source_id = 2; string url = 3; }