diff --git a/api/swagger/swagger-v1.yaml b/api/swagger/swagger-v1.yaml index 35386bb5..989a8847 100644 --- a/api/swagger/swagger-v1.yaml +++ b/api/swagger/swagger-v1.yaml @@ -311,6 +311,13 @@ paths: required: true schema: type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/react_comment_request_body' + required: true + x-codegen-request-body-name: metadata responses: "200": description: Comment reacted successfully @@ -348,6 +355,13 @@ paths: required: true schema: type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/react_comment_request_body' + required: true + x-codegen-request-body-name: metadata responses: "200": description: Comment unreacted successfully @@ -386,6 +400,13 @@ paths: required: true schema: type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/pin_comment_request_body' + required: true + x-codegen-request-body-name: metadata responses: "200": description: Comment pinned successfully @@ -423,6 +444,13 @@ paths: required: true schema: type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/pin_comment_request_body' + required: true + x-codegen-request-body-name: metadata responses: "200": description: Comment unpinned successfully @@ -10205,11 +10233,30 @@ components: update_comment_request_body: type: object required: + - entityType + - entityId - body properties: + entityType: + allOf: + - $ref: '#/components/schemas/comment_entity_type' + example: "Track" + entityId: + type: integer + description: ID of the entity being commented on + minimum: 1 + example: 12345 body: type: string description: The updated comment text + maxLength: 500 + mentions: + type: array + description: Array of user IDs mentioned in the comment (max 10) + maxItems: 10 + items: + type: integer + minimum: 1 create_comment_request_body: type: object required: @@ -10222,19 +10269,64 @@ components: - $ref: '#/components/schemas/comment_entity_type' example: "Track" entityId: - type: string + type: integer description: ID of the entity being commented on - example: "abc123" + minimum: 1 + example: 12345 body: type: string description: Comment text + maxLength: 500 example: "Great track!" commentId: type: integer - description: Optional comment ID + description: Optional comment ID (will be generated if not provided) + minimum: 1 parentId: type: integer description: Parent comment ID if this is a reply + minimum: 1 + trackTimestampS: + type: integer + description: Timestamp in the track where the comment was made (in seconds) + minimum: 0 + mentions: + type: array + description: Array of user IDs mentioned in the comment (max 10) + maxItems: 10 + items: + type: integer + minimum: 1 + react_comment_request_body: + type: object + required: + - entityType + - entityId + properties: + entityType: + allOf: + - $ref: '#/components/schemas/comment_entity_type' + example: "Track" + entityId: + type: integer + description: ID of the entity (track or playlist) being commented on + minimum: 1 + example: 12345 + pin_comment_request_body: + type: object + required: + - entityType + - entityId + properties: + entityType: + allOf: + - $ref: '#/components/schemas/comment_entity_type' + example: "Track" + entityId: + type: integer + description: ID of the entity (track or playlist) the comment is on + minimum: 1 + example: 12345 create_developer_app_request_body: type: object required: @@ -10345,7 +10437,6 @@ components: description: Whether the deactivation was successful comment_entity_type: type: string - description: Type of entity that can be commented on enum: - Track field_visibility: diff --git a/api/v1_comments.go b/api/v1_comments.go index ff70d761..60b55acd 100644 --- a/api/v1_comments.go +++ b/api/v1_comments.go @@ -23,26 +23,30 @@ type GetCommentsParams struct { } type CreateCommentRequest struct { - EntityType string `json:"entityType" validate:"required,oneof=Track"` - EntityId string `json:"entityId" validate:"required"` - Body string `json:"body" validate:"required"` - CommentId *int `json:"commentId,omitempty"` - ParentId *int `json:"parentId,omitempty"` + EntityType string `json:"entityType" validate:"required,oneof=Track"` + EntityId int `json:"entityId" validate:"required,min=1"` + Body string `json:"body" validate:"required,max=500"` + CommentId *int `json:"commentId,omitempty" validate:"omitempty,min=1"` + ParentId *int `json:"parentId,omitempty" validate:"omitempty,min=1"` + TrackTimestampS *int `json:"trackTimestampS,omitempty" validate:"omitempty,min=0"` + Mentions []int `json:"mentions,omitempty" validate:"omitempty,dive,min=1"` } type UpdateCommentRequest struct { - TrackId string `json:"trackId"` - Body string `json:"body"` + EntityType string `json:"entityType" validate:"required,oneof=Track"` + EntityId int `json:"entityId" validate:"required,min=1"` + Body string `json:"body" validate:"required,max=500"` + Mentions []int `json:"mentions,omitempty" validate:"omitempty,dive,min=1"` } type ReactCommentRequest struct { - TrackId string `json:"trackId"` - IsLiked bool `json:"isLiked"` + EntityType string `json:"entityType" validate:"required,oneof=Track"` + EntityId int `json:"entityId" validate:"required,min=1"` } type PinCommentRequest struct { - TrackId string `json:"trackId"` - IsPin bool `json:"isPin"` + EntityType string `json:"entityType" validate:"required,oneof=Track"` + EntityId int `json:"entityId" validate:"required,min=1"` } func (app *ApiServer) queryFullComments( @@ -159,6 +163,17 @@ func (app *ApiServer) postV1Comment(c *fiber.Ctx) error { if req.ParentId != nil { metadataMap["parent_id"] = *req.ParentId } + if req.TrackTimestampS != nil { + metadataMap["track_timestamp_s"] = *req.TrackTimestampS + } + if len(req.Mentions) > 0 { + // Limit to first 10 mentions + mentions := req.Mentions + if len(mentions) > 10 { + mentions = mentions[:10] + } + metadataMap["mentions"] = mentions + } metadataObj := map[string]interface{}{ "cid": "", @@ -213,12 +228,23 @@ func (app *ApiServer) putV1Comment(c *fiber.Ctx) error { nonce := time.Now().UnixNano() + metadataMap := map[string]interface{}{ + "entity_type": req.EntityType, + "entity_id": req.EntityId, + "body": req.Body, + } + if len(req.Mentions) > 0 { + // Limit to first 10 mentions + mentions := req.Mentions + if len(mentions) > 10 { + mentions = mentions[:10] + } + metadataMap["mentions"] = mentions + } + metadataObj := map[string]interface{}{ - "cid": "", - "data": map[string]interface{}{ - "entity_id": req.TrackId, - "body": req.Body, - }, + "cid": "", + "data": metadataMap, } metadataBytes, _ := json.Marshal(metadataObj) @@ -306,15 +332,12 @@ func (app *ApiServer) postV1CommentReact(c *fiber.Ctx) error { nonce := time.Now().UnixNano() action := indexer.Action_React - if !req.IsLiked { - action = indexer.Action_Unreact - } metadataObj := map[string]interface{}{ "cid": "", "data": map[string]interface{}{ - "entity_id": req.TrackId, - "entity_type": indexer.Entity_Track, + "entity_id": req.EntityId, + "entity_type": req.EntityType, }, } metadataBytes, _ := json.Marshal(metadataObj) @@ -367,8 +390,8 @@ func (app *ApiServer) deleteV1CommentReact(c *fiber.Ctx) error { metadataObj := map[string]interface{}{ "cid": "", "data": map[string]interface{}{ - "entity_id": req.TrackId, - "entity_type": indexer.Entity_Track, + "entity_id": req.EntityId, + "entity_type": req.EntityType, }, } metadataBytes, _ := json.Marshal(metadataObj) @@ -419,14 +442,12 @@ func (app *ApiServer) postV1CommentPin(c *fiber.Ctx) error { nonce := time.Now().UnixNano() action := indexer.Action_Pin - if !req.IsPin { - action = indexer.Action_Unpin - } metadataObj := map[string]interface{}{ "cid": "", "data": map[string]interface{}{ - "entity_id": req.TrackId, + "entity_type": req.EntityType, + "entity_id": req.EntityId, }, } metadataBytes, _ := json.Marshal(metadataObj) @@ -479,7 +500,8 @@ func (app *ApiServer) deleteV1CommentPin(c *fiber.Ctx) error { metadataObj := map[string]interface{}{ "cid": "", "data": map[string]interface{}{ - "entity_id": req.TrackId, + "entity_type": req.EntityType, + "entity_id": req.EntityId, }, } metadataBytes, _ := json.Marshal(metadataObj)