From 80d9224259ae993c78eb4de7081fe8781a9dea17 Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:31:17 -0800 Subject: [PATCH 01/15] add a bunch of missing track fields, make access gate a discriminated union --- api/swagger/swagger-v1.yaml | 141 ++++++++++++++++++++++++++++++------ 1 file changed, 117 insertions(+), 24 deletions(-) diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index b600fd9b..8d2d1b09 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -7906,18 +7906,12 @@ components: items: type: string access_gate: - type: object - properties: - usdc_purchase: - $ref: '#/components/schemas/extended_purchase_gate' - follow_user_id: - type: integer - tip_user_id: - type: integer - nft_collection: - type: object - token_gate: - $ref: '#/components/schemas/extended_token_gate' + oneOf: + - $ref: '#/components/schemas/tip_gate' + - $ref: '#/components/schemas/follow_gate' + - $ref: '#/components/schemas/extended_purchase_gate' + - $ref: '#/components/schemas/nft_gate' + - $ref: '#/components/schemas/token_gate' nft_collection: required: - address @@ -9774,6 +9768,12 @@ components: maxLength: 1000 mood: $ref: '#/components/schemas/mood' + bpm: + type: number + description: Beats per minute (tempo) + musical_key: + type: string + description: Musical key of the track tags: type: string description: Comma-separated tags @@ -9792,9 +9792,18 @@ components: track_cid: type: string description: IPFS CID for the track audio file (required) + orig_file_cid: + type: string + description: IPFS CID for the original track file + orig_filename: + type: string + description: Original filename of the track cover_art_cid: type: string description: IPFS CID for cover art + cover_art_sizes: + type: string + description: Cover art sizes metadata preview_cid: type: string description: IPFS CID for the track preview @@ -9814,6 +9823,15 @@ components: is_unlisted: type: boolean description: Whether the track is unlisted + stream_conditions: + $ref: '#/components/schemas/access_gate' + download_conditions: + $ref: '#/components/schemas/access_gate' + field_visibility: + $ref: '#/components/schemas/field_visibility' + placement_hosts: + type: string + description: Placement hosts for the track ddex_app: type: string description: DDEX application identifier @@ -9824,37 +9842,90 @@ components: type: object description: Request body for updating track information. All fields are optional. properties: + track_id: + type: string + description: Optional track ID (will be generated if not provided) title: type: string description: Track title + genre: + $ref: '#/components/schemas/genre' description: type: string description: Track description - maxLength: 5000 - genre: - $ref: '#/components/schemas/genre' + maxLength: 1000 mood: $ref: '#/components/schemas/mood' + bpm: + type: number + description: Beats per minute (tempo) + musical_key: + type: string + description: Musical key of the track tags: type: string description: Comma-separated tags - release_date: + license: type: string - format: date-time - description: Track release date + description: License type isrc: type: string description: International Standard Recording Code - is_downloadable: + iswc: + type: string + description: International Standard Musical Work Code + release_date: + type: string + description: Release date + track_cid: + type: string + description: IPFS CID for the track audio file + orig_file_cid: + type: string + description: IPFS CID for the original track file + orig_filename: + type: string + description: Original filename of the track + cover_art_cid: + type: string + description: IPFS CID for cover art + cover_art_sizes: + type: string + description: Cover art sizes metadata + preview_cid: + type: string + description: IPFS CID for the track preview + preview_start_seconds: + type: number + format: float + description: Preview start time in seconds + minimum: 0 + duration: + type: number + format: float + description: Track duration in seconds + minimum: 0 + downloadable: type: boolean description: Whether the track is downloadable - is_original_available: + is_unlisted: type: boolean - description: Whether the original file is available - artwork_url: + description: Whether the track is unlisted + stream_conditions: + $ref: '#/components/schemas/access_gate' + download_conditions: + $ref: '#/components/schemas/access_gate' + field_visibility: + $ref: '#/components/schemas/field_visibility' + placement_hosts: type: string - description: URL for track artwork - format: uri + description: Placement hosts for the track + ddex_app: + type: string + description: DDEX application identifier + parental_warning_type: + type: string + description: Parental warning type create_playlist_request_body: type: object required: @@ -10211,6 +10282,28 @@ components: description: Type of entity that can be commented on enum: - Track + field_visibility: + required: + - genre + - mood + - play_count + - remixes + - share + - tags + type: object + properties: + mood: + type: boolean + tags: + type: boolean + genre: + type: boolean + share: + type: boolean + play_count: + type: boolean + remixes: + type: boolean genre: type: string description: Music genre From beb705d92967a789c719fc26b01911b02ec98632 Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:39:47 -0800 Subject: [PATCH 02/15] add stem_of and remix_of to writes --- api/swagger/swagger-v1.yaml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index 8d2d1b09..068e4864 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -6897,6 +6897,13 @@ components: type: array items: $ref: '#/components/schemas/track_element' + remix_parent_write: + type: object + properties: + tracks: + type: array + items: + $ref: '#/components/schemas/track_element_write' track_element: required: - parent_track_id @@ -6904,6 +6911,13 @@ components: properties: parent_track_id: type: string + track_element_write: + required: + - parent_track_id + type: object + properties: + parent_track_id: + type: integer album_backlink: required: - permalink @@ -8107,6 +8121,16 @@ components: type: integer orig_filename: type: string + stem_parent: + required: + - category + - parent_track_id + type: object + properties: + category: + type: string + parent_track_id: + type: integer undisbursed_challenges: type: object properties: @@ -9832,6 +9856,10 @@ components: placement_hosts: type: string description: Placement hosts for the track + stem_of: + $ref: '#/components/schemas/stem_parent' + remix_of: + $ref: '#/components/schemas/remix_parent_write' ddex_app: type: string description: DDEX application identifier @@ -9920,6 +9948,10 @@ components: placement_hosts: type: string description: Placement hosts for the track + stem_of: + $ref: '#/components/schemas/stem_parent' + remix_of: + $ref: '#/components/schemas/remix_parent_write' ddex_app: type: string description: DDEX application identifier From 3099996b872969729b52be4d34d514a3c4d32afb Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:44:38 -0800 Subject: [PATCH 03/15] remove nft gate --- api/swagger/swagger-v1.yaml | 39 ------------------------------------- 1 file changed, 39 deletions(-) diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index 068e4864..8e74bfd1 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -7820,7 +7820,6 @@ components: - $ref: '#/components/schemas/tip_gate' - $ref: '#/components/schemas/follow_gate' - $ref: '#/components/schemas/extended_purchase_gate' - - $ref: '#/components/schemas/nft_gate' - $ref: '#/components/schemas/token_gate' tip_gate: required: @@ -7900,16 +7899,6 @@ components: type: string amount: type: integer - nft_gate: - required: - - nft_collection - type: object - properties: - nft_collection: - type: object - description: Must hold an NFT of the given collection to unlock - allOf: - - $ref: '#/components/schemas/nft_collection' media_link: type: object properties: @@ -7924,35 +7913,7 @@ components: - $ref: '#/components/schemas/tip_gate' - $ref: '#/components/schemas/follow_gate' - $ref: '#/components/schemas/extended_purchase_gate' - - $ref: '#/components/schemas/nft_gate' - $ref: '#/components/schemas/token_gate' - nft_collection: - required: - - address - - chain - - name - type: object - properties: - chain: - type: string - example: eth - enum: - - eth - - sol - standard: - type: string - example: ERC721 - enum: - - ERC721 - - ERC1155 - address: - type: string - name: - type: string - imageUrl: - type: string - externalLink: - type: string track_response: type: object properties: From bb33639939ee704e7f261bb60a09678f50666bdb Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:48:18 -0800 Subject: [PATCH 04/15] make release dates formatted as dates --- api/swagger/swagger-v1.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index 8e74bfd1..03a1094a 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -6731,6 +6731,7 @@ components: type: string release_date: type: string + format: date isrc: type: string remix_of: @@ -7106,6 +7107,7 @@ components: type: boolean release_date: type: string + format: date ddex_release_ids: type: object properties: {} @@ -9773,6 +9775,7 @@ components: description: International Standard Musical Work Code release_date: type: string + format: date description: Release date track_cid: type: string @@ -9865,6 +9868,7 @@ components: description: International Standard Musical Work Code release_date: type: string + format: date description: Release date track_cid: type: string From f01429c3c22fceb67380cfe362e6c8094ec685a9 Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:59:47 -0800 Subject: [PATCH 05/15] add user_id to share track --- api/swagger/swagger-v1.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index 03a1094a..8cab2237 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -3176,6 +3176,12 @@ paths: required: true schema: type: string + - name: user_id + in: query + description: User ID + required: true + schema: + type: string responses: "200": description: Track share recorded successfully From cd9670e798c7bffc8d9129eb8af5d5d1e483d78b Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 21:26:44 -0800 Subject: [PATCH 06/15] use unclaimed ids, int ids in requests --- api/swagger/swagger-v1.yaml | 9 ++++++--- api/v1_playlist.go | 17 +++++++++-------- api/v1_track.go | 17 +++++++++-------- api/v1_unclaimed_id.go | 20 ++++++++++++-------- api/v1_users.go | 16 ++++++++-------- 5 files changed, 44 insertions(+), 35 deletions(-) diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index 8cab2237..206ba2bd 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -9747,8 +9747,9 @@ components: - track_cid properties: track_id: - type: string + type: integer description: Optional track ID (will be generated if not provided) + minimum: 1 title: type: string description: Track title @@ -9935,8 +9936,9 @@ components: - playlist_name properties: playlist_id: - type: string + type: integer description: Optional playlist ID (will be generated if not provided) + minimum: 1 playlist_name: type: string description: Playlist or album name @@ -10017,8 +10019,9 @@ components: - wallet properties: user_id: - type: string + type: integer description: Optional user ID (will be generated if not provided) + minimum: 1 handle: type: string description: User handle (unique username) diff --git a/api/v1_playlist.go b/api/v1_playlist.go index fa3a3fa2..bc57a4db 100644 --- a/api/v1_playlist.go +++ b/api/v1_playlist.go @@ -2,6 +2,7 @@ package api import ( "encoding/json" + "math" "strconv" "time" @@ -21,7 +22,7 @@ type PlaylistTrackInfo struct { } type CreatePlaylistRequest struct { - PlaylistId *string `json:"playlist_id,omitempty"` + PlaylistId *int `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"` @@ -107,16 +108,16 @@ func (app *ApiServer) postV1Playlists(c *fiber.Ctx) error { // Determine playlist ID var playlistID int if req.PlaylistId != nil { - decodedID, err := trashid.DecodeHashId(*req.PlaylistId) + playlistID = *req.PlaylistId + } else { + // Generate unclaimed playlist ID if not provided + generatedID, err := app.generateUnclaimedId(c.Context(), "tracks", "track_id", 400_000, math.MaxInt32) if err != nil { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ - "error": "Invalid playlist_id: " + err.Error(), + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to generate playlist ID: " + err.Error(), }) } - playlistID = decodedID - } else { - // Generate playlist ID from timestamp if not provided - playlistID = int(time.Now().UnixNano() % 1000000000) + playlistID = generatedID } // Convert struct to map for metadata diff --git a/api/v1_track.go b/api/v1_track.go index 7978af94..02fc03ce 100644 --- a/api/v1_track.go +++ b/api/v1_track.go @@ -2,6 +2,7 @@ package api import ( "encoding/json" + "math" "strconv" "time" @@ -113,7 +114,7 @@ type DDEXRightsController struct { } type CreateTrackRequest struct { - TrackId *string `json:"track_id,omitempty"` + TrackId *int `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"` @@ -234,16 +235,16 @@ func (app *ApiServer) postV1Tracks(c *fiber.Ctx) error { // Determine track ID var trackID int if req.TrackId != nil { - decodedID, err := trashid.DecodeHashId(*req.TrackId) + trackID = *req.TrackId + } else { + // Generate unclaimed track ID if not provided + generatedID, err := app.generateUnclaimedId(c.Context(), "tracks", "track_id", 2_000_000, math.MaxInt32) if err != nil { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ - "error": "Invalid track_id: " + err.Error(), + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to generate track ID: " + err.Error(), }) } - trackID = decodedID - } else { - // Generate track ID from timestamp if not provided - trackID = int(time.Now().UnixNano() % 1000000000) + trackID = generatedID } // Convert struct to map for metadata diff --git a/api/v1_unclaimed_id.go b/api/v1_unclaimed_id.go index 7911e9b6..fe77126b 100644 --- a/api/v1_unclaimed_id.go +++ b/api/v1_unclaimed_id.go @@ -1,6 +1,7 @@ package api import ( + "context" "fmt" "math" "math/rand" @@ -10,23 +11,26 @@ import ( "github.com/jackc/pgx/v5" ) -func (app *ApiServer) v1UnclaimedId(c *fiber.Ctx, tableName, idField string, lowerBound, upperBound int) error { - +// generateUnclaimedId finds an unclaimed integer ID in the given range for the specified table +func (app *ApiServer) generateUnclaimedId(ctx context.Context, tableName, idField string, lowerBound, upperBound int) (int, error) { sql := fmt.Sprintf(`select true from %s where %s = $1`, tableName, idField) - freeId := 0 for i := 0; i < 50; i++ { randomId := lowerBound + rand.Intn(upperBound-lowerBound) isTaken := false - err := app.pool.QueryRow(c.Context(), sql, randomId).Scan(&isTaken) + err := app.pool.QueryRow(ctx, sql, randomId).Scan(&isTaken) if err == pgx.ErrNoRows { - freeId = randomId - break + return randomId, nil } } - if freeId == 0 { - return fiber.NewError(500, "unable to find unclaimed id") + return 0, fmt.Errorf("unable to find unclaimed id after 50 attempts") +} + +func (app *ApiServer) v1UnclaimedId(c *fiber.Ctx, tableName, idField string, lowerBound, upperBound int) error { + freeId, err := app.generateUnclaimedId(c.Context(), tableName, idField, lowerBound, upperBound) + if err != nil { + return fiber.NewError(500, err.Error()) } id, _ := trashid.EncodeHashId(freeId) diff --git a/api/v1_users.go b/api/v1_users.go index 59a0afba..26ce93eb 100644 --- a/api/v1_users.go +++ b/api/v1_users.go @@ -27,7 +27,7 @@ type PlaylistLibrary struct { } type CreateUserRequest struct { - UserId *string `json:"user_id,omitempty"` + UserId *int `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"` @@ -106,16 +106,16 @@ func (app *ApiServer) postV1Users(c *fiber.Ctx) error { // Determine user ID var userID int if req.UserId != nil { - decodedID, err := trashid.DecodeHashId(*req.UserId) + userID = *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) if err != nil { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ - "error": "Invalid user_id: " + err.Error(), + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to generate user ID: " + err.Error(), }) } - userID = decodedID - } else { - // Generate user ID from timestamp if not provided - userID = int(time.Now().UnixNano() % 1000000000) + userID = generatedID } // Convert struct to map for metadata From bf3065a9ae069e9e6a4e01f5b72a942eeb5c0a50 Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 21:28:00 -0800 Subject: [PATCH 07/15] use generated ids for comments --- api/v1_comments.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/api/v1_comments.go b/api/v1_comments.go index 452e9a02..ff70d761 100644 --- a/api/v1_comments.go +++ b/api/v1_comments.go @@ -2,6 +2,7 @@ package api import ( "encoding/json" + "math" "strconv" "time" @@ -139,8 +140,14 @@ func (app *ApiServer) postV1Comment(c *fiber.Ctx) error { if req.CommentId != nil { commentID = *req.CommentId } else { - // Generate random comment ID if not provided - commentID = int(nonce % 1000000) + // Generate unclaimed comment ID if not provided + generatedID, err := app.generateUnclaimedId(c.Context(), "comments", "comment_id", 4_000_000, math.MaxInt32) + if err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to generate comment ID: " + err.Error(), + }) + } + commentID = generatedID } // Build metadata From 02e55da5a5dfb22b07189230d10812d0bfdb7b5f Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 21:32:14 -0800 Subject: [PATCH 08/15] remove track id from update track --- api/swagger/swagger-v1.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index 206ba2bd..8fba9a0c 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -9841,9 +9841,6 @@ components: type: object description: Request body for updating track information. All fields are optional. properties: - track_id: - type: string - description: Optional track ID (will be generated if not provided) title: type: string description: Track title From 933bcba2d013f6915266792d0aafd7d43ee92b4a Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 21:32:55 -0800 Subject: [PATCH 09/15] allow explicity unsetting fields in track updates --- api/swagger/swagger-v1.yaml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index 8fba9a0c..fc4c0adb 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -9848,27 +9848,34 @@ components: $ref: '#/components/schemas/genre' description: type: string + nullable: true description: Track description maxLength: 1000 mood: $ref: '#/components/schemas/mood' bpm: type: number + nullable: true description: Beats per minute (tempo) musical_key: type: string + nullable: true description: Musical key of the track tags: type: string + nullable: true description: Comma-separated tags license: type: string + nullable: true description: License type isrc: type: string + nullable: true description: International Standard Recording Code iswc: type: string + nullable: true description: International Standard Musical Work Code release_date: type: string @@ -9909,9 +9916,13 @@ components: type: boolean description: Whether the track is unlisted stream_conditions: - $ref: '#/components/schemas/access_gate' + nullable: true + allOf: + - $ref: '#/components/schemas/access_gate' download_conditions: - $ref: '#/components/schemas/access_gate' + nullable: true + allOf: + - $ref: '#/components/schemas/access_gate' field_visibility: $ref: '#/components/schemas/field_visibility' placement_hosts: @@ -9923,9 +9934,11 @@ components: $ref: '#/components/schemas/remix_parent_write' ddex_app: type: string + nullable: true description: DDEX application identifier parental_warning_type: type: string + nullable: true description: Parental warning type create_playlist_request_body: type: object From 83331e7c86528cc90fe3552cc66845699b910a15 Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 22:36:56 -0800 Subject: [PATCH 10/15] small nullable things and optional things --- api/swagger/swagger-v1.yaml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index fc4c0adb..628f8797 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -6906,6 +6906,8 @@ components: $ref: '#/components/schemas/track_element' remix_parent_write: type: object + required: + - tracks properties: tracks: type: array @@ -9852,7 +9854,9 @@ components: description: Track description maxLength: 1000 mood: - $ref: '#/components/schemas/mood' + nullable: true + allOf: + - $ref: '#/components/schemas/mood' bpm: type: number nullable: true @@ -10299,13 +10303,6 @@ components: enum: - Track field_visibility: - required: - - genre - - mood - - play_count - - remixes - - share - - tags type: object properties: mood: From 039c871a0551a46dd1ea4d65d44dbffe4a72ab92 Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 22:42:53 -0800 Subject: [PATCH 11/15] add stem category enum --- api/swagger/swagger-v1.yaml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index 628f8797..9f0a3a5a 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -8092,6 +8092,21 @@ components: type: integer orig_filename: type: string + stem_category: + type: string + enum: + - INSTRUMENTAL + - LEAD_VOCALS + - MELODIC_LEAD + - PAD + - SNARE + - KICK + - HIHAT + - PERCUSSION + - SAMPLE + - BACKING_VOX + - BASS + - OTHER stem_parent: required: - category @@ -8099,7 +8114,7 @@ components: type: object properties: category: - type: string + $ref: '#/components/schemas/stem_category' parent_track_id: type: integer undisbursed_challenges: From b600f3ecf2a90a50975ff70d8bbcb11d0e9fba50 Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 22:43:39 -0800 Subject: [PATCH 12/15] Update stem categories --- api/v1_track.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/v1_track.go b/api/v1_track.go index 02fc03ce..220b2536 100644 --- a/api/v1_track.go +++ b/api/v1_track.go @@ -26,7 +26,7 @@ type RemixOf struct { } type StemOf struct { - Category string `json:"category" validate:"required,oneof=BASS DRUMS MELODY VOCALS OTHER"` + Category string `json:"category" validate:"required,oneof=INSTRUMENTAL LEAD_VOCALS MELODIC_LEAD PAD SNARE KICK HIHAT PERCUSSION SAMPLE BACKING_VOX BASS OTHER"` ParentTrackId string `json:"parent_track_id" validate:"required"` } From 0e7268fb8aee27dff4d55b8ad87c60da6f7d829a Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 22:44:55 -0800 Subject: [PATCH 13/15] parent track ids should be integers --- api/v1_track.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/v1_track.go b/api/v1_track.go index 220b2536..b57102d3 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 string `json:"parent_track_id" validate:"required"` + ParentTrackId int `json:"parent_track_id" validate:"required,min=1"` } type RemixOf struct { @@ -27,7 +27,7 @@ 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 string `json:"parent_track_id" validate:"required"` + ParentTrackId int `json:"parent_track_id" validate:"required,min=1"` } type FieldVisibility struct { From 3914a4396d0527d52ecd7a932bed6e667617ccd7 Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 22:57:02 -0800 Subject: [PATCH 14/15] add some more playlist/album fields --- api/swagger/swagger-v1.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index 9f0a3a5a..947d0e5a 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -10030,6 +10030,20 @@ components: is_private: type: boolean description: Whether the playlist is private + genre: + $ref: '#/components/schemas/genre' + mood: + $ref: '#/components/schemas/mood' + tags: + type: string + description: Comma-separated tags + license: + type: string + description: License type + release_date: + type: string + format: date + description: Release date playlist_contents: type: array description: Array of track IDs to include in the playlist From 9a91b94596f36e9d9f463c9cc11ba8e04bb1ab68 Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Thu, 12 Feb 2026 23:05:11 -0800 Subject: [PATCH 15/15] name the request bodies "metadata" --- api/swagger/swagger-v1.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index 947d0e5a..ca6eea45 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -982,6 +982,7 @@ paths: schema: type: string requestBody: + x-codegen-request-body-name: metadata required: true content: application/json: @@ -1221,6 +1222,7 @@ paths: schema: type: string requestBody: + x-codegen-request-body-name: metadata required: true content: application/json: @@ -1697,6 +1699,7 @@ paths: schema: type: string requestBody: + x-codegen-request-body-name: metadata required: true content: application/json: @@ -2521,6 +2524,7 @@ paths: schema: type: string requestBody: + x-codegen-request-body-name: metadata required: true content: application/json: @@ -3417,6 +3421,7 @@ paths: schema: type: string requestBody: + x-codegen-request-body-name: metadata required: true content: application/json: @@ -3834,6 +3839,7 @@ paths: schema: type: string requestBody: + x-codegen-request-body-name: metadata required: true content: application/json: