diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index 6587013d..980c1f22 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -6969,7 +6969,8 @@ components: access: $ref: "#/components/schemas/track_access_info" ai_attribution_user_id: - type: integer + type: string + example: "x5pJ3Az" allowed_api_keys: type: array items: @@ -7118,7 +7119,8 @@ components: type: object properties: parent_track_id: - type: integer + type: string + example: "x5pJ3Az" album_backlink: required: - permalink @@ -8032,6 +8034,7 @@ components: properties: tip_user_id: type: integer + example: 1234 description: Must tip the given user ID to unlock follow_gate: required: @@ -8040,6 +8043,7 @@ components: properties: follow_user_id: type: integer + example: 1234 description: Must follow the given user ID to unlock token_gate: required: @@ -8096,6 +8100,7 @@ components: properties: user_id: type: integer + example: 1234 percentage: type: number eth_wallet: @@ -8311,7 +8316,8 @@ components: category: $ref: "#/components/schemas/stem_category" parent_track_id: - type: integer + type: string + example: "x5pJ3Az" undisbursed_challenges: type: object properties: @@ -9962,9 +9968,9 @@ components: - track_cid properties: track_id: - type: integer + type: string description: Optional track ID (will be generated if not provided) - minimum: 1 + example: "x5pJ3Az" title: type: string description: Track title @@ -10027,7 +10033,7 @@ components: format: float description: Track duration in seconds minimum: 0 - downloadable: + is_downloadable: type: boolean description: Whether the track is downloadable is_unlisted: @@ -10126,7 +10132,7 @@ components: format: float description: Track duration in seconds minimum: 0 - downloadable: + is_downloadable: type: boolean description: Whether the track is downloadable is_unlisted: @@ -10163,9 +10169,9 @@ components: - playlist_name properties: playlist_id: - type: integer + type: string description: Optional playlist ID (will be generated if not provided) - minimum: 1 + example: "x5pJ3Az" playlist_name: type: string description: Playlist or album name @@ -10260,9 +10266,9 @@ components: - wallet properties: user_id: - type: integer - description: Optional user ID (will be generated if not provided) - minimum: 1 + type: string + description: Optional user hash ID (will be generated if not provided) + example: "p9Km2Lx" handle: type: string description: User handle (unique username) @@ -10322,27 +10328,15 @@ components: type: string description: Solana USDC payout wallet address playlist_library: - type: object - description: User's playlist library with support for folders and playlists - required: - - contents - properties: - contents: - type: array - description: Array of folders and playlist identifiers - items: - oneOf: - - $ref: "#/components/schemas/playlist_library_folder" - - $ref: "#/components/schemas/playlist_library_playlist_identifier" - - $ref: "#/components/schemas/playlist_library_explore_playlist_identifier" + $ref: '#/components/schemas/user_playlist_library' events: type: object description: User events for tracking referrals and mobile users properties: referrer: - type: integer - description: User ID of the referrer - minimum: 1 + type: string + description: Hash ID of the user who referred this user + example: "k9Xm5Pz" is_mobile_user: type: boolean description: Whether the user is on mobile @@ -10397,9 +10391,9 @@ components: type: boolean description: Whether the user is deactivated artist_pick_track_id: - type: integer - description: Track ID to feature as artist pick - minimum: 1 + type: string + description: Track hash ID to feature as artist pick + example: "x5pJ3Az" allow_ai_attribution: type: boolean description: Whether to allow AI attribution @@ -10410,25 +10404,15 @@ components: type: string description: Coin flair mint address playlist_library: - type: object - description: User's playlist library with support for folders and playlists - properties: - contents: - type: array - description: Array of folders and playlist identifiers - items: - oneOf: - - $ref: "#/components/schemas/playlist_library_folder" - - $ref: "#/components/schemas/playlist_library_playlist_identifier" - - $ref: "#/components/schemas/playlist_library_explore_playlist_identifier" + $ref: '#/components/schemas/user_playlist_library' events: type: object description: User events for tracking referrals and mobile users properties: referrer: - type: integer - description: User ID of the referrer - minimum: 1 + type: string + description: Hash ID of the user who referred this user + example: "k9Xm5Pz" is_mobile_user: type: boolean description: Whether the user is on mobile @@ -10446,7 +10430,6 @@ components: entityId: type: integer description: ID of the entity being commented on - minimum: 1 example: 12345 body: type: string @@ -10458,7 +10441,7 @@ components: maxItems: 10 items: type: integer - minimum: 1 + example: 67890 create_comment_request_body: type: object required: @@ -10473,7 +10456,6 @@ components: entityId: type: integer description: ID of the entity being commented on - minimum: 1 example: 12345 body: type: string @@ -10482,12 +10464,12 @@ components: example: "Great track!" commentId: type: integer - description: Optional comment ID (will be generated if not provided) - minimum: 1 + description: Optional ID for the comment (will be generated if not provided) + example: 98765 parentId: type: integer description: Parent comment ID if this is a reply - minimum: 1 + example: 54321 trackTimestampS: type: integer description: Timestamp in the track where the comment was made (in seconds) @@ -10498,7 +10480,7 @@ components: maxItems: 10 items: type: integer - minimum: 1 + example: 67890 react_comment_request_body: type: object required: @@ -10511,8 +10493,7 @@ components: example: "Track" entityId: type: integer - description: ID of the entity (track or playlist) being commented on - minimum: 1 + description: ID of the entity (track) being commented on example: 12345 pin_comment_request_body: type: object @@ -10526,8 +10507,7 @@ components: example: "Track" entityId: type: integer - description: ID of the entity (track or playlist) the comment is on - minimum: 1 + description: ID of the entity (track) the comment is on example: 12345 create_grant_request_body: type: object @@ -10662,6 +10642,20 @@ components: success: type: boolean description: Whether the deactivation was successful + user_playlist_library: + type: object + description: User's playlist library with support for folders and playlists + required: + - contents + properties: + contents: + type: array + description: Array of folders and playlist identifiers + items: + oneOf: + - $ref: '#/components/schemas/playlist_library_folder' + - $ref: '#/components/schemas/playlist_library_playlist_identifier' + - $ref: '#/components/schemas/playlist_library_explore_playlist_identifier' playlist_library_folder: type: object description: Folder containing nested playlists and folders @@ -10701,7 +10695,7 @@ components: playlist_id: type: integer description: Playlist ID - minimum: 1 + example: 1234 playlist_library_explore_playlist_identifier: type: object description: Reference to an explore playlist diff --git a/api/v1_playlist.go b/api/v1_playlist.go index bc57a4db..6621b00d 100644 --- a/api/v1_playlist.go +++ b/api/v1_playlist.go @@ -22,7 +22,7 @@ type PlaylistTrackInfo struct { } type CreatePlaylistRequest struct { - PlaylistId *int `json:"playlist_id,omitempty" validate:"omitempty,min=1"` + PlaylistId *trashid.HashId `json:"playlist_id,omitempty" validate:"omitempty,min=1"` PlaylistName string `json:"playlist_name" validate:"required,min=1"` Description *string `json:"description,omitempty" validate:"omitempty,max=1000"` IsPrivate *bool `json:"is_private,omitempty"` @@ -108,7 +108,7 @@ func (app *ApiServer) postV1Playlists(c *fiber.Ctx) error { // Determine playlist ID var playlistID int if req.PlaylistId != nil { - playlistID = *req.PlaylistId + playlistID = int(*req.PlaylistId) } else { // Generate unclaimed playlist ID if not provided generatedID, err := app.generateUnclaimedId(c.Context(), "tracks", "track_id", 400_000, math.MaxInt32) diff --git a/api/v1_track.go b/api/v1_track.go index b57102d3..0de57e91 100644 --- a/api/v1_track.go +++ b/api/v1_track.go @@ -18,7 +18,7 @@ import ( // Nested type definitions for track metadata type RemixParent struct { - ParentTrackId int `json:"parent_track_id" validate:"required,min=1"` + ParentTrackId trashid.HashId `json:"parent_track_id" validate:"required,min=1"` } type RemixOf struct { @@ -26,8 +26,8 @@ type RemixOf struct { } type StemOf struct { - Category string `json:"category" validate:"required,oneof=INSTRUMENTAL LEAD_VOCALS MELODIC_LEAD PAD SNARE KICK HIHAT PERCUSSION SAMPLE BACKING_VOX BASS OTHER"` - ParentTrackId int `json:"parent_track_id" validate:"required,min=1"` + Category string `json:"category" validate:"required,oneof=INSTRUMENTAL LEAD_VOCALS MELODIC_LEAD PAD SNARE KICK HIHAT PERCUSSION SAMPLE BACKING_VOX BASS OTHER"` + ParentTrackId trashid.HashId `json:"parent_track_id" validate:"required,min=1"` } type FieldVisibility struct { @@ -114,7 +114,7 @@ type DDEXRightsController struct { } type CreateTrackRequest struct { - TrackId *int `json:"track_id,omitempty" validate:"omitempty,min=1"` + TrackId *trashid.HashId `json:"track_id,omitempty" validate:"omitempty,min=1"` Title string `json:"title" validate:"required,min=1"` Genre string `json:"genre" validate:"required,oneof='Electronic' 'Rock' 'Metal' 'Alternative' 'Hip-Hop/Rap' 'Experimental' 'Punk' 'Folk' 'Pop' 'Ambient' 'Soundtrack' 'World' 'Jazz' 'Acoustic' 'Funk' 'R&B/Soul' 'Devotional' 'Classical' 'Reggae' 'Podcasts' 'Country' 'Spoken Word' 'Comedy' 'Blues' 'Kids' 'Audiobooks' 'Latin' 'Lo-Fi' 'Hyperpop' 'Dancehall' 'Techno' 'Trap' 'House' 'Tech House' 'Deep House' 'Disco' 'Electro' 'Jungle' 'Progressive House' 'Hardstyle' 'Glitch Hop' 'Trance' 'Future Bass' 'Future House' 'Tropical House' 'Downtempo' 'Drum & Bass' 'Dubstep' 'Jersey Club' 'Vaporwave' 'Moombahton'"` Description *string `json:"description,omitempty" validate:"omitempty,max=1000"` @@ -129,7 +129,7 @@ type CreateTrackRequest struct { PreviewCid *string `json:"preview_cid,omitempty"` PreviewStartSeconds *float64 `json:"preview_start_seconds,omitempty" validate:"omitempty,min=0"` Duration *float64 `json:"duration,omitempty" validate:"omitempty,min=0"` - Downloadable *bool `json:"downloadable,omitempty"` + IsDownloadable *bool `json:"is_downloadable,omitempty"` IsUnlisted *bool `json:"is_unlisted,omitempty"` FieldVisibility *FieldVisibility `json:"field_visibility,omitempty" validate:"omitempty"` RemixOf *RemixOf `json:"remix_of,omitempty" validate:"omitempty"` @@ -138,7 +138,7 @@ type CreateTrackRequest struct { StreamConditions *AccessConditions `json:"stream_conditions,omitempty" validate:"omitempty"` IsStreamGated *bool `json:"is_stream_gated,omitempty"` IsDownloadGated *bool `json:"is_download_gated,omitempty"` - AiAttributionUserId *int `json:"ai_attribution_user_id,omitempty" validate:"omitempty,min=0"` + AiAttributionUserId *trashid.HashId `json:"ai_attribution_user_id,omitempty" validate:"omitempty,min=0"` AllowedApiKeys *[]string `json:"allowed_api_keys,omitempty"` PlacementHosts *string `json:"placement_hosts,omitempty"` DdexApp *string `json:"ddex_app,omitempty"` @@ -170,7 +170,7 @@ type UpdateTrackRequest struct { CoverArtCid *string `json:"cover_art_cid,omitempty"` PreviewCid *string `json:"preview_cid,omitempty"` PreviewStartSeconds *float64 `json:"preview_start_seconds,omitempty" validate:"omitempty,min=0"` - Downloadable *bool `json:"downloadable,omitempty"` + IsDownloadable *bool `json:"is_downloadable,omitempty"` IsUnlisted *bool `json:"is_unlisted,omitempty"` FieldVisibility *FieldVisibility `json:"field_visibility,omitempty" validate:"omitempty"` RemixOf *RemixOf `json:"remix_of,omitempty" validate:"omitempty"` @@ -179,7 +179,7 @@ type UpdateTrackRequest struct { StreamConditions *AccessConditions `json:"stream_conditions,omitempty" validate:"omitempty"` IsStreamGated *bool `json:"is_stream_gated,omitempty"` IsDownloadGated *bool `json:"is_download_gated,omitempty"` - AiAttributionUserId *int `json:"ai_attribution_user_id,omitempty" validate:"omitempty,min=0"` + AiAttributionUserId *trashid.HashId `json:"ai_attribution_user_id,omitempty" validate:"omitempty,min=0"` AllowedApiKeys *[]string `json:"allowed_api_keys,omitempty"` PlacementHosts *string `json:"placement_hosts,omitempty"` DdexApp *string `json:"ddex_app,omitempty"` @@ -235,7 +235,7 @@ func (app *ApiServer) postV1Tracks(c *fiber.Ctx) error { // Determine track ID var trackID int if req.TrackId != nil { - trackID = *req.TrackId + trackID = int(*req.TrackId) } else { // Generate unclaimed track ID if not provided generatedID, err := app.generateUnclaimedId(c.Context(), "tracks", "track_id", 2_000_000, math.MaxInt32) diff --git a/api/v1_users.go b/api/v1_users.go index babc5850..18524ae1 100644 --- a/api/v1_users.go +++ b/api/v1_users.go @@ -24,12 +24,12 @@ type PlaylistLibrary struct { } type Events struct { - Referrer *int `json:"referrer,omitempty" validate:"omitempty,min=1"` - IsMobileUser *bool `json:"is_mobile_user,omitempty"` + Referrer *trashid.HashId `json:"referrer,omitempty" validate:"omitempty,min=1"` + IsMobileUser *bool `json:"is_mobile_user,omitempty"` } type CreateUserRequest struct { - UserId *int `json:"user_id,omitempty" validate:"omitempty,min=1"` + UserId *trashid.HashId `json:"user_id,omitempty" validate:"omitempty,min=1"` Handle string `json:"handle" validate:"required,min=1"` Wallet string `json:"wallet" validate:"required"` Name *string `json:"name,omitempty" validate:"omitempty,min=1"` @@ -66,7 +66,7 @@ type UpdateUserRequest struct { CoverPhotoSizes *string `json:"cover_photo_sizes,omitempty"` ProfileType *string `json:"profile_type,omitempty" validate:"omitempty,oneof=label"` IsDeactivated *bool `json:"is_deactivated,omitempty"` - ArtistPickTrackId *int `json:"artist_pick_track_id,omitempty" validate:"omitempty,min=1"` + ArtistPickTrackId *trashid.HashId `json:"artist_pick_track_id,omitempty" validate:"omitempty,min=1"` AllowAiAttribution *bool `json:"allow_ai_attribution,omitempty"` PlaylistLibrary *PlaylistLibrary `json:"playlist_library,omitempty" validate:"omitempty"` SplUsdcPayoutWallet *string `json:"spl_usdc_payout_wallet,omitempty"` @@ -111,7 +111,7 @@ func (app *ApiServer) postV1Users(c *fiber.Ctx) error { // Determine user ID var userID int if req.UserId != nil { - userID = *req.UserId + userID = int(*req.UserId) } else { // Generate unclaimed user ID if not provided generatedID, err := app.generateUnclaimedId(c.Context(), "users", "user_id", 3_000_000, 999_999_999)