From fc5a2b26752825eb6131540b6a24750480b982b3 Mon Sep 17 00:00:00 2001 From: Thomas Rademaker Date: Fri, 20 Mar 2026 14:32:29 -0400 Subject: [PATCH] snake_case --- appview/database/models.go | 174 ++++++++++++++--------------- appview/handlers/bookmark.go | 33 +++++- appview/handlers/comment.go | 65 ++++++++++- appview/handlers/episode_state.go | 2 +- appview/handlers/list.go | 39 +++++-- appview/handlers/profile.go | 19 ++-- appview/handlers/recommendation.go | 37 +++++- appview/handlers/social.go | 14 +-- appview/handlers/subscription.go | 33 +++++- 9 files changed, 294 insertions(+), 122 deletions(-) diff --git a/appview/database/models.go b/appview/database/models.go index 1be1cf7..56fff0c 100644 --- a/appview/database/models.go +++ b/appview/database/models.go @@ -11,87 +11,87 @@ type FirehoseCursor struct { func (FirehoseCursor) TableName() string { return "firehose_cursor" } type Subscription struct { - ID uint `gorm:"primaryKey"` - DID string `gorm:"column:did;size:255;not null;index:idx_subscriptions_did_rkey,unique;index:idx_subscriptions_did"` - Rkey string `gorm:"size:512;not null;index:idx_subscriptions_did_rkey,unique"` - FeedID int64 `gorm:"not null;index:idx_subscriptions_feed_id"` - FeedURL string `gorm:"size:2048"` - PodcastGuid string `gorm:"size:512"` - CreatedAt string `gorm:"size:64;not null"` - IndexedAt time.Time `gorm:"autoCreateTime"` + ID uint `gorm:"primaryKey" json:"-"` + DID string `gorm:"column:did;size:255;not null;index:idx_subscriptions_did_rkey,unique;index:idx_subscriptions_did" json:"did"` + Rkey string `gorm:"size:512;not null;index:idx_subscriptions_did_rkey,unique" json:"rkey"` + FeedID int64 `gorm:"not null;index:idx_subscriptions_feed_id" json:"feed_id"` + FeedURL string `gorm:"size:2048" json:"feed_url"` + PodcastGuid string `gorm:"size:512" json:"podcast_guid"` + CreatedAt string `gorm:"size:64;not null" json:"created_at"` + IndexedAt time.Time `gorm:"autoCreateTime" json:"-"` } func (Subscription) TableName() string { return "subscriptions" } type Comment struct { - ID uint `gorm:"primaryKey"` - DID string `gorm:"column:did;size:255;not null;index:idx_comments_did_rkey,unique;index:idx_comments_did"` - Rkey string `gorm:"size:512;not null;index:idx_comments_did_rkey,unique"` - ATURI string `gorm:"column:at_uri;size:1024;index;not null"` - FeedID int64 `gorm:"not null;index:idx_comments_episode"` - EpisodeID int64 `gorm:"not null;index:idx_comments_episode"` - EpisodeGuid string `gorm:"size:512"` - PodcastGuid string `gorm:"size:512"` - Text string `gorm:"type:text;not null"` - TimestampS *int `gorm:"index"` - ReplyRoot string `gorm:"size:1024;index:idx_comments_reply_root"` - ReplyParent string `gorm:"size:1024"` - Facets []byte `gorm:"type:jsonb"` - CreatedAt string `gorm:"size:64;not null"` - IndexedAt time.Time `gorm:"autoCreateTime"` + ID uint `gorm:"primaryKey" json:"-"` + DID string `gorm:"column:did;size:255;not null;index:idx_comments_did_rkey,unique;index:idx_comments_did" json:"did"` + Rkey string `gorm:"size:512;not null;index:idx_comments_did_rkey,unique" json:"rkey"` + ATURI string `gorm:"column:at_uri;size:1024;index;not null" json:"at_uri"` + FeedID int64 `gorm:"not null;index:idx_comments_episode" json:"feed_id"` + EpisodeID int64 `gorm:"not null;index:idx_comments_episode" json:"episode_id"` + EpisodeGuid string `gorm:"size:512" json:"episode_guid"` + PodcastGuid string `gorm:"size:512" json:"podcast_guid"` + Text string `gorm:"type:text;not null" json:"text"` + TimestampS *int `gorm:"index" json:"timestamp_s"` + ReplyRoot string `gorm:"size:1024;index:idx_comments_reply_root" json:"reply_root"` + ReplyParent string `gorm:"size:1024" json:"reply_parent"` + Facets []byte `gorm:"type:jsonb" json:"facets"` + CreatedAt string `gorm:"size:64;not null" json:"created_at"` + IndexedAt time.Time `gorm:"autoCreateTime" json:"-"` } func (Comment) TableName() string { return "comments" } type Recommendation struct { - ID uint `gorm:"primaryKey"` - DID string `gorm:"column:did;size:255;not null;index:idx_recommendations_did_rkey,unique;index:idx_recommendations_did"` - Rkey string `gorm:"size:512;not null;index:idx_recommendations_did_rkey,unique"` - FeedID int64 `gorm:"not null;index:idx_recommendations_episode"` - EpisodeID int64 `gorm:"not null;index:idx_recommendations_episode"` - EpisodeGuid string `gorm:"size:512"` - PodcastGuid string `gorm:"size:512"` - Text string `gorm:"type:text"` - CreatedAt string `gorm:"size:64;not null"` - IndexedAt time.Time `gorm:"autoCreateTime"` + ID uint `gorm:"primaryKey" json:"-"` + DID string `gorm:"column:did;size:255;not null;index:idx_recommendations_did_rkey,unique;index:idx_recommendations_did" json:"did"` + Rkey string `gorm:"size:512;not null;index:idx_recommendations_did_rkey,unique" json:"rkey"` + FeedID int64 `gorm:"not null;index:idx_recommendations_episode" json:"feed_id"` + EpisodeID int64 `gorm:"not null;index:idx_recommendations_episode" json:"episode_id"` + EpisodeGuid string `gorm:"size:512" json:"episode_guid"` + PodcastGuid string `gorm:"size:512" json:"podcast_guid"` + Text string `gorm:"type:text" json:"text"` + CreatedAt string `gorm:"size:64;not null" json:"created_at"` + IndexedAt time.Time `gorm:"autoCreateTime" json:"-"` } func (Recommendation) TableName() string { return "recommendations" } type PodcastList struct { - ID uint `gorm:"primaryKey"` - DID string `gorm:"column:did;size:255;not null;index:idx_lists_did_rkey,unique;index:idx_lists_did"` - Rkey string `gorm:"size:512;not null;index:idx_lists_did_rkey,unique"` - Name string `gorm:"size:500;not null"` - Description string `gorm:"type:text"` - Podcasts []byte `gorm:"type:jsonb;not null"` - CreatedAt string `gorm:"size:64;not null"` - IndexedAt time.Time `gorm:"autoCreateTime"` + ID uint `gorm:"primaryKey" json:"-"` + DID string `gorm:"column:did;size:255;not null;index:idx_lists_did_rkey,unique;index:idx_lists_did" json:"did"` + Rkey string `gorm:"size:512;not null;index:idx_lists_did_rkey,unique" json:"rkey"` + Name string `gorm:"size:500;not null" json:"name"` + Description string `gorm:"type:text" json:"description"` + Podcasts []byte `gorm:"type:jsonb;not null" json:"-"` + CreatedAt string `gorm:"size:64;not null" json:"created_at"` + IndexedAt time.Time `gorm:"autoCreateTime" json:"-"` } func (PodcastList) TableName() string { return "podcast_lists" } type Bookmark struct { - ID uint `gorm:"primaryKey"` - DID string `gorm:"column:did;size:255;not null;index:idx_bookmarks_did_rkey,unique;index:idx_bookmarks_did"` - Rkey string `gorm:"size:512;not null;index:idx_bookmarks_did_rkey,unique"` - FeedID int64 `gorm:"not null;index:idx_bookmarks_episode"` - EpisodeID int64 `gorm:"not null;index:idx_bookmarks_episode"` - EpisodeGuid string `gorm:"size:512"` - PodcastGuid string `gorm:"size:512"` - TimestampS *int `gorm:"index"` - CreatedAt string `gorm:"size:64;not null"` - IndexedAt time.Time `gorm:"autoCreateTime"` + ID uint `gorm:"primaryKey" json:"-"` + DID string `gorm:"column:did;size:255;not null;index:idx_bookmarks_did_rkey,unique;index:idx_bookmarks_did" json:"did"` + Rkey string `gorm:"size:512;not null;index:idx_bookmarks_did_rkey,unique" json:"rkey"` + FeedID int64 `gorm:"not null;index:idx_bookmarks_episode" json:"feed_id"` + EpisodeID int64 `gorm:"not null;index:idx_bookmarks_episode" json:"episode_id"` + EpisodeGuid string `gorm:"size:512" json:"episode_guid"` + PodcastGuid string `gorm:"size:512" json:"podcast_guid"` + TimestampS *int `gorm:"index" json:"timestamp"` + CreatedAt string `gorm:"size:64;not null" json:"created_at"` + IndexedAt time.Time `gorm:"autoCreateTime" json:"-"` } func (Bookmark) TableName() string { return "bookmarks" } type Profile struct { - DID string `gorm:"column:did;primaryKey;size:255"` - DisplayName string `gorm:"size:640"` - Description string `gorm:"type:text"` - FavoriteGenres []byte `gorm:"type:jsonb"` - IndexedAt time.Time `gorm:"autoCreateTime"` + DID string `gorm:"column:did;primaryKey;size:255" json:"did"` + DisplayName string `gorm:"size:640" json:"display_name"` + Description string `gorm:"type:text" json:"description"` + FavoriteGenres []byte `gorm:"type:jsonb" json:"-"` + IndexedAt time.Time `gorm:"autoCreateTime" json:"-"` } func (Profile) TableName() string { return "profiles" } @@ -129,47 +129,47 @@ type EpisodeStats struct { func (EpisodeStats) TableName() string { return "episode_stats" } type EpisodeState struct { - ID uint `gorm:"primaryKey"` - DID string `gorm:"column:did;size:255;not null;index:idx_episode_states_did_rkey,unique;index:idx_episode_states_did"` - Rkey string `gorm:"size:512;not null;index:idx_episode_states_did_rkey,unique"` - FeedID int64 `gorm:"not null;index:idx_episode_states_episode,unique"` - EpisodeID int64 `gorm:"not null;index:idx_episode_states_episode,unique"` - EpisodeGuid string `gorm:"size:512"` - PodcastGuid string `gorm:"size:512"` - PositionS *int - DurationS *int - Played bool `gorm:"default:false"` - Saved bool `gorm:"default:false"` - Hidden bool `gorm:"default:false"` - UpdatedAt string `gorm:"size:64"` - CreatedAt string `gorm:"size:64;not null"` - IndexedAt time.Time `gorm:"autoCreateTime"` + ID uint `gorm:"primaryKey" json:"-"` + DID string `gorm:"column:did;size:255;not null;index:idx_episode_states_did_rkey,unique;index:idx_episode_states_did" json:"did"` + Rkey string `gorm:"size:512;not null;index:idx_episode_states_did_rkey,unique" json:"rkey"` + FeedID int64 `gorm:"not null;index:idx_episode_states_episode,unique" json:"feed_id"` + EpisodeID int64 `gorm:"not null;index:idx_episode_states_episode,unique" json:"episode_id"` + EpisodeGuid string `gorm:"size:512" json:"episode_guid"` + PodcastGuid string `gorm:"size:512" json:"podcast_guid"` + PositionS *int `json:"position_s"` + DurationS *int `json:"duration_s"` + Played bool `gorm:"default:false" json:"played"` + Saved bool `gorm:"default:false" json:"saved"` + Hidden bool `gorm:"default:false" json:"hidden"` + UpdatedAt string `gorm:"size:64" json:"updated_at"` + CreatedAt string `gorm:"size:64;not null" json:"created_at"` + IndexedAt time.Time `gorm:"autoCreateTime" json:"-"` } func (EpisodeState) TableName() string { return "episode_states" } type Block struct { - ID uint `gorm:"primaryKey"` - DID string `gorm:"column:did;size:255;not null;index:idx_blocks_did_rkey,unique;index:idx_blocks_did;index:idx_blocks_did_subject,unique"` - Rkey string `gorm:"size:512;not null;index:idx_blocks_did_rkey,unique"` - ATURI string `gorm:"column:at_uri;size:1024;not null;index"` - SubjectDID string `gorm:"column:subject_did;size:255;not null;index:idx_blocks_subject;index:idx_blocks_did_subject,unique"` - CreatedAt string `gorm:"size:64;not null"` - IndexedAt time.Time `gorm:"autoCreateTime"` + ID uint `gorm:"primaryKey" json:"-"` + DID string `gorm:"column:did;size:255;not null;index:idx_blocks_did_rkey,unique;index:idx_blocks_did;index:idx_blocks_did_subject,unique" json:"did"` + Rkey string `gorm:"size:512;not null;index:idx_blocks_did_rkey,unique" json:"rkey"` + ATURI string `gorm:"column:at_uri;size:1024;not null;index" json:"-"` + SubjectDID string `gorm:"column:subject_did;size:255;not null;index:idx_blocks_subject;index:idx_blocks_did_subject,unique" json:"subject_did"` + CreatedAt string `gorm:"size:64;not null" json:"created_at"` + IndexedAt time.Time `gorm:"autoCreateTime" json:"-"` } func (Block) TableName() string { return "blocks" } type Report struct { - ID uint `gorm:"primaryKey"` - DID string `gorm:"column:did;size:255;not null;index:idx_reports_did_rkey,unique;index:idx_reports_did"` - Rkey string `gorm:"size:512;not null;index:idx_reports_did_rkey,unique"` - SubjectURI string `gorm:"size:1024;not null"` - ReasonType string `gorm:"size:64;not null"` - Reason string `gorm:"type:text"` - Status string `gorm:"size:64;not null;default:pending;index:idx_reports_status"` - CreatedAt string `gorm:"size:64;not null"` - IndexedAt time.Time `gorm:"autoCreateTime"` + ID uint `gorm:"primaryKey" json:"-"` + DID string `gorm:"column:did;size:255;not null;index:idx_reports_did_rkey,unique;index:idx_reports_did" json:"did"` + Rkey string `gorm:"size:512;not null;index:idx_reports_did_rkey,unique" json:"rkey"` + SubjectURI string `gorm:"size:1024;not null" json:"subject_uri"` + ReasonType string `gorm:"size:64;not null" json:"reason_type"` + Reason string `gorm:"type:text" json:"reason"` + Status string `gorm:"size:64;not null;default:pending;index:idx_reports_status" json:"status"` + CreatedAt string `gorm:"size:64;not null" json:"created_at"` + IndexedAt time.Time `gorm:"autoCreateTime" json:"-"` } func (Report) TableName() string { return "reports" } diff --git a/appview/handlers/bookmark.go b/appview/handlers/bookmark.go index 196824c..3543edf 100644 --- a/appview/handlers/bookmark.go +++ b/appview/handlers/bookmark.go @@ -42,5 +42,36 @@ func (h *Handlers) GetBookmarks(c echo.Context) error { rows = rows[:limit] } - return c.JSON(http.StatusOK, map[string]any{"bookmarks": rows, "cursor": nextCursor}) + type episodeRef struct { + FeedID int64 `json:"feed_id"` + EpisodeID int64 `json:"episode_id"` + EpisodeGuid string `json:"episode_guid,omitempty"` + PodcastGuid string `json:"podcast_guid,omitempty"` + } + + type bookmark struct { + DID string `json:"did"` + Rkey string `json:"rkey"` + Episode episodeRef `json:"episode"` + Timestamp *int `json:"timestamp,omitempty"` + CreatedAt string `json:"created_at"` + } + + list := make([]bookmark, 0, len(rows)) + for _, row := range rows { + list = append(list, bookmark{ + DID: row.DID, + Rkey: row.Rkey, + Episode: episodeRef{ + FeedID: row.FeedID, + EpisodeID: row.EpisodeID, + EpisodeGuid: row.EpisodeGuid, + PodcastGuid: row.PodcastGuid, + }, + Timestamp: row.TimestampS, + CreatedAt: row.CreatedAt, + }) + } + + return c.JSON(http.StatusOK, map[string]any{"bookmarks": list, "cursor": nextCursor}) } diff --git a/appview/handlers/comment.go b/appview/handlers/comment.go index 9842d9a..b777332 100644 --- a/appview/handlers/comment.go +++ b/appview/handlers/comment.go @@ -1,12 +1,56 @@ package handlers import ( + "encoding/json" "net/http" "tangled.org/sparrowtek.com/effem-AppView/appview/database" "github.com/labstack/echo/v4" ) +type commentEpisodeRef struct { + FeedID int64 `json:"feed_id"` + EpisodeID int64 `json:"episode_id"` + EpisodeGuid string `json:"episode_guid,omitempty"` + PodcastGuid string `json:"podcast_guid,omitempty"` +} + +type commentResponse struct { + DID string `json:"did"` + Rkey string `json:"rkey"` + Episode commentEpisodeRef `json:"episode"` + Text string `json:"text"` + Timestamp *int `json:"timestamp,omitempty"` + ReplyRoot string `json:"reply_root,omitempty"` + ReplyParent string `json:"reply_parent,omitempty"` + Facets json.RawMessage `json:"facets,omitempty"` + CreatedAt string `json:"created_at"` +} + +func toCommentResponse(row database.Comment) commentResponse { + var facets json.RawMessage + if len(row.Facets) > 0 { + facets = row.Facets + } + + return commentResponse{ + DID: row.DID, + Rkey: row.Rkey, + Episode: commentEpisodeRef{ + FeedID: row.FeedID, + EpisodeID: row.EpisodeID, + EpisodeGuid: row.EpisodeGuid, + PodcastGuid: row.PodcastGuid, + }, + Text: row.Text, + Timestamp: row.TimestampS, + ReplyRoot: row.ReplyRoot, + ReplyParent: row.ReplyParent, + Facets: facets, + CreatedAt: row.CreatedAt, + } +} + func (h *Handlers) GetComments(c echo.Context) error { feedID := parseInt64(c.QueryParam("feedId"), 0) episodeID := parseInt64(c.QueryParam("episodeId"), 0) @@ -38,8 +82,13 @@ func (h *Handlers) GetComments(c echo.Context) error { comments = comments[:limit] } + list := make([]commentResponse, 0, len(comments)) + for _, row := range comments { + list = append(list, toCommentResponse(row)) + } + return c.JSON(http.StatusOK, map[string]any{ - "comments": comments, + "comments": list, "cursor": nextCursor, }) } @@ -65,8 +114,18 @@ func (h *Handlers) GetCommentThread(c echo.Context) error { return writeError(c, http.StatusInternalServerError, "InternalError", "") } + replyNodes := make([]map[string]any, 0, len(replies)) + for _, row := range replies { + replyNodes = append(replyNodes, map[string]any{ + "comment": toCommentResponse(row), + "replies": []any{}, + }) + } + return c.JSON(http.StatusOK, map[string]any{ - "root": root, - "replies": replies, + "thread": map[string]any{ + "comment": toCommentResponse(root), + "replies": replyNodes, + }, }) } diff --git a/appview/handlers/episode_state.go b/appview/handlers/episode_state.go index ecf5734..c13d2ca 100644 --- a/appview/handlers/episode_state.go +++ b/appview/handlers/episode_state.go @@ -43,5 +43,5 @@ func (h *Handlers) GetEpisodeStates(c echo.Context) error { rows = rows[:limit] } - return c.JSON(http.StatusOK, map[string]any{"episodeStates": rows, "cursor": nextCursor}) + return c.JSON(http.StatusOK, map[string]any{"episode_states": rows, "cursor": nextCursor}) } diff --git a/appview/handlers/list.go b/appview/handlers/list.go index 3489323..9e76cd9 100644 --- a/appview/handlers/list.go +++ b/appview/handlers/list.go @@ -9,6 +9,31 @@ import ( "github.com/labstack/echo/v4" ) +type listResponse struct { + DID string `json:"did"` + Rkey string `json:"rkey"` + Name string `json:"name"` + Description string `json:"description,omitempty"` + Podcasts json.RawMessage `json:"podcasts"` + CreatedAt string `json:"created_at"` +} + +func toListResponse(row database.PodcastList) listResponse { + podcasts := json.RawMessage("[]") + if len(row.Podcasts) > 0 { + podcasts = row.Podcasts + } + + return listResponse{ + DID: row.DID, + Rkey: row.Rkey, + Name: row.Name, + Description: row.Description, + Podcasts: podcasts, + CreatedAt: row.CreatedAt, + } +} + func (h *Handlers) GetList(c echo.Context) error { uriRaw := c.QueryParam("uri") if uriRaw == "" { @@ -31,12 +56,7 @@ func (h *Handlers) GetList(c echo.Context) error { return writeError(c, http.StatusNotFound, "NotFound", "list not found") } - var podcasts []map[string]any - if len(list.Podcasts) > 0 { - _ = json.Unmarshal(list.Podcasts, &podcasts) - } - - return c.JSON(http.StatusOK, map[string]any{"list": list, "podcasts": podcasts}) + return c.JSON(http.StatusOK, map[string]any{"list": toListResponse(list)}) } func (h *Handlers) GetLists(c echo.Context) error { @@ -64,5 +84,10 @@ func (h *Handlers) GetLists(c echo.Context) error { rows = rows[:limit] } - return c.JSON(http.StatusOK, map[string]any{"lists": rows, "cursor": nextCursor}) + list := make([]listResponse, 0, len(rows)) + for _, row := range rows { + list = append(list, toListResponse(row)) + } + + return c.JSON(http.StatusOK, map[string]any{"lists": list, "cursor": nextCursor}) } diff --git a/appview/handlers/profile.go b/appview/handlers/profile.go index 2b9cacf..a8745f5 100644 --- a/appview/handlers/profile.go +++ b/appview/handlers/profile.go @@ -36,16 +36,15 @@ func (h *Handlers) GetProfile(c echo.Context) error { _ = h.db.WithContext(c.Request().Context()).Model(&database.PodcastList{}).Where("did = ?", did).Count(&listCount).Error return c.JSON(http.StatusOK, map[string]any{ - "did": profile.DID, - "displayName": profile.DisplayName, - "description": profile.Description, - "favoriteGenres": genres, - "stats": map[string]any{ - "subscriptionCount": subscriptionCount, - "commentCount": commentCount, - "recommendationCount": recommendationCount, - "bookmarkCount": bookmarkCount, - "listCount": listCount, + "profile": map[string]any{ + "did": profile.DID, + "display_name": profile.DisplayName, + "description": profile.Description, + "favorite_genres": genres, + "subscription_count": subscriptionCount, + "comment_count": commentCount, + "recommendation_count": recommendationCount, + "list_count": listCount, }, }) } diff --git a/appview/handlers/recommendation.go b/appview/handlers/recommendation.go index 91aadcb..94f53b5 100644 --- a/appview/handlers/recommendation.go +++ b/appview/handlers/recommendation.go @@ -38,12 +38,43 @@ func (h *Handlers) GetRecommendations(c echo.Context) error { rows = rows[:limit] } - return c.JSON(http.StatusOK, map[string]any{"recommendations": rows, "cursor": nextCursor}) + type episodeRef struct { + FeedID int64 `json:"feed_id"` + EpisodeID int64 `json:"episode_id"` + EpisodeGuid string `json:"episode_guid,omitempty"` + PodcastGuid string `json:"podcast_guid,omitempty"` + } + + type recommendation struct { + DID string `json:"did"` + Rkey string `json:"rkey"` + Episode episodeRef `json:"episode"` + Text string `json:"text,omitempty"` + CreatedAt string `json:"created_at"` + } + + list := make([]recommendation, 0, len(rows)) + for _, row := range rows { + list = append(list, recommendation{ + DID: row.DID, + Rkey: row.Rkey, + Episode: episodeRef{ + FeedID: row.FeedID, + EpisodeID: row.EpisodeID, + EpisodeGuid: row.EpisodeGuid, + PodcastGuid: row.PodcastGuid, + }, + Text: row.Text, + CreatedAt: row.CreatedAt, + }) + } + + return c.JSON(http.StatusOK, map[string]any{"recommendations": list, "cursor": nextCursor}) } type popularRow struct { - FeedID int64 `json:"feedId"` - EpisodeID int64 `json:"episodeId"` + FeedID int64 `json:"feed_id"` + EpisodeID int64 `json:"episode_id"` Count int64 `json:"count"` } diff --git a/appview/handlers/social.go b/appview/handlers/social.go index de6222e..a1e4003 100644 --- a/appview/handlers/social.go +++ b/appview/handlers/social.go @@ -10,16 +10,16 @@ import ( ) type SocialCounts struct { - SubscriberCount int `json:"subscriberCount"` - CommentCount int `json:"commentCount"` - RecommendationCount int `json:"recommendationCount"` - SubscribedByFollowing []string `json:"subscribedByFollowing"` + SubscriberCount int `json:"subscriber_count"` + CommentCount int `json:"comment_count"` + RecommendationCount int `json:"recommendation_count"` + SubscribedByFollowing []string `json:"subscribed_by_following"` } type EpisodeSocialCounts struct { - CommentCount int `json:"commentCount"` - RecommendationCount int `json:"recommendationCount"` - BookmarkCount int `json:"bookmarkCount"` + CommentCount int `json:"comment_count"` + RecommendationCount int `json:"recommendation_count"` + BookmarkCount int `json:"bookmark_count"` } func anyToInt64(v any) int64 { diff --git a/appview/handlers/subscription.go b/appview/handlers/subscription.go index 9947970..c1b65cd 100644 --- a/appview/handlers/subscription.go +++ b/appview/handlers/subscription.go @@ -32,8 +32,35 @@ func (h *Handlers) GetSubscriptions(c echo.Context) error { rows = rows[:limit] } + type podcastRef struct { + FeedID int64 `json:"feed_id"` + FeedURL string `json:"feed_url,omitempty"` + PodcastGuid string `json:"podcast_guid,omitempty"` + } + + type subscription struct { + DID string `json:"did"` + Rkey string `json:"rkey"` + Podcast podcastRef `json:"podcast"` + CreatedAt string `json:"created_at"` + } + + list := make([]subscription, 0, len(rows)) + for _, row := range rows { + list = append(list, subscription{ + DID: row.DID, + Rkey: row.Rkey, + Podcast: podcastRef{ + FeedID: row.FeedID, + FeedURL: row.FeedURL, + PodcastGuid: row.PodcastGuid, + }, + CreatedAt: row.CreatedAt, + }) + } + return c.JSON(http.StatusOK, map[string]any{ - "subscriptions": rows, + "subscriptions": list, "cursor": nextCursor, }) } @@ -69,7 +96,7 @@ func (h *Handlers) GetSubscribers(c echo.Context) error { type subscriber struct { DID string `json:"did"` Rkey string `json:"rkey"` - CreatedAt string `json:"createdAt"` + CreatedAt string `json:"created_at"` } list := make([]subscriber, 0, len(subs)) @@ -83,7 +110,7 @@ func (h *Handlers) GetSubscribers(c echo.Context) error { } return c.JSON(http.StatusOK, map[string]any{ - "feedId": feedID, + "feed_id": feedID, "subscribers": list, "count": count, "cursor": nextCursor, -- 2.51.2